Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC5.1 with Web API 2 and AngularJS

I am working on a side project to teach myself AngularJS and Web API and how the two can work together nicely.

I have good ASP.NET MVC knowledge, but I still can't get my head around AngularJS and Web API and how all three can work together.

At the moment, I have a Web API Controller with the following code:

public class PlanController : ApiController
{
    [Route("api/thing")]
    public HttpResponseMessage Post(ThingVM model)
    {
        HttpResponseMessage response;

        if (ModelState.IsValid)
        {
            using (var context = new MyContext())
            {

                var thing = new Thing();

                context.Thing.Add(thing);
                context.SaveChanges();
                response = Request.CreateResponse(HttpStatusCode.Created);
                string uri = Url.Link("GetThingById", new {id = thing.Id});
                response.Headers.Location = new Uri(uri);
            }
        }
        else
        {
            response = Request.CreateResponse(HttpStatusCode.BadRequest);
        }
        return response;
    }
}

In my Create.cshtml view I have the ng-app directive and I have created a JS controller and placed the ng-controller directive around the form, and have pointed it at the JS controller.

But here I am stuck. First of all, how do I bind my ThingVM.cs ViewModel to Angular? Do I need to return a JSONResult on my MVC controller? If Yes, how? Cause I tried, the following, and it isn't compiling.

[HttpGet]
public JsonResult Create()
{
    using (var context = new MyContext())
    {
        var model = new ThingVM();
        return Json(model);
    }
}

Assuming I get that to work, how do I bind it to AngularJS, so that it knows what my ViewModel structure is like? Because my ThingVM has many levels of complexity.

Finally, how do I handle the form submission, so that angular points at my Web API Controller for the POST request.

like image 686
J86 Avatar asked Feb 01 '14 21:02

J86


People also ask

Can we use AngularJS with ASP.NET MVC?

AngularJS can complement the server-side technology, ASP.NET MVC by simplifying and reducing the operations performed by the server. The JavaScript technology supports template engine, dependency injection and routing engine of its own.

Can we use MVC with angular?

Since then, Angular has received bi-yearly updates and today, the latest version of Angular is Angular 8. The only difference is that Angular is now based on TypeScript, which is a superset of JavaScript, but it still maintains the MVC architecture.

Can I use MVC controller as Web API?

In order to add a Web API Controller you will need to Right Click the Controllers folder in the Solution Explorer and click on Add and then Controller. Now from the Add Scaffold window, choose the Web API 2 Controller – Empty option as shown below. Then give it a suitable name and click OK.

Should I use MVC or Web API?

Web API can be used for generating HTTP services that replies data alone, but MVC would be suitable for developing web applications that replies as both, views and data. Web API looks at Accept Header of the request who returning the data in various formats, so it can return in various formats, like XML, JSON etc.


1 Answers

In MVC SPA like angular, you should separate models from views. I would suggest that your asp.mvc is where you serve your views (HTML) and your asp.net web api is where you serve your models (JSON) with CRUD operations.

Your asp.net mvc controller:

[HttpGet]
public ActionResult Create()
{
    return View(); //this return Create.cshtml
}

Your asp.net api controller:

public class PlanController : ApiController
{
    public ThingVM Get()
    {
        using (var context = new MyContext())
        {
            var model = new ThingVM();
            return model;
        }
    }

    public HttpResponseMessage Post(ThingVM model)
    {
        HttpResponseMessage response;
        //It's better to write the modelstate validation as an attribute. See improvement suggestion below
        if (ModelState.IsValid)
        {
            using (var context = new MyContext())
            {

                var thing = new Thing();

                context.Thing.Add(thing);
                context.SaveChanges();
                response = Request.CreateResponse(HttpStatusCode.Created);
                string uri = Url.Link("GetThingById", new {id = thing.Id});
                response.Headers.Location = new Uri(uri);
            }
        }
        else
        {
            response = Request.CreateResponse(HttpStatusCode.BadRequest);
        }
        return response;
    }
}

Your angular controller, here I use $http for quick demonstration. In real app, you could try angular resource to create a REST client

app.controller("planController", function ($scope, $http){
    $scope.thingVM = $http.get("api/Plan"); //load view model as json from web api

    $scope.saveThingVM = function(){
          http.post("api/Plan",$scope.thingVM); //send a post request to web api to update 
    }
});

Your Create.cshtml could be like this:

<form ng-submit="saveThingVM()" ng-controller="planController">
   <input ng-model="thingVM.Name" type="text"></input>
   <input type="submit">Save model</input>
</form>

Improvement suggestion:

Model validation is a cross-cutting concern, it's better to write the logic as an attribute to reuse the logic. Take a look at my another answer at How can I centralize modelstate validation in asp.net mvc using action filters?

like image 181
Khanh TO Avatar answered Nov 02 '22 15:11

Khanh TO