ASP.NET MVC 模棱两可的动作方法 [英] ASP.NET MVC ambiguous action methods

查看:19
本文介绍了ASP.NET MVC 模棱两可的动作方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个相互冲突的操作方法.基本上,我希望能够使用两个不同的路由到达同一个视图,要么通过项目的 ID,要么通过项目的名称及其父项(项目可以在不同的父项中具有相同的名称).搜索词可用于过滤列表.

I have two action methods that are conflicting. Basically, I want to be able to get to the same view using two different routes, either by an item's ID or by the item's name and its parent's (items can have the same name across different parents). A search term can be used to filter the list.

例如...

Items/{action}/ParentName/ItemName
Items/{action}/1234-4321-1234-4321

这是我的操作方法(还有Remove 操作方法)...

Here are my action methods (there are also Remove action methods)...

// Method #1
public ActionResult Assign(string parentName, string itemName) { 
    // Logic to retrieve item's ID here...
    string itemId = ...;
    return RedirectToAction("Assign", "Items", new { itemId });
}

// Method #2
public ActionResult Assign(string itemId, string searchTerm, int? page) { ... }

这里是路线...

routes.MapRoute("AssignRemove",
                "Items/{action}/{itemId}",
                new { controller = "Items" }
                );

routes.MapRoute("AssignRemovePretty",
                "Items/{action}/{parentName}/{itemName}",
                new { controller = "Items" }
                );

我理解错误发生的原因,因为 page 参数可以为 null,但我无法找出解决它的最佳方法.我的设计一开始就很差吗?我想过扩展 Method #1 的签名以包含搜索参数,并将 Method #2 中的逻辑移出到他们都会调用的私有方法中,但是我认为这不会真正解决歧义.

I understand why the error is occurring, since the page parameter can be null, but I can't figure out the best way to resolve it. Is my design poor to begin with? I've thought about extending Method #1's signature to include the search parameters and moving the logic in Method #2 out to a private method they would both call, but I don't believe that will actually resolve the ambiguity.

任何帮助将不胜感激.

实际解决方案(基于李维斯的回答)

我添加了以下类...

public class RequireRouteValuesAttribute : ActionMethodSelectorAttribute {
    public RequireRouteValuesAttribute(string[] valueNames) {
        ValueNames = valueNames;
    }

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
        bool contains = false;
        foreach (var value in ValueNames) {
            contains = controllerContext.RequestContext.RouteData.Values.ContainsKey(value);
            if (!contains) break;
        }
        return contains;
    }

    public string[] ValueNames { get; private set; }
}

然后修饰动作方法...

And then decorated the action methods...

[RequireRouteValues(new[] { "parentName", "itemName" })]
public ActionResult Assign(string parentName, string itemName) { ... }

[RequireRouteValues(new[] { "itemId" })]
public ActionResult Assign(string itemId) { ... }

推荐答案

MVC 不支持仅基于签名的方法重载,因此会失败:

MVC doesn't support method overloading based solely on signature, so this will fail:

public ActionResult MyMethod(int someInt) { /* ... */ }
public ActionResult MyMethod(string someString) { /* ... */ }

但是,它确实支持基于属性的方法重载:

However, it does support method overloading based on attribute:

[RequireRequestValue("someInt")]
public ActionResult MyMethod(int someInt) { /* ... */ }

[RequireRequestValue("someString")]
public ActionResult MyMethod(string someString) { /* ... */ }

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute {
    public RequireRequestValueAttribute(string valueName) {
        ValueName = valueName;
    }
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
        return (controllerContext.HttpContext.Request[ValueName] != null);
    }
    public string ValueName { get; private set; }
}

在上面的示例中,该属性只是表示如果请求中存在键 xxx,则此方法匹配".如果更适合您的目的,您还可以通过包含在路由 (controllerContext.RequestContext) 中的信息进行过滤.

In the above example, the attribute simply says "this method matches if the key xxx was present in the request." You can also filter by information contained within the route (controllerContext.RequestContext) if that better suits your purposes.

这篇关于ASP.NET MVC 模棱两可的动作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆