属性路由不在区域中工作

时间:2013-12-09 09:14:23

标签: asp.net-mvc asp.net-mvc-routing

场景:我的ASP.NET MVC 5站点中有一个Forms区域。

我正在尝试重定向到使用使用新属性路由功能定义的自定义路由的详细信息操作。

RedirectToAction:

return RedirectToAction("Details", new { slug });

我正在重定向的行动:

[HttpGet]
[Route("forms/{slug}")]
public ActionResult Details(string slug)
{
    var form = FormRepository.Get(slug);

    ...

    return View(model);
}

我希望重定向到http://localhost/forms/my-slug,但该应用会将我重定向到http://localhost/Forms/Details?slug=my-slug

这意味着属性路由不起作用。

如何解决这个问题?

我添加了routes.MapMvcAttributeRoutes();到我的RouteConfig:

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 }
        );
    }
}

这是我的Application_Start():

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

2 个答案:

答案 0 :(得分:89)

您可能正在将基于约定的路由与属性路由相结合,并且在映射属性路由后注册您的区域

该行

AreaRegistration.RegisterAllAreas();

应在此行之后调用:

routes.MapMvcAttributeRoutes();

解释(来自http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#route-areas):

  

如果您同时使用具有路由属性的区域和具有基于约定的路由的区域(由AreaRegistration类设置),则需要确保在配置MVC属性路由后发生区域注册,但是在默认约定之前 - 基于路线设定。原因是路由注册应该从最具体(属性)到更通用(区域注册)到雾通用(默认路由)进行排序,以避免通用路由通过过早匹配传入请求来“隐藏”更具体的路由。管道。

当您创建一个空白的asp.net mvc网站,添加一个区域并开始使用属性路由时,您将遇到此问题,因为Visual Studio中的“添加区域”操作会在路由配置之前在Application_Start中添加RegisterAllAreas调用..

替代解决方案

也许您不打算继续使用基于约定的路由,而更喜欢仅使用属性路由。 在这种情况下,您只需删除FormsAreaRegistration.cs文件即可。

答案 1 :(得分:38)

将AreaRegistration.RegisterAllAreas()移动到RouteConfig.cs对我来说还不够。我还需要为RouteArea attibute使用AreaPrefix参数:

//Use the named parameter "AreaPrefix"
[RouteArea("AreaName", AreaPrefix = "area-name-in-url")]
[RoutePrefix("controller-name-in-url")]
public class SampleController : Controller
{
    [Route("{actionParameter}")]
    public ActionResult Index(string actionParameter)
    {
        return View();
    }
}

编辑:在某些时候,我遇到了一个来自Microsoft的示例解决方案,它很好地展示了如何处理属性路由。它还展示了一些很好的示例,说明了如何将SelectList转换为input[type="radio"]项的数组,以及对input[type="checkbox"]项的数组执行相同操作(如果我记得的话)。这个示例解决方案可能是这个问题的更好答案 - 以及在显示单选按钮和复选框项目时提供一些很好的示例。如果有人知道这个示例解决方案,请添加一个带有链接的评论。