使用属性路由填充 Defaults RouteValueDictionary
Populate the Defaults RouteValueDictionary with attribute routing
我正在将一个 ASP.NET MVC 4 项目升级到 MVC 5,并希望使用属性路由而不是约定路由。到目前为止一切顺利,但我在填充 Defaults
RouteValueDictionary
时遇到了一个问题。这如何通过属性路由来实现?
我正在为同一个动作使用多个路由,每个路由都传递一个不同的枚举值来确定该动作是哪种类型。枚举的值不会直接在路由中可见!这很重要,否则我可以在路由模板中使用枚举参数的值。
我的简化控制器操作:
public class MyController : Controller
{
public ActionResult MyAction(MyType myTypeValue)
{
// ...
}
}
public enum MyType
{
FirstOption,
SecondOption
}
我的旧公约路线:
routes.Add("First", new Route("a-route", new { controller = "MyController", action = "MyAction", myTypeValue = MyType.FirstOption }));
routes.Add("Second", new Route("a-total/different-route", new { controller = "MyController", action = "MyAction", myTypeValue = MyType.Second }));
对于属性路由,我希望使用这样的东西:
Route["a-route", new { myTypeValue = MyType.FirstOption }]
Route["a-total/different-route", new { myTypeValue = MyType.SecondOption }]
但不幸的是,这并不存在。我试图制作一个自定义 RouteAttribute
接受一个对象来填充 Defaults
RouteValueDictionary
:
public class MyRouteAttribute : RouteFactoryAttribute
{
private RouteValueDictionary _defaults;
public Route(string template, object defaults)
:base(template)
{
_defaults = new RouteValueDictionary(defaults);
}
public override RouteValueDictionary Defaults
{
get { return _defaults; }
}
}
但这不起作用,因为路由属性无法处理匿名类型的编译时间。
有谁知道以某种方式让它工作的方法吗?
"Just make two different actions" 不是这里的选项。
首先,您不清楚为什么要从基于约定的路由更改为(不太灵活的)基于属性的路由,尤其是考虑到后者不支持您感兴趣的某些功能.
但是,如果您只是因为 "looks cool" 而坚持更改为属性路由,那么您有几个选择。
选项 1:制定单独的操作方法
如果您使用 2 个不同的操作并从第一个开始 return 一个操作,您通常不必重写逻辑。但这是属性路由中对设置可选参数的唯一原生支持。 Enum
支持可选参数的示例可以是 found here.
[Route("a-route")]
public ActionResult MyAction(MyType myTypeValue = MyType.FirstOption)
{
return View("Index");
}
[Route("a-total/different-route")]
public ActionResult My2ndAction(MyType myTypeValue = MyType.SecondOption)
{
return MyAction(myTypeValue);
}
选项 2:破解属性路由框架
Microsoft 通过使用几种 internal/private 类型来加载具有属性路由的 RouteValueCollection
,故意使属性路由框架不可扩展。
您可能会破解属性路由框架以提供您自己的逻辑 。这需要使用反射,但由于它在应用程序启动时运行,而不是按请求运行,因此对整体性能的影响将是最小的。
但根据您的要求,您可能需要从 MVC 属性路由框架复制更多逻辑来填充您的路由,这可能不值得付出努力。在我支持多种文化的简单案例中,确实如此。在您的情况下,您将需要使用附加参数来支持您自己的属性类型,这将更具挑战性。
但如果您需要比这更大的灵活性,我建议您坚持使用基于约定的路由。
- Attributes have limitations on which datatypes are supported 相对于基于代码的解决方案。
- 使用属性路由时,包括填充默认路由值、使用约束和构建自定义路由在内的多项功能要么更加困难,要么不受支持。
底线是,属性路由不是路由的圣杯。它是 MVC 5 中添加的另一个路由选项,可以在基于约定的路由能够实现的路由场景的有限子集下使用。它不是也不应该被视为路由 "upgrade" 只是因为它恰好在 MVC 5 之前不是一个选项。
我正在将一个 ASP.NET MVC 4 项目升级到 MVC 5,并希望使用属性路由而不是约定路由。到目前为止一切顺利,但我在填充 Defaults
RouteValueDictionary
时遇到了一个问题。这如何通过属性路由来实现?
我正在为同一个动作使用多个路由,每个路由都传递一个不同的枚举值来确定该动作是哪种类型。枚举的值不会直接在路由中可见!这很重要,否则我可以在路由模板中使用枚举参数的值。
我的简化控制器操作:
public class MyController : Controller
{
public ActionResult MyAction(MyType myTypeValue)
{
// ...
}
}
public enum MyType
{
FirstOption,
SecondOption
}
我的旧公约路线:
routes.Add("First", new Route("a-route", new { controller = "MyController", action = "MyAction", myTypeValue = MyType.FirstOption }));
routes.Add("Second", new Route("a-total/different-route", new { controller = "MyController", action = "MyAction", myTypeValue = MyType.Second }));
对于属性路由,我希望使用这样的东西:
Route["a-route", new { myTypeValue = MyType.FirstOption }]
Route["a-total/different-route", new { myTypeValue = MyType.SecondOption }]
但不幸的是,这并不存在。我试图制作一个自定义 RouteAttribute
接受一个对象来填充 Defaults
RouteValueDictionary
:
public class MyRouteAttribute : RouteFactoryAttribute
{
private RouteValueDictionary _defaults;
public Route(string template, object defaults)
:base(template)
{
_defaults = new RouteValueDictionary(defaults);
}
public override RouteValueDictionary Defaults
{
get { return _defaults; }
}
}
但这不起作用,因为路由属性无法处理匿名类型的编译时间。
有谁知道以某种方式让它工作的方法吗?
"Just make two different actions" 不是这里的选项。
首先,您不清楚为什么要从基于约定的路由更改为(不太灵活的)基于属性的路由,尤其是考虑到后者不支持您感兴趣的某些功能.
但是,如果您只是因为 "looks cool" 而坚持更改为属性路由,那么您有几个选择。
选项 1:制定单独的操作方法
如果您使用 2 个不同的操作并从第一个开始 return 一个操作,您通常不必重写逻辑。但这是属性路由中对设置可选参数的唯一原生支持。 Enum
支持可选参数的示例可以是 found here.
[Route("a-route")]
public ActionResult MyAction(MyType myTypeValue = MyType.FirstOption)
{
return View("Index");
}
[Route("a-total/different-route")]
public ActionResult My2ndAction(MyType myTypeValue = MyType.SecondOption)
{
return MyAction(myTypeValue);
}
选项 2:破解属性路由框架
Microsoft 通过使用几种 internal/private 类型来加载具有属性路由的 RouteValueCollection
,故意使属性路由框架不可扩展。
您可能会破解属性路由框架以提供您自己的逻辑
但根据您的要求,您可能需要从 MVC 属性路由框架复制更多逻辑来填充您的路由,这可能不值得付出努力。在我支持多种文化的简单案例中,确实如此。在您的情况下,您将需要使用附加参数来支持您自己的属性类型,这将更具挑战性。
但如果您需要比这更大的灵活性,我建议您坚持使用基于约定的路由。
- Attributes have limitations on which datatypes are supported 相对于基于代码的解决方案。
- 使用属性路由时,包括填充默认路由值、使用约束和构建自定义路由在内的多项功能要么更加困难,要么不受支持。
底线是,属性路由不是路由的圣杯。它是 MVC 5 中添加的另一个路由选项,可以在基于约定的路由能够实现的路由场景的有限子集下使用。它不是也不应该被视为路由 "upgrade" 只是因为它恰好在 MVC 5 之前不是一个选项。