在ASP.NET MVC中将多个参数传递给控制器​​; 另外,在LINQ-to-SQL中生成即时查询

我正在研究一个基本的问题管理系统,以便学习ASP.NET MVC。 我已经把它运行到相当不错的水平,但我遇到了一个问题。

我有一个名为Issue的控制器,其视图名为Open。 / Issue / Open列出当前系统上记录的所有未解决问题。 我已经定义了这样的路线:

routes.MapRoute( "OpenSort", // Route name "Issue/Open/{sort}", // URL with parameters new { controller = "Issue", action = "Open", sort = "TimeLogged" } // Parameter defaults ); 

到目前为止,这是正常工作,使用IssueController.cs中的以下代码:

 public ActionResult Open(string sort) { var Issues = from i in db.Issues where i.Status == "Open" orderby i.TimeLogged ascending select i; switch (sort) { case "ID": Issues = from i in db.Issues where i.Status == "Open" orderby i.ID ascending select i; break; case "TimeLogged": goto default; case "Technician": Issues = from i in db.Issues where i.Status == "Open" orderby i.Technician ascending select i; break; case "Customer": Issues = from i in db.Issues where i.Status == "Open" orderby i.Customer ascending select i; break; case "Category": Issues = from i in db.Issues where i.Status == "Open" orderby i.Category ascending select i; break; case "Priority": Issues = from i in db.Issues where i.Status == "Open" orderby i.Priority ascending select i; break; case "Status": Issues = from i in db.Issues where i.Status == "Open" orderby i.Status ascending select i; break; default: break; } ViewData["Title"] = "Open Issues"; ViewData["SortID"] = sort.ToString(); return View(Issues.ToList()); } 

这工作正常(虽然,我想知道是否有更好的方法来处理我的查询定义而不是交换机?)但现在我希望能够在Open Issues视图上做两件事:

  1. 按任何标题排序 – 好的
  2. 过滤某些标题(技术人员,客户,类别,优先级,状态) – ??

我无法弄清楚如何将两个参数传递给Controller,以便我可以组织我的查询。 我也刚刚意识到,除非我弄清楚如何动态生成我的查询,我将需要(排序选项的数量)*(filter选项的数量)在我的交换机中。

唉,有人能指出我正确的方向吗? 干杯!

  1. 从路线中删除排序。 只需使用没有参数的路线。
  2. 将查询字符串参数添加到查询中以进行排序,过滤等。因此,您的查询将如下所示:

http://example.com/Issue/Open?sort=ID&filter=foo

 public ActionResult Open(string sort, string filter) 

MVC框架将填充查询字符串参数的参数。 确保并为可能未填写的任何查询字符串参数参数使用可空类型(如字符串)。

我实际上认为这是一种“更正确”的方式来编写URL。 URL本身标识资源(开放问题); 查询字符串参数自定义如何显示资源。

就查询数量而言,请记住您不必一次构建整个查询。 您可以使用.OrderBy扩展方法重新排序现有的IQueryable ,类似于.Where。

 var Issues = from i in db.Issues where i.Status == "Open" select i; switch (sort) { case "ID": Issues = Issues.OrderBy(i => i.ID); break; // [...] default: Issues = Issues.OrderBy(i => i.TimeLogged); } 

如果你期望任意数量的参数,你可以做这样的事情。

 public ActionResult Open(){ string[] keys = Request.QueryString.AllKeys; Dictionary queryParams = new Dictionary(); foreach (string key in keys) { queryParams[key] = Request.QueryString[key]; } string sort = queryParams["sort"]; ... 

这应该是对kimsks答案的评论,但由于某些原因,评论要求我进行审查,所以我必须将其发布在错误的地方。

处理任意数量的查询字符串参数的更好方法是使用ActionFilter如下所示:

 public class QueryStringFilterAttribute : ActionFilterAttribute { public string ParameterName { get; private set; } public QueryStringFilterAttribute(string parameterName) { if(string.IsNullOrEmpty(parameterName)) throw new ArgumentException("ParameterName is required."); ParameterName = parameterName; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var qs = new FormCollection(filterContext.HttpContext.Request.QueryString); filterContext.ActionParameters[ParameterName] = qs; base.OnActionExecuting(filterContext); } } 

现在您可以将an属性添加到您的操作中,如[QueryStringFilter("attributes")] ,它将作为FormCollection传递查询字符串值。 这样您的操作就更容易测试,因为它不再依赖于Request singleton。

您可以使用Dynamic Linq代替开关,它可以让您说:

 Issues = Issues.OrderBy("Status"); 

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

请查看下面的post,其中介绍了所有流程http://www.c-sharpcorner.com/UploadFile/4b0136/editing-multiple-records-using-model-binding-in-mvc/