visual studio 2012 - ASP.net MVC 4, How to keep routing to default document after project publishing

24
2014-04
  • Sami-L

    I created a new MVC 4 project from the internet application template in VS 2012 express, for details click here

    When I wanted to publish it, I got: HTTP 403.14 - Forbidden

    I searched for a solution, and found that it looks like a routing issue, other posts in stackoverflow give answers through modifying MVC 3 global.asax instructions.

    when I tried to apply the same solution to the MVC 4 global.asax I found syntaxes too different from those of MVC 3, i.e. RouteConfig.RegisterRoutes(RouteTable.Routes)

    namespace MyMVC4
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                AuthConfig.RegisterAuth();
                }
            }
        }
    
  • Answers
  • Sami-L

    My doubt was wrong, This is why it happens, and the solution is provided by Dommer here, The procedure is the same for Visual Studio 2012.


  • Related Question

    c# - MVC4 API Routing goes to first action
  • Billdr

    I am attempting to write an API. The signatures look like this:

    public class CardsController : ApiController
    {
        [HttpGet]
        public ClientData NewGame(){...}
        [HttpGet]
        public ClientData Deal(int sessionId){...}
        [HttpGet]
        public ClientData Stand(int sessionId){...}
    }
    

    With everything else at default I was getting an error saying my class couldn't differentiate between Deal and Stand. After a bit of research I found it was a routing issue. So I decided to update my routing.

    My global.asax.cs now looks like this:

    public class MvcApplication : HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
    
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
            RegisterRoutes(RouteTable.Routes);
        }
    
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapHttpRoute("api", "api/{controller}/{action}/{value}", new { value = RouteParameter.Optional});
        }
    }
    

    Going to http://localhost:54924/api/Cards/Stand/19 gives an error that says no HttpResource was found, and going to http://localhost:54924/api/Cards/Stand triggers the NewGame() action. How can I get Stand and Deal to work on the same controller?


  • Related Answers
  • Mickael Caruso

    Add the routes:

    routes.MapHttpRoute("DealApi", 
                        "api/{controller}/deal/{sessionId}",
                        new { action="Deal", sessionId = RouteParameter.Optional });
    
    
    routes.MapHttpRoute("StandApi", 
                        "api/{controller}/stand/{sessionId}",
                        new { action="Stand", sessionId = RouteParameter.Optional });
    

    Now, in your Controller class:

    [HttpGet]
    [ActionName("Deal")]
    public ClientData Deal(int sessionId){...}
    
    [HttpGet]
    [ActionName("Stand")]
    public ClientData Stand(int sessionId){...}
    

    Now, whenever you pull up the url http://www.yourhost.com/api/deal/12345, the Deal function will be called. Same thing with Stand.

    Keep in mind that whatever you set in your routes tables are only for recognizing whether a url is valid. By having the action specified in the third parameter, you're telling Web Api to find a function whose ActionName attribute is set to what you specify.

    Another thing - put those two routes BEFORE any of your default api routes.

  • Darin Dimitrov

    Web API works with RESTful routes. In REST you have resources and standard actions with them: GET, POST, PUT, PATCH and DELETE. That's how your actions should be named. Deal and Stand means absolutely noting in RESTful routing. When you are designing an API you should be thinking in terms of resources and the standard HTTP verbs that you could do with those resources. In a RESTful API the controller represents your resource and the HTTP verbs are the actions that you want to perform with this resource.

    If you want to violate the default RESTful conventions that are built into the Web Api routing you will have to modify your route setup and include the {action} name in it. Then you will be able to name your actions however you want. Just bare in mind that if you are designing an API there are standards that consumers adhere to. If you want to be reinventing wheels make sure you have really good documentation of your API.