Reputation: 25
In the interest of crawling before walking with angularjs, I have created a simple application to display results from a sql server table using webapi. unfortunately the webapi is never called, because the routing is wrong, but I am not sure how to resolve. fiddler shows a 404 error.
the cshtml is as follows, defining the app and controller.
<script type="text/javascript">
var app = angular.module('streamApp', []);
app.controller('streamController', function($scope, $http){
$scope.loading = true;
$scope.addMode = false;
//Used to display the data
$http.get('/api/Stream/').success(function (data) {
$scope.streams = data;
$scope.loading = false;
})
.error(function () {
$scope.error = "An Error has occured while loading streams!";
$scope.loading = false;
});
});
</script>
the rendering section in the cshtml file is
<div data-ng-app="streamApp" data-ng-controller="streamController" class="container">
....
</div>
The webapi class is in a folder named WebApi in the MVC project, but since it is never reached, there is no point in displaying its code. it is non-descript anyway.
The route config is as follows:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
I am not sure if I need to specify route instructions in angularjs code or in mvc route config, and exactly what functions or configuration to supply. I have tried moving the webapi class to the Controllers folder with the same results - http 404. Any advice on how to make this example get to the webapi code would be appreciated.
well hot-diggity....I solved the immediate problem by adding the annotation to my webapi class method
[Route("api/stream")]
[System.Web.Http.HttpGet]
public IEnumerable<Models.StreamViewModel> Get()
{
.....
}
so now the question is should something be done with RouteConfig as a better practice? Or is the Route() annotation the preferred way to go? or is it 6 of one half a dozen of the other?
Upvotes: 1
Views: 649
Reputation: 1182
Answer to your updated question , Best Practice of routing:
Route() annotation is the preferred way of doing this.
MVC 5 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web application.
The earlier style of routing, called convention-based routing, is still fully supported. In fact, you can combine both techniques in the same project.
There are other advantages of attribute routing like
It puts the route information adjacent to the controller action that implements that route. This helps in debugging and troubleshooting, as well as providing an ability to quickly search for route information in your solution.
It reduces risk in the process of making changes to routes. In RouteConfig.cs or WebApiConfig.cs (in the case of Web API solutions), the possibility exists to inadvertently change the wrong route or otherwise adversely affect other parts of your application.
You may also want to include acceptable HTTP methods, permitted user types and registration priorities, which if included with the attribute-based routes, put all of that information together in one place.
This post provided inspiration and reinforcement for me on the above, and goes into more detail: http://kevinmontrose.com/2011/07/25/why-i-love-attribute-based-routing/
Upvotes: 1
Reputation: 125
First , you should use ApiController rather then Controller, as it take a role of an api action.
Second, If we take a look, it looks like you created a controller named ApiController, and a function called Stream. Otherwise, its a misunderstanding of the designing your web integration using MVC.
App_Start\WebApiConfig.cs:
using System.Web.Http;
class WebApiConfig
{
public static void Register(HttpConfiguration configuration)
{
configuration.Routes.MapHttpRoute("API Default", "api/{controller}/{action}/{id}",
new { id = RouteParameter.Optional });
}
}
Global.asax.cs:
using System.Web.Http;
...
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
WebApiConfig.Register(GlobalConfiguration.Configuration);
RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
and ApiControllerNameController: //The Controller word closes the file name, and will be reached without writing it:
using System;
..
..
..
namespace MvcApplication1.Controllers
{
public class ValuesController : ApiController
{
// GET api/values/MethodName
public IEnumerable<int> MethodName()
{
return new List<int> { 1, 2, 3 };
}
}
}
Upvotes: 0
Reputation: 3101
You can use either, but without the annotation your endpoint would have been api/get
not api/stream
(assuming you didn't rename your method).
Upvotes: 0