2014年11月28日 星期五

使用Area產生的例外錯誤

Tool:Visual Studio 2013 Ultimate Update 4
OS:Windows 8.1
ASP.NET MVC 5

在ASP.NET MVC5專案中建立Area時發生例外錯誤:

Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

重現錯誤,建立一個範本MVC專案

image

image

加入Area

image

命為Dept

image

為Dept Area 加入HomeControllerimage

image

image

在Dept Area 的HomdController 加入Index View

image

執行Dept/Home/Index,可以正確存取:

image

 

不過,若存取/Home/Index,則發生例外錯誤:

image

原因是預設MVC範本專案中的HomeController與Dept Area下的HomeController名稱重複了。

解決方式一

在RouteConfig.cs檔案預設路由處設定Controller所在的namespace:

namespace MyWebApplication {
  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 } ,
          namespaces: new[ ] { "MyWebApplication.Controllers" }
      );
    }
  }
}

 

這樣就解決了,可存取Home/Index。

image

解決方式二

若使用Attribute Routing則可以採用RouteArea Attribute來處理。

先啟用Attribute Routing,在RouteConfig.cs:

namespace MyWebApplication {
  public class RouteConfig {
    public static void RegisterRoutes( RouteCollection routes ) {
      routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );

      routes.MapMvcAttributeRoutes( );

      //routes.MapRoute(
      //    name: "Default" ,
      //    url: "{controller}/{action}/{id}" ,
      //    defaults: new { controller = "Home" , action = "Index" , id = UrlParameter.Optional }
      //);
    }
  }
}


設定RouteArea與Route:

namespace MyWebApplication.Controllers {
 
  [RouteArea("MySite")]
  [Route( "home/{action}" )]
  public class HomeController : Controller {
    public ActionResult Index( ) {
      return View( );
    }

    public ActionResult About( ) {
      ViewBag.Message = "Your application description page.";

      return View( );
    }

    public ActionResult Contact( ) {
      ViewBag.Message = "Your contact page.";

      return View( );
    }
  }
}

 

存取Mysite/Home/Index,就可以看到路由正確套用了

image

 
我們也可以將RouteArea設定為空字串,這樣就可以使用Home/Index存取到首頁:


namespace MyWebApplication.Controllers {
 
  [RouteArea("")]
  [Route( "home/{action}" )]
  public class HomeController : Controller {
    public ActionResult Index( ) {
      return View( );
    }


    public ActionResult About( ) {
      ViewBag.Message = "Your application description page.";


      return View( );
    }


    public ActionResult Contact( ) {
      ViewBag.Message = "Your contact page.";


      return View( );
    }
  }
}


 


Home/Index 執行結果:


image

沒有留言:

總瀏覽量