【问题标题】:Passing custom arguments to controllers in mvc3将自定义参数传递给 mvc3 中的控制器
【发布时间】:2012-02-14 22:47:11
【问题描述】:

有没有办法在定义路由表时将参数传递给控制器​​?

所以同一个控制器可以用于两个或多个“部分”,例如

http://site.com/BizContacts   // internal catid = 1 defined in the route        
http://site.com/HomeContacts   // internal catid = 3
http://site.com/OtherContacts   // internal catid = 4

控制器获取路由表中定义的自定义参数,通过该附加参数过滤和显示数据

所以在上面的示例中,将显示索引操作,并且显示的数据将由查询返回,例如

 select * from contacts where cat_id = {argument} // 1 or 3 or 4

我希望这有点清楚

感谢您的帮助?

【问题讨论】:

  • 如果类别名称是唯一的,为什么不将它们用作您的过滤器?

标签: c# .net asp.net-mvc asp.net-mvc-3


【解决方案1】:

您可以编写自定义路线:

public class MyRoute : Route
{
    private readonly Dictionary<string, string> _slugs;

    public MyRoute(IDictionary<string, string> slugs)
        : base(
        "{slug}", 
        new RouteValueDictionary(new 
        { 
            controller = "categories", action = "index" 
        }), 
        new RouteValueDictionary(GetDefaults(slugs)), 
        new MvcRouteHandler()
    )
    {
        _slugs = new Dictionary<string, string>(
            slugs, 
            StringComparer.OrdinalIgnoreCase
        );
    }

    private static object GetDefaults(IDictionary<string, string> slugs)
    {
        return new { slug = string.Join("|", slugs.Keys) };
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        if (rd == null)
        {
            return null;
        }
        var slug = rd.Values["slug"] as string;
        if (!string.IsNullOrEmpty(slug))
        {
            string id;
            if (_slugs.TryGetValue(slug, out id))
            {
                rd.Values["id"] = id;
            }
        }
        return rd;
    }
}

可以在Application_Startglobal.asax注册:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(
        "MyRoute", 
        new MyRoute(
            new Dictionary<string, string> 
            { 
                { "BizContacts", "1" },
                { "HomeContacts", "3" },
                { "OtherContacts", "4" },
            }
        )
    );

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

最后你可以拥有你的 CategoriesController:

public class CategoriesController : Controller
{
    public ActionResult Index(string id)
    {
        ...
    }
}

现在:

  • http://localhost:7060/bizcontacts 将触发 Categories 控制器的 Index 动作并传递 id=1
  • http://localhost:7060/homecontacts 将点击Categories 控制器的Index 操作并传递 id=3
  • http://localhost:7060/othercontacts 将点击 Index 控制器的 Index 动作并传递 id=4

【讨论】:

  • 看起来不错,这会支持类别控制器中的其他操作吗?例如site.com/BizContacts/Edit/4 等?
  • @Kumar,不,不会。但是您可以通过更改基本构造函数调用来更新它以支持。此外,您可能需要将 {id} 路由参数更改为 {categoryid} 以便更清楚地区分它和 url 末尾的参数。
猜你喜欢
  • 1970-01-01
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 2014-06-06
相关资源
最近更新 更多