Browsing:

Category: c#

Getting started with ASP.NET API with MongoLab and Angularjs part 4

In my previous blogpost we created a Web API with a Mongodb backend. Now we'll create a client application that consumes the API with a JavaScript framework.
That is obviously the way to go nowadays.

There is a plethora of Javascript frameworks to use and Angular.js is in fact the first one that I've tried, because it gets a lot of traction lately.

What are we creating?

Let's try to make a single page application (SPA) where people can enter and lookup their contacts. Instead of the classic addressbooks, it is possible to enter Facebook pages, Twitter accounts and so on.
To make sure it looks nice we will be using Twitter Bootstrap.

Getting ready for Angular

First get the Angular.js and Twitter Bootstrap through the Nuget Package Manager Console:

Install-Package angularjs
Install-Package bootstrap

Then, create a folder named 'app' with the following subfolders:
-app
---css
---fonts
---img
---js
---lib

Then drag the css and angular etc to this new folder structure, like so:

2013-11-02 12_02_23-AddressBook - Microsoft Visual Studio

In case you are wondering why I am doing this. When I first started to look at Angular, I used Angular-seed as a boilerplate. I think that is a good startingpoint for organizing code.
Further, the Web API has nothing to do with the client code I'm going to write. I will not be using ASP.NET MVC routing and views with Razor, instead I will be using the routing and the controllers from the Angular framework. So that explains the separate 'app' folder in the project.

We need to configure the AddressBook application to start in the app folder though:

2013-11-03 09_45_19-AddressBook - Microsoft Visual Studio

I've also changed to port to 8000 so it's easier to remember.

A little bit of Angular background info

This is a good introduction to Angular by Dan Wahlin. Be sure to check it out.

Angular uses modules to specify how a web application should be bootstrapped.
Modules break an application up into functional sections. For example, services, directives, controllers and filters that are specific to a particular application can be added to the application module.
Ehm.. What does that even mean!?
Well, controllers for front-end development serve a very similar purpose as controllers we know from ASP.NET MVC. Controllers present data to the views, via a scope. And Angular services are singletons objects or functions that carry out specific tasks common to web apps. A typical task for a service would be fetching data from a server.

At Thruzero I found a very good explanation of the Angular architecture:
Angular architecture

Getting started

In /app/js create a javascript file named app.js.
I will be adding all the javascript in there because this app is very trivial. Later I will break it up in several files (javascript files for controllers, for services etc.).

Let's first declare the module:

//app/js/app.js:
var addressbookModule = angular.module('addressbookModule',[])

The '[ ]' array thing is very important, because later we can inject other modules into this array.

Next we can add a controller to the addressbookModule. The first argument is the controller name,'WelcomeController' and the second argument is a function, in which we pass in a $scope.
The scope is the 'glue' between the controller and the view. We can give the scope properties in the controller which will be presented to the view.

//app/js/app.js:
var addressbookModule = angular.module('addressbookModule',[])

addressbookModule.controller('WelcomeController', function ($scope) {
    $scope.title = "Welcome to your AddressBook";
 });

Finally, this is the view (/app/index.html):





    AddressBook





{{title}}

This is the result:

2013-11-02 13_32_13-Mozilla Firefox

What we just did:

  • We wired up Angularjs in our application by adding angular.js to our html file
  • We created a module named AddressBookModule as an Angular module.
  • Now we can chain Angular functionality to this module (routing, services, controllers etc).
  • We added a Controller.

It took a while for me to grasp all this. If you're coming from a C# world the whole Javascript syntax is already confusing enough. All these 'function() { }' curly braces, hooks and semicolons confuse me. And if you forget to put a }); well then it just doesn't work.
You can have anonymous functions with 30 miles of arguments!

The solution is: practice, practice, practice. Make stupid mistakes and blog about it.

Next time we'll add some CRUD.


Getting started with ASP.NET API with MongoLab part 3

This is the sequel to this post
We will be using MongoLab as a backend for our Web Api.

We are using the AddressBook again in this example, but for clarity we're building it from scratch.

Creating the MongoLab database

Head over to MongoLab and create an account!

  • First create a new database. Make sure you choose the free plan. Name the database 'addressbook'.
  • Click to create a new user.
  • Add a new collection (equivalent for a table) named persons.

Please take note of the connectionstring:

2013-11-01 08_12_03-MongoLab_ MongoDB-as-a-Service

Setting up the Web Api project in Visual Studio

Fire up Visual Studio 2013 and hit File -> New -> Project.
Choose Empty ASP.NET Web Application with a Web API and name the project AddressBook.

2013-11-01 08_07_48-New ASP.NET Project - AddressBook

We must install the Mongo Csharp Driver:

Install-Package MongoCsharpDriver

Now open App_Start\WebApiConfig.cs and add json formatting to it (see my previous post why):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace AddressBook
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

//This section you need to add:
            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);
        }
    }
}

Connecting to the MongoLab

Let's not reinvent the wheel if you don't have to. This article is a great introduction to Mongo and C#. I borrowed their MongoConnectionHandler.

using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AddressBook
{
    public class MongoConnectionHandler
    {
        public MongoCollection MongoCollection { get; private set; }

 public MongoConnectionHandler()
        {
            const string connectionString = "mongodb://:@ds031108.mongolab.com:31108/addressbook";
            //const string connectionString = "mongodb://localhost:27017";
            //// Get a thread-safe client object by using a connection string
            var mongoClient = new MongoClient(connectionString);

            //// Get a reference to a server object from the Mongo client object
            var mongoServer = mongoClient.GetServer();

            //// Get a reference to the database object 
            //// from the Mongo server object
            const string databaseName = "persons";
            var db = mongoServer.GetDatabase(databaseName);

            //// Get a reference to the collection object from the Mongo database object
            //// The collection name is the type converted to lowercase + "s"
            MongoCollection = db.GetCollection(typeof(T).Name.ToLower() + "s");
        }
    }
}

The Person class

I want the Person_Id to be the same as the document id, so I can retrieve documents easily. I'm not sure though if this is best practice. But it works.

public class Person 
    {
        public Person()
        {
            Person_Id = ObjectId.GenerateNewId().ToString();
        }

        [BsonId]
        public string Person_Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public string Blog { get; set; }
        public string Facebook { get; set; }
        public string Twitter { get; set; }
        public string LinkedIn { get; set; }
        public string Googleplus { get; set; }
    }

And here's the POST method:

public class PersonController : ApiController
    {
        public MongoConnectionHandler collection = new MongoConnectionHandler();

        public HttpResponseMessage Post([FromBody] Person person)
        {
            collection.MongoCollection.Insert(person);
            var response = Request.CreateResponse(HttpStatusCode.Created, person);

          
            string uri = Url.Link("DefaultApi", new { id = person.Person_Id });
            response.Headers.Location = new Uri(uri);
            return response;

        }


    }
      

You can use the API with Fiddler.

2013-11-01 14_33_36-Fiddler Web Debugger

Look at the results it has returned:

2013-11-01 14_35_25-Fiddler Web Debugger

It returned the new URI with the new Id as you can see.

Now let's check MongoLab, and lo and behold:

2013-11-01 14_39_53-MongoLab_ MongoDB-as-a-Service

Here's the remainder of the CRUD methods:

        public IEnumerable Get()
        {
            return collection.MongoCollection.FindAll().AsEnumerable();

        }


        public Person Get(string id) {

            //var query = Query.EQ(p => p.Person_Id, id);
            return collection.MongoCollection.FindOne(Query.EQ("_id", id));

        }

        public void Delete(string id)
        {
            collection.MongoCollection.Remove(Query.EQ("_id", id));

        }

        public HttpResponseMessage Put([FromBody] Person person)
        {
            
            var p = collection.MongoCollection.FindOne(Query.EQ("_id", person.Person_Id));

            if (p != null)
            {
                collection.MongoCollection.Save(person);
            }
           
            return Request.CreateResponse(HttpStatusCode.OK, person);
        }

So, that works.
Next time, let's consume this WebApi with Angularjs.

And here's all the code: here

I have changed 'Person' to 'Contact' in the sourcecode


Entity Framework from scratch Part 4 EF4 Multi Layered – System.Data.Entity not referenced

As i mentioned in the previous post, there seems to be a problem when you work with Multi layered Solutions in the Entity Framework. You need to add the Entity references to all the solutions in your project, but i found another small problem when creating a web front to your application.
I've built this app with EF4 features with web functionality.

When i debug my code, the database connection works and the table rows are fetched, but my webpage displays an compilation error: CS0012: The type 'System.Data.Objects.DataClasses.EntityObject' is defined in an assembly that is not referenced. You must add a reference assembly to 'System.Data.Entity, version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

You need to add extra code manualy to your Web.config file directly under the system.web

<configuration>
  <system.web>

copy/paste the following code:

  <compilation debug="true" targetFramework="4.0">
    <assemblies>
      <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </assemblies>
  </compilation>

If you built and re-run the the app, the webpage is displayed correctly.


Entity Framework from scratch Part 2 EF4 release

A lot has happened since the last blog where we introduced the entity framework and tried to explain the possible benefits it could have over the other NoSQL.
Microsoft has released a new EF4 that builds us cleaner code, “Code First Development”

They have kept their eyes out on the other NoSQL movements and learned, In this post we are going to introduce 2 new types, the DbContext and the DbSet that EF4 brought us.
At first I was puzzled as in why two new types, and not just remake the ObjectContext and ObjectSet.
But there is a logica behind this, as you can read on the Msdn blog. They are no replacement, they are just simplified. Now you can always choose to use the more advanced types. DBSet has full compatibility with the excisting EF’s and to switch to the ObjectContext and ObjectSet.

We are going to build a standard console app.
First, make sure you're on .Net version 4, or the entity framework 4 will not work.

Dwnload the new EF4 features here and install them.

Fire up your visual studio and choose the console app, and name it ShoeShoe. Now add a using statement on top of the program.cs

using System.Data.Entity;

Now define the two classes we need for our data, namely ShoeShoe a class that describes the shoes in my closet and second the type of shoes i have collected.

public class ShoeCat
{
    public string ShoeCatId { get; set; }
    public string Name { get; set; }

    public virtual ICollection Shoe { get; set; }
}

public class ShoeShoe
{
    public int ShoeShoeId { get; set; }
    public string Name { get; set; }
    public string CategoryId { get; set; }

    public virtual ShoeCat Category { get; set; }

Now we are gonna add context using the new DbContext DbSet type from EF4

public class ShoeShoeCatalog : DbContext
{
    public DbSet Categories { get; set; }
    public DbSet Products { get; set; }
}

To get your console app to recognize the Dbset statement, we need to add 2 references:
The Microsoft.Data.Entity.CTP
microsoft.data.entity
and the system.data.entity.

this is all the code needed to start the process of storing and retrieving data.

Now let’s put some data in the app and build a program class

class Program
{
    static void Main(string[] args)
    {
        using (var context = new ShoeShoeCatalog())
        {
            var Pump = new ShoeCat { ShoeCatId = "Pump", Name = "Sexy" };
            context.Categories.Add(Pump);
            int recordsAffected = context.SaveChanges();

            Console.WriteLine(
                "Succesfully Saved {0} row(s) to the database, press any key to exit.",
                recordsAffected);

            Console.ReadKey();
        }
    }
}

Now we successfully added shoeshoe data.
This is ofcourse just the beginning of our shoeshoe app, but i hope you are bit more familiar with the 2 new types EF4 has provided us.

Enjoy ! Next we are going to build extra features in ourShoeShoe console application.


Db4o and ASP.NET MVC 2 part 1

Today Scott Guthrie anounced the final release of ASP.NET MVC 2. So it's a good time to give this a spin and check out the enhancements, like the new model validation and asynchronous controllers.

The best way to learn is to actually build an application. That's what I would like to do here. I am going to build a blog application. For persistence I will use db4o, an object oriented database. Reasons for using Db40 is convenience. With Db4o, you don't need to run SQL Server, which makes your code very portable and extremely easy to adjust to changing businessneeds.

The way I code this application is probably not from the books. It's just how I think I should code. If you can think of any improvements please do not hesitate and tell us.

IkZeg
I'm going to call this application 'IkZeg'. It's a blog application, so we need a class for stories and for writers. We also like to enable comments. The classdiagram would be something like this:
ClassDiagram2

Now install ASP.NET MVC 2 and download Db40 for .NET 3.5

Start Visual Studio (2008, I won't use 2010 until it's RTM-ed) and create a new ASP.NET MVC 2 Web Application: IkZeg.

start

I'm not adding a Test project because I just want to get going as fast as possible.

Then, rightclick the folder Models and add a new class and name it: Story.

public partial class Story
    {
        public Story()
        {
            storyId = System.Guid.NewGuid();
            commentsCount = 0;
            storyDate = DateTime.Now;
        }
        public Guid storyId { get; set; }
        public string storyTitle { get; set; }
        public string storyText { get; set; }
        public DateTime storyDate { get; set; }
        public Writer writer { get; set; }
        public int commentsCount { get; set; }
        public List

Also add a Writer and a Comment class:

 public class Writer
    {
       public Writer()
       {
           registerDate = DateTime.Now;
       }
        public string username { get; set; }
        public string password { get; set; }
        public string email { get; set; }
        public DateTime registerDate { get; set; }
        //the birthday is nullable:
        public DateTime? birthday { get; set; }
    }

public class Comment
    {
        public Comment()
        {
            postedDate = DateTime.Now;
        }
        public string username { get; set; }
        public string commentOn { get; set; }
        public DateTime postedDate { get; set; }
        public string commentText { get; set; }
    }

Now that we've created the model it's time to dive into persistence with Db4o.

Data Access with Db4o

An object-oriented database stores objects directly in the database without having to map it to a relational structure. This is a major timesaver and it has lots of other advantages (and disadvantages) but that discussion is a bit out of scope. Db4o is just awesome to use.

Add references to dll's from Db4o: Db40objects.Db4o, Db40objects.Db4o.CS and Db40objects.Db4o.Linq:

ref

To implement persistence I followed Rob Conery because yes, he's my hero. I learn an awful lot from him and from the Tekpub vids.

Data Access

To get started with Db4o is really simple. After adding the references you can start doing CRUD operations immediately, like so:

using(IObjectContainer db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(),@"c:\temp\thebigblahdatabase.dat"))
{
    Story story = new Story();
    story.storyTitle="Wat doen we met Pasen?!"
    story.storyText="Codekloppen, obviously!"
    db.store(story);
    db.Close();
}

But that would mean we would be repeating ourselves continuously. With every CRUD operation, we would have to write the same piece of code and worry about closing the database. It would be nice to abstract these operations away. Also, maybe we would like to migrate to MySQL or Oracle later. So let's take another approach.

Unit of Work

We'll set up a Unit of Work. This takes care of CRUD methods. The value of using a Unit of Work pattern is to free the rest of your code from these concerns so that you can concentrate on business logic.

DataAccess

using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using Db4objects.Db4o.CS;

namespace IkZeg.Models
{
    public interface ISession:IDisposable 
    {
        void CommitChanges();
        Db4objects.Db4o.IObjectContainer Container { get; }
        void Delete(System.Linq.Expressions.Expression> expression);
        void Delete(T item);
        void DeleteAll();
        void Dispose();
        T Single(System.Linq.Expressions.Expression> expression);
        System.Linq.IQueryable All();
        void Save(T item);
    }
}

There's a lot of funky generics in there. That's good, because we need to implement this interface for all our ikZeg classes (Story, Writer and Comment).

Now let's create a class that implements the ISession interface we just created:

using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using Db4objects.Db4o.CS;

namespace IkZeg
{
    public class Db4oSession : IDisposable,ISession
    {
        private IObjectContainer db;
        public IObjectContainer Container {
            get {
                return db;
            }
        }

        public Db4oSession(IObjectServer server) {
            db=server.OpenClient();
        }

       /// 
        /// Returns all T records in the repository
        /// 
        public IQueryable All() {
            return (from T items in db
                    select items).AsQueryable();
        }
/// 
        /// Finds a subset of items using a passed-in expression lambda
        /// 
        public IQueryable Where(System.Linq.Expressions.Expression> expression)
        {
            return All().Where(expression);
        }
 
        
        /// 
        /// Finds an item using a passed-in expression lambda
        /// 
        public T Single(System.Linq.Expressions.Expression> expression) {
            return All().SingleOrDefault(expression);
        }
 
        /// 
        /// Saves an item to the database
        /// 
        /// 
        public void Save(T item) {
            db.Store(item);
        }
 
        /// 
        /// Deletes an item from the database
        /// 
        /// 
        public void Delete(T item) {
            db.Delete(item);
        }
 
        /// 
        /// Deletes subset of objects
        /// 
        public void Delete(System.Linq.Expressions.Expression> expression) {
            var items = All().Where(expression).ToList();
            items.ForEach(x => db.Delete(x));
        }
 
        /// 
        /// Deletes all T objects
        /// 
        public void DeleteAll() {
            var items = All().ToList();
            items.ForEach(x => db.Delete(x));
        }
 
 
        /// 
        /// Commits changes to disk
        /// 
        public void CommitChanges() {
            //commit the changes
            db.Commit();
 
        }


        public void Dispose() {
            //explicitly close
            db.Close();
            //dispose 'em
            db.Dispose();
        }
    }
}

       

Now create a class that inherits from Db4oSession and it all starts making sense:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using Db4objects.Db4o.CS;

namespace IkZeg.Models
{
    public class IkZegSession : Db4oSession
    {
        internal IkZegSession(IObjectServer server) : base(server) { }

        public IQueryable stories
        {
            get
            {
                return All();
            }
        }


        public IQueryable storiesByWriter(string writer)
        {
            return Where(s => s.writer.ToString() == writer);
        }


        public Story getStory(string id)
        {
            return Single(s => s.storyId.ToString() == id);
        }

        public int getComments(string storyGuid)
        {
            return Where(c => c.commentOn == storyGuid).Count();
        }

       }
}

And here is the class that holds the Db40 file- and connectioninfo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Db4objects.Db4o;
using Db4objects.Db4o.CS;
using Db4objects.Db4o.Linq;

namespace IkZeg.Models
{
    public class SessionFactory
    {
        static ISession _current;
       
        static IObjectServer _server;

        public static ISession CreateSession()
        {
            if (_server == null)
            {
                _server = Db4oFactory.OpenServer( @"c:\temp\debigblahdatabase", 0);
            }

            return new IkZegSession(_server);
        }

        public static IkZegSession Current
        {
            get
            {
                if (_current == null)
                    _current = CreateSession();
                return (IkZegSession)_current;
            }
        }

    }
}

Let's use this

So, let's create a story and show it on the website. To do that, I'll need a controller and a view. Let's start with the controller.

Right click the folder Controllers and click Add Controller.
Name the Controller StoryController and add action methods. Like this:

contr2

Add using statements for Db4o and the Models folder:

using IkZeg.Models;
using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using Db4objects.Db4o.CS;

Just below the StoryController declare an IkZegSession:

  public class StoryController : Controller
    {
        IkZegSession db = SessionFactory.Current;

Scroll down to line 63 or so to the Create method and make it look like this:

   [HttpPost]
        public ActionResult Create(Story story)
        {
            if (ModelState.IsValid)
            {
                    story.writer = new Writer { username = Request.Form["writer.username"] };
                    story.storyDate = DateTime.Now;
                    db.Save(story);
                    return RedirectToAction("Index");
                }

                        else
            {
                return View();
            }
        }

Now add the view. Right click the Create Method (along line 65) and click Add View.

addView

Create a strongly-typed view. The data class is IkZeg.Models.Story. That's the story class we made earlier.

view2

Almost done now. Let's take a look a this View though. In the folder Views, you have now a Story folder, with a file named Create.aspx. Open the file and remove the HTML fieldset (because I think it's ugly). Also remove the Guid labels and textboxes and the Postdate labels and textboxes. We don't need them as they are generated in the Create method in the controller.

Hit debug (or F5). The webbrowser starts with the standard webpage. Browse to: http://localhost:51305(or whatever portnumber)/Story/Create. And there we are. It's a bit ugly but we will work at the layout later.
cr

After clicking Create you'll get a Yellow Screen of Death, which is okay, as we did not implement the Index method yet. I will cover that (and validation) in part 2.