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.
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.
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.
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.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With