Search code examples
asp.netasp.net-mvcasp.net-mvc-3asp.net-mvc-4attributerouting

ASP MVP Configuration NOT Convention


I understand a lot of the benefits of the convention over configuration approach of ASP MVC. That said, I would like to attempt to build an ASP MVC-based site using an configuration-based a approach and with route attributes.

Effectively, I'd like to have all my Controllers in the root of the project (not nested below the 'Controllers' folder) and the views beside then (no nested below the views folder).

e.g. within the root folder something like:

  • Posts.cs (Controller) - would have methods that's would map to routes via attributes

  • Posts.cshtml (View)

I've been searching and surprising have found very little on the topic.

For example i've got following controller in my root directory (more.cs)

public class More : Controller
{
    [Route("more")]
    public ActionResult Index()
    {
        return View("~/more.cshtml");
    }
}

And I'm calling this in RouteConfig.cs

routes.MapMvcAttributeRoutes();

But generates a resource cannot be found error

Again - I am not looking for WHY I would not want to do this... i understand the benefits of convention... but HOW I could do it if i wanted to (rightfully or wrongly).


Solution

  • For those that are interested... there are a number of configurations that are necessary... to attempt to do this.

    1. Remove Route Naming convention - The simplest means to do this is to use Attribute Routing on the controller class:
    
    [RoutePrefix("mypath")] 
    Public class AnyNameController : Controller{    
           [Route("prettyUrlName/{parameter}")]
           public ActionResult somefunction(string parameter){    
                 ///do stuff
           }
        }
    
    

    For this to work you need to call the following at the web application startup:

    RouteTable.Routes.MapMvcAttributeRoutes(); 2. To move any view out of the Views folder requires that you copy the Web.config settings that are in the Views folder to whereever folder you want to put the the *.cshtml view files (e.g. root)

       <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
    

    <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="us.communion.www" />
      </namespaces>
    </pages>
    

    1. Do removed the '*Controller' naming convention requires creating a custom controller factory. There is another thread about this: change controller name convention in ASP.NET MVC