如何在MVC中重载控制器

时间:2015-02-03 19:25:54

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

我正在尝试重载MVC控制器,如何正确地重载它?

我想在ListCompanies()控制器中列出我网站中的所有公司,如下所示

http://localhost:21047/Home/ListCompanies

如果用户进行如下搜索

,我想添加搜索条件
http://localhost:21047/Home/ListCompanies/sera

“sera”是我的搜索条件。如果存在搜索条件,我想根据搜索条件过滤搜索结果。

这是我的控制器

public ActionResult ListCompanies()
{
   return View(db.AY_COMPANIES);
}

[ActionName("ListCompaniesFilter")]
public ActionResult ListCompanies(string filter)
{
    var filtredCompanies = from c in db.AY_COMPANIES
                  where c.COMPANY_FULL_NAME.StartsWith(filter)
                               select c;
    return View(filtredCompanies);
}

这是我的ROUTING行为不正确。

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

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

        routes.MapRoute(
            "Home", // Route name
            "{controller}/{action}/{filter}", // URL with parameters
            new { controller = "Home", action = "ListCompanies", filter = UrlParameter.Optional} // Parameter defaults
        );
    }

我的MapRoutes不正确,因为它没有正确获取搜索条件。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

首先这些路线完全相同:

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index",
              id = UrlParameter.Optional } // Parameter defaults
    );

    routes.MapRoute(
        "Home", // Route name
        "{controller}/{action}/{filter}", // URL with parameters
        new { controller = "Home", action = "ListCompanies", 
              filter = UrlParameter.Optional} // Parameter defaults
    );

它们完全相同,因为参数的数量完全匹配(您的参数名称和参数类型不会更改http请求方法的签名)。

有几种不同的方法可以完成这项工作。如果控制器/ action / id匹配一组特定条件,您可以为Default编写MapRoute Constraint,以防止它工作。可能不是最好的行动方案。

  

http://localhost:21047/Home/ListCompanies   http://localhost:21047/Home/ListCompanies/sera   http://localhost:21047/Home/ListCompanies/text   http://localhost:21047/Home/ListCompanies/search

在程序上与{id}具有方法ListCompanies()空值的请求相同,我可能会这样写:

public ActionResult ListCompanies(string id)
{
  var query = db.AY_COMPANIES;

  if (!string.IsNullOrWhiteSpace(id))
  {
    query.Where(c => c.COMPANY_FULL_NAME.StartsWith(id))
  }

  var model = query.ToList();

  return View(model);
}

并删除“Home”MapRoute,不需要它。

答案 1 :(得分:2)

你不能以这种方式超载,因为由于两条路线具有相同的三个部分而存在调度问题,它们基本上是相同的。

"{controller}/{action}/{id}"

"{controller}/{action}/{filter}"

一种方法是将两种动作方法合并为一种

public ActionResult ListCompanies(string filter)

然后如果filter为null则返回完整列表,否则返回已过滤的列表。 我不喜欢这种做法。

解决此问题的更简单方法是:

1)删除第二条路线(带过滤器的路线)

2)从

更改操作方法的签名
public ActionResult ListCompanies(string filter)

public ActionResult ListCompanies(string id)

允许第一个路径匹配名称上的参数。

3)由于您无法重载方法,因此在请求过滤结果时需要使用ActionName,

 http://localhost:21047/Home/ListCompaniesFilter/sera

答案 2 :(得分:1)

如果您只有一个带有可选参数的操作,会发生什么?如下所示:

public ActionResult ListCompanies(string filter = null)
{
    var filteredCompanies = string.IsNullOrEmpty(filter)
         ? db.AY_COMPANIES
         : from c in db.AY_COMPANIES
           where c.COMPANY_FULL_NAME.StartsWith(filter)
           select c;
    return View(filteredCompanies);
}