27

我正在开发一个基本的问题管理系统以学习 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. 过滤某些标题(技术人员、客户、类别、优先级、状态) - ??

我不知道如何将两个参数传递给控制器​​,以便我可以组织我的查询。我也刚刚意识到,除非我弄清楚如何动态生成我的查询,否则我将需要(排序选项的数量)*(过滤器选项的数量)在我的开关中。

啊,谁能指出我正确的方向?干杯!

4

5 回答 5

33
  1. 从路线中删除排序。只需使用不带参数的路由。
  2. 将查询字符串参数添加到用于排序、过滤等的查询中。因此您的查询将如下所示:

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

public ActionResult Open(string sort, string filter)

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

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

就查询数量而言,请记住您不必一次构建整个查询。您可以使用 .OrderBy 扩展方法重新排序现有的 IQueryable<T>,与 .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);
}     
于 2009-01-28T15:47:09.023 回答
10

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


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"];
   ...


于 2009-01-29T03:17:48.050 回答
8

这应该是对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单例。

于 2009-06-18T16:55:03.417 回答
1

您可以使用 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

于 2012-03-28T11:46:56.947 回答
0

请查看下面描述所有过程的帖子 http://www.c-sharpcorner.com/UploadFile/4b0136/editing-multiple-records-using-model-binding-in-mvc/

于 2015-11-09T10:36:49.767 回答