MVC路由约束自定义属性

时间:2016-01-22 16:51:49

标签: asp.net-mvc

我想设置一个自定义路由约束,允许我使用属性修饰控制器,这样我就不必将字符串传递给路径并记住用新的控制器名称更新它。

我以为我可以设置使用IRouteConstraint,但我似乎无法获得该属性。也许我只是错过了一些明显的东西。

routes.MapRoute("test", 
    "foo/{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { controller = new TestConstraint()}
);

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



public class TestConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, 
        RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        return false;
    }
}

[AttributeUsage(AttributeTargets.Class)]
public class CustomConstraintControllerAttribute : Attribute
{

}

[CustomConstraintController]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

修改

当前方法:

routes.MapSubdomainRoute("Store",
    "{store}/{controller}/{action}/{id}",
    new {controller = "Home", action = "Index", id = UrlParameter.Optional},
    new {controller = "StoreHome|Contacts|..." }
    );

此路线配置可确保网址必须与subdomain.test.com/GiggleInc/Contactssubdomain.test.com/GiggleInc/StoreHome匹配。

subdomain.test.com/GiggleInc/StoreHome
MapSubdomainRoute /{store}  /{controller}/{action}/{id}

此方法要求将以这种方式使用的每个控制器必须添加到控制器约束中。

正如我在评论中提到的,我希望替换属性或类似内容的硬编码字符串。

2 个答案:

答案 0 :(得分:0)

试试这个......

public class TestRouteAttribute : RouteFactoryAttribute
{      
    public TestRouteAttribute(string template) : base(template) { }

    public override RouteValueDictionary Constraints
    {
        get
        {
            var constraints = new RouteValueDictionary();
            constraints.Add("TestConstraint", new TestConstraint());
            return constraints;
        }
    }
}

然后你应该能够使用[TestRoute]

来装饰你的行动方法

顺便说一下,如果有人知道的话,很想知道如何在asp.net核心中完成这个。

答案 1 :(得分:0)

首先,感谢您提供的这行我不知道的代码:

constraints: new { controller = "StoreHome|Contacts" }

我不知道我能如此轻松地将MapRoute过滤到控制器列表中。
其次,您无需为此实现自定义IRouteConstraint。
MVC提供您正在寻找的属性路由。

您甚至可以包括默认/可选值,就像在MapRoute中一样。
像这样装饰您的Controller类:

[RoutePrefix("{store}/Test")]
[Route("{action=Index}/{id?}")]//Without this, you need to define "[Route]" above every Action-Method.
public class TestController : Controller
{
    public ActionResult Index(string store)//Adding "string store" is optional.
    {
        return View();
    }
}

就是这样。
记住要在每个控制器下的所有操作中添加“ store ”参数(但这不是必需的)。

注意
如果使用属性而不是MapRoute,则不能不能在没有“ store ”前缀的情况下访问Controller。
使用Custom和Default MapRoutes,您可以通过任何一种方式访问​​控制器。
通过使用这些属性装饰Controller,现在您可以 force 使其仅使用此确切路径。
这可能就是您想要的,但是如果您在其中一个视图上从Visual Studio启动IIS Express,它将找不到它,因为Visual Studio不知道为您添加RoutePrefix。

有关此属性路由的更多信息,请参见以下链接:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/