Mik*_*eon 33 c# asp.net asp.net-mvc c#-6.0 nameof
是否有推荐的方式来使用新的
nameof()
Run Code Online (Sandbox Code Playgroud)
在ASP.NET MVC中表达控制器名称?
Url.Action("ActionName", "Home") <------ works
Run Code Online (Sandbox Code Playgroud)
VS
Url.Action(nameof(ActionName), nameof(HomeController)) <----- doesn't work
Run Code Online (Sandbox Code Playgroud)
显然它不起作用因为nameof(HomeController)转换为"HomeController"而MVC需要的只是"Home".
Gig*_*igi 23
我喜欢詹姆斯关于使用扩展方法的建议.只有一个问题:虽然你正在使用nameof()
并消除了魔法字符串,但仍然存在类型安全的小问题:你仍在使用字符串.因此,很容易忘记使用扩展方法,或提供无效的任意字符串(例如,错误输入控制器的名称).
我认为我们可以通过使用Controller 的通用扩展方法来改进James的建议,其中泛型参数是目标控制器:
public static class ControllerExtensions
{
public static string Action<T>(this Controller controller, string actionName)
where T : Controller
{
var name = typeof(T).Name;
string controllerName = name.EndsWith("Controller")
? name.Substring(0, name.Length - 10) : name;
return controller.Url.Action(actionName, controllerName);
}
}
Run Code Online (Sandbox Code Playgroud)
用法现在更清洁了:
this.Action<HomeController>(nameof(ActionName));
Run Code Online (Sandbox Code Playgroud)
考虑一种扩展方法:
public static string UrlName(this Type controller)
{
var name = controller.Name;
return name.EndsWith("Controller") ? name.Substring(0, name.Length - 10) : name;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用:
Url.Action(nameof(ActionName), typeof(HomeController).UrlName())
Run Code Online (Sandbox Code Playgroud)
我需要确保routeValues
正确处理,而不是总是像querystring
值一样对待。但是,我仍然想确保操作与控制器相匹配。
我的解决方案是为Url.Action
.
<a href="@(Url.Action<MyController>(x=>x.MyAction))">Button Text</a>
Run Code Online (Sandbox Code Playgroud)
我有不同类型的单参数操作的重载。如果我需要通过routeValues
...
<a href="@(Url.Action<MyController>(x=>x.MyAction, new { myRouteValue = myValue }))">Button Text</a>
Run Code Online (Sandbox Code Playgroud)
对于我没有显式创建重载的具有复杂参数的操作,需要使用控制器类型指定类型以匹配操作定义。
<a href="@(Url.Action<MyController,int,string>(x=>x.MyAction, new { myRouteValue1 = MyInt, MyRouteValue2 = MyString}))">Button Text</a>
Run Code Online (Sandbox Code Playgroud)
当然,大多数时候动作都在同一个控制器内,所以我仍然只使用nameof
这些。
<a href="@Url.Action(nameof(MyController.MyAction))">Button Text</a>
Run Code Online (Sandbox Code Playgroud)
由于routeValues
不一定与操作参数匹配,因此该解决方案允许这种灵活性。
扩展代码
namespace System.Web.Mvc {
public static class UrlExtensions {
// Usage : <a href="@(Url.Action<MyController>(x=>x.MyActionNoVars, new {myroutevalue = 1}))"></a>
public static string Action<T>(this UrlHelper helper,Expression<Func<T,Func<ActionResult>>> expression,object routeValues = null) where T : Controller
=> helper.Action<T>((LambdaExpression)expression,routeValues);
// Usage : <a href="@(Url.Action<MyController,vartype1>(x=>x.MyActionWithOneVar, new {myroutevalue = 1}))"></a>
public static string Action<T, P1>(this UrlHelper helper,Expression<Func<T,Func<P1,ActionResult>>> expression,object routeValues = null) where T : Controller
=> helper.Action<T>(expression,routeValues);
// Usage : <a href="@(Url.Action<MyController,vartype1,vartype2>(x=>x.MyActionWithTwoVars, new {myroutevalue = 1}))"></a>
public static string Action<T, P1, P2>(this UrlHelper helper,Expression<Func<T,Func<P1,P2,ActionResult>>> expression,object routeValues = null) where T : Controller
=> helper.Action<T>(expression,routeValues);
// Usage : <a href="@(Url.Action<MyController>(x=>x.MyActionWithOneInt, new {myroutevalue = 1}))"></a>
public static string Action<T>(this UrlHelper helper,Expression<Func<T,Func<int,ActionResult>>> expression,object routeValues = null) where T : Controller
=> helper.Action<T>((LambdaExpression)expression,routeValues);
// Usage : <a href="@(Url.Action<MyController>(x=>x.MyActionWithOneString, new {myroutevalue = 1}))"></a>
public static string Action<T>(this UrlHelper helper,Expression<Func<T,Func<string,ActionResult>>> expression,object routeValues = null) where T : Controller
=> helper.Action<T>((LambdaExpression)expression,routeValues);
//Support function
private static string Action<T>(this UrlHelper helper,LambdaExpression expression,object routeValues = null) where T : Controller
=> helper.Action(
((MethodInfo)((ConstantExpression)((MethodCallExpression)((UnaryExpression)expression.Body).Operand).Object).Value).Name,
typeof(T).Name.Replace("Controller","").Replace("controller",""),
routeValues);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6683 次 |
最近记录: |