【问题标题】:UrlHelper.Action without hard-coded strings for controllerName and controllerActionUrlHelper.Action 没有用于 controllerName 和 controllerAction 的硬编码字符串
【发布时间】:2019-07-04 16:28:07
【问题描述】:

我想创建一个方便的辅助方法,帮助从给定的控制器类型和该控制器上的操作/方法构造一个 URL。在ASP.NET Core MVC 中有一个IUrlHelper.Action(string actionName, string controllerName) 方法可以做同样的事情。

但是,而不是这个:UrlHelper.Action("MyAction", "MyController")

我想使用:UrlHelper.Action<MyController>(c => c.MyAction)

现在,我只部分设法解决了这个问题,这使我可以使用以下代码执行以下操作:UrlHelper.Action<MyController>(c => c.MyAction())(注意操作名称后的括号):

    public static string ActionFor<TController>(this IUrlHelper source, Expression<Func<TController, object>> memberExpression) where TController : Controller
    {
        if (!(memberExpression.Body is MemberExpression body)) throw new ArgumentException($"Expression must be a {typeof(MemberExpression).Name}.", nameof(memberExpression));

        return source.Action(body.Member.Name, typeof(TController).RemoveControllerSufix());
    }

但我不知道如何告诉编译器我希望 memberExpression 参数接受一个方法组(或类似的),所以我可以编写不带括号的操作名称。

附:我们也可以这样做:UrlHelper.Action&lt;MyController&gt;(nameof(MyController.MyAction)),这也避免了字符串的硬编码,但仍然重复了控制器类型,这也是很好的避免。

我想我在 SO 上的某个地方看到了 Jon Skeet 的帖子,与类似的东西有关,但我现在找不到它......

【问题讨论】:

  • 不久前我问了一个类似的问题。我发誓它最初有一个答案。无论哪种方式,这种情绪似乎都是不可能的。 stackoverflow.com/q/41223581/491907

标签: c# asp.net-core lambda .net-core asp.net-core-mvc


【解决方案1】:

获取方法组的名称有点繁琐。这就是它的工作原理(在 dotnet6/C#10.0 中测试)。

调用获取方法组的名称:

var name = GetMethodGroupName<Foo>(f => f.Bar);
// name: "Bar"

模式匹配方法

private static string GetMethodGroupName<TController>(Expression<Func<TController, object>> memberExpression)
{
    if (memberExpression.Body is UnaryExpression
        { Operand: MethodCallExpression
            { Object: ConstantExpression
                { Value: MethodInfo me } } })
        return me.Name;

    throw new ArgumentException(
        "expression does not look like a method group.", 
        nameof(memberExpression));
}

...或者使用连接检查...

private static string GetMethodGroupName<TController>(Expression<Func<TController, object>> memberExpression)
{
    if (memberExpression.Body is UnaryExpression ue)
        if (ue.Operand is  MethodCallExpression mce)
            if (mce.Object is ConstantExpression ce)
                if (ce.Value is MethodInfo me)
                    return me.Name;

    throw new ArgumentException(
        "expression does not look like a method group.", 
        nameof(memberExpression));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2010-11-07
    相关资源
    最近更新 更多