Nerdly Things

.tech and personal blog of david stanley.

Interacting with ASP.NET Web API from the client!

7/18/2012

If any of your have been paying attention you will notice that I have been all about Web API lately. It has been quite a struggle however because I am very weak in the areas on jQuery/javascript as well as understanding all the inner workings of http. A breakthrough has been made however! I have a demo of the super ghetto and not quote really working perfectly site here. Before I go any further, I will give the credit of this where credit is due. Thank you to pluralsight and Jon Flanders for the course. Walking through the first couple of modules really helped me get a grasp, though I did have to do some discovery to get mine to work.

To the code!

I am using Visual Studio 2012 RC with the latest patch as of the date of publishing this. I did a File > New Project, selected MVC4 (.NET v4.0) and chose the default internet application. Not going to go into the MVC structure here, email me, or look at my Custom MVC Blog posts in the archives if interested. 

The first thing I did was clean up my HomeController:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Task(int id)
    {
        return View(id);
    }

    public ActionResult Create()
    {
        return View();
    }
}

I also adjusted the layout page navigation bar to match this stuff I changed. Next I needed some data to interact with so in the models folder I add a Model.cs file and a ModelInitializer.cs file. The first to define the model, the second to load it up with some dummy data. Here they are:

Model (Nevermind the name):

public class Onus
{
    public int id { get; set; }
    public string name { get; set; }
    public string content { get; set; }
    public bool hasLocation { get; set; }
}

And here is the Initializer:

public static List InitOni()
{
    var ret = new List();
    ret.Add(new TaskIt.Models.TaskItModels.Onus { 
        id = 0, 
        name = "Get Milk", 
        content = "Get 2 gallons of milk from the store", 
        hasLocation = true});
    ret.Add(new TaskIt.Models.TaskItModels.Onus { 
        id = 1, 
        name = "Read Pride and Prejudive", 
        content = "Try to finish it sooner than later", 
        hasLocation = false });
    ret.Add(new TaskIt.Models.TaskItModels.Onus { 
        id = 2, name = "Turn in timecard", 
        content = "Give it to the boss by friday", 
        hasLocation = true });
    ret.Add(new TaskIt.Models.TaskItModels.Onus { 
        id = 3, 
        name = "Call Insurance about goats", 
        content = "Ask them cost of coverage for 2 goats", 
        hasLocation = false });
    return ret;
}

Now I went ahead and created a new Empty Web API Controller called TasksController. You will notice that all the methods within are named based off of convention. Meaning if my api gets a post request, it will look for a method called Post() automatically. Here is all the code I have in the Task Controller.

public class TasksController : ApiController
{
    static List _oni = 
        TaskIt.Models.TaskItInitializer.InitOni();

    //uri: /api/courses/
    public IEnumerable Get()
    {
        return _oni;
    }

    //uri: /api/courses/{id}
    public TaskIt.Models.TaskItModels.Onus Get(int id)
    {
        TaskIt.Models.TaskItModels.Onus ret = null;
        ret = (from c in _oni where c.id == id select c).FirstOrDefault();
        return ret;
    }

    public TaskIt.Models.TaskItModels.Onus Post(TaskIt.Models.TaskItModels.Onus newOnus)
    {
        newOnus.id = _oni.Count();
        _oni.Add(newOnus);
        return newOnus;
    }

    public void Put(int id, TaskIt.Models.TaskItModels.Onus updatedOnus)
    {
        TaskIt.Models.TaskItModels.Onus ret = null;
        ret = (from c in _oni where c.id == id select c).FirstOrDefault();
        _oni.Remove(ret);
        _oni.Add(updatedOnus);
    }

    public void Delete(int id)
    {
        TaskIt.Models.TaskItModels.Onus ret = null;
        ret = (from c in _oni where c.id == id select c).FirstOrDefault();
        if (ret != null)
        {
            _oni.Remove(ret);
        }
    }
}

Nothing too complicated here. First I am filling up a list with my initialized model data, then I have a couple of GET methods, a POST method, a PUT method, and a DELETE method. All of your CRUD operations! What is happening inside the methods is really basic LINQ. This post is about how I talk to this from my website, not about LINQ, so if you are unfamiliar, shoot my a line and I can explain what is going on above in detail, or you can read up on LINQ.

Now to the good stuff: making our MVC Views talk to this thing. For my home page I just wanted the index to show my a list of all the tasks. Here is the javascript that accomplishes that:

Client Side API Index Page

So all I do is point an ajax request to the url of my api (api/tasks), and then on success, fill up an unordered list with list items that contain task.name. Naming is important here, not that name is lowercase, just like it is in the Model we created. This is how it knows what data to grab.

Next I wanted to get a task by id, which looks like this (This is in my Task View):

Client Side Api Task Page

All I do to pass the id value is using razor to get it from my bound model. Super cool!

The best part for last, how to add some tasks via the client. This is done in the Create View:

Client Side Api Create Page

This was something that up until seeing this I just couldn't figure out. Turns out that in $.ajax() you get specific the type of call it is. Here we specify POST, meaning that when it hits that API url, it is going to execute the Post() method. Then I simple specified the data by grabbing the values from the form, I alert the user it was added, then redirect to the home page using window.location.

So again, per my demo style: quick and dirty. Obviously a useful api would have error handling and return the standard status codes, which is something I did not implement here. So no, this code is not production ready, but yes it does show you have to tie it together end-to-end.

Back to Blog
Ogun
Date Posted: 8/27/2012
We had a problem with Sears when we paerhuscd a washer/dryer from them. The guys that delivered the set told us that the exhaust hose from the dryer was larger than the one going into the wall. They told my wife (who was at the house by herself) that she would have to go to Home Depot and get a smaller hose because they weren't sure they had anymore in the truck. Not that they didn't have anymore. Just that they weren't sure. She asked them to check and they never returned. Poor service after the sale.

Add a comment