
[英]Paging using Linq-To-Sql based on two parameters in asp.net mvc
[英]Passing multiple parameters to controller in ASP.NET MVC; also, generating on-the-fly queries in 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视图上做两件事:
我无法弄清楚如何将两个参数传递给Controller,以便我可以组织我的查询。 我也刚刚意识到,除非我弄清楚如何动态生成我的查询,我将需要(排序选项的数量)*(过滤器选项的数量)在我的交换机中。
唉,有人能指出我正确的方向吗? 干杯!
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);
}
如果你期望任意数量的参数,你可以做这样的事情。
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
单例。
您可以使用Dynamic Linq代替开关,它可以让您说:
Issues = Issues.OrderBy("Status");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.