c# - .NET MVC 路由 - 绑定(bind) 2 个 routeMap 参数

标签 c# asp.net-mvc routes

我需要像下面这样解析一个 url

/controller/action/subaction/id

目前我正在使用子 Action 开关来查看实际需要做什么。例如:

    public ActionResult Members(string subaction, long id=0)
    {
        switch (subaction)
        {
            case "Details":
                var member = _payment.GetMember(id);
                return View("Members_details", member);
            default:
                var members = _payment.GetMembers().ToList();
                return View("Members_list", members);
        }
    }

这可行,但我宁愿为每个事件单独执行操作,直接从路由访问。如果可能的话,我想结合路线图中的 Action 和子 Action 来访问正确的 Action 。

  • /controller/action/会调用 action()
  • /controller/action/subaction 会调用 action_subaction()
  • /controller/action/subaction/id 会调用 action_subaction(id)

是否可以直接从路线图中获取?

最佳答案

自定义 Action 方法选择器类

如果我是您,我会编写一个操作方法选择器 并使用它来避免在您的操作中出现分支。我写了一个分离采用可选参数的 Action (从而避免 Action 中的分支代码 - 简化单元测试)。默认的 Asp.net MVC 定义的路由有一个可选的 id 参数

{controller}/{action}/{id}
id = UrlParameter.Optional

所以有这两个 Action 方法是有意义的:

public ActionResult Index() { ... }
public ActionResult Index(int id) { ... }

我已经通过编写自定义操作选择器过滤器完成了这一点。这是一个 detailed blog post它描述了整个事情并提供了一些您可以查看的代码。

你的问题的解决方案怎么样

在您的情况下,这意味着您必须编写一个名为 SubactionAttribute 的自定义操作方法选择器类,然后用它简单地装饰您的操作:

[Subaction("Details")]
public ActionResult Members(long id)
{
    var member = _payment.GetMember(id);
    return View("Members.Details", member);
}

[Subaction] // no name would mean default subaction (when not provided)
public ActionResult Members()
{
    var members = _payment.GetMembers().ToList();
    return View("Members.List", members);
}

我不会为您编写整个类(class),但我只会为您指明正确的方向,以便您可以按照相同的路径到达目的地:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public sealed class SubactionAttribute : ActionMethodSelectorAttribute
{
    #region Properties

    /// <summary>
    /// Gets subaction name.
    /// </summary>
    public string Name { get; private set; }

    #endregion

    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="SubactionAttribute"/> class.
    /// </summary>
    public SubactionAttribute()
        : this(null)
    {
        // does nothing
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="SubactionAttribute"/> class.
    /// </summary>
    /// <param name="subactionName">Sub-action name</param>
    public SubactionAttribute(string subactionName)
    {
        this.Name = subactionName;
    }

    #endregion

    #region ActionMethodSelectorAttribute implementation

    /// <summary>
    /// Determines whether the action method selection is valid for the specified controller context.
    /// </summary>
    /// <param name="controllerContext">The controller context.</param>
    /// <param name="methodInfo">Information about the action method.</param>
    /// <returns>
    /// true if the action method selection is valid for the specified controller context; otherwise, false.
    /// </returns>
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }

        // get the value of subaction here
        string subName = /* this part you'll have to write */

        // determine whether subaction matches
        return this.Name == subName;
    }

    #endregion
}

关于c# - .NET MVC 路由 - 绑定(bind) 2 个 routeMap 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6680708/

相关文章:

javascript - 在 View 中将 Razor 语法与 Javascript 混合

asp.net-mvc - ASP.NET MVC 中的 Server.Execute()

javascript - 维护和组织 ExpressJS 路由

linux - linux 内核支持多少个 vrf,哪些系统资源限制了 vrf 数量?

c# - Enum 的 Count 和 ToList 扩展方法?

c# - 将 8 位数字转换为日期时间类型

c# - 将页面控制从 jscript 传递到代码隐藏中的 pagemethod?

c# - C#中所有的数组都实现了哪些接口(interface)?

asp.net-mvc - 编译器错误消息 : CS1583 while opening the asp.net mvc 2.0 网站

php - Slim 4 中的路由中间件不会停止调用路由中的可调用对象