Передача нескольких параметров в контроллер в ASP.NET MVC; также генерирование запросов на лету в LINQ-to-SQL - PullRequest
27 голосов
/ 28 января 2009

Я работаю над базовой системой управления проблемами для изучения 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());
}

Это работает нормально (хотя, мне интересно, есть ли лучший способ обработать мое определение запроса, чем переключатель?), Но теперь я хочу иметь возможность сделать две вещи в представлении «Открытые проблемы»:

  1. Сортировать по любому из заголовков - ОК
  2. Фильтр по определенным рубрикам (техник, клиент, категория, приоритет, статус) - ??

Я не могу понять, как передать два параметра в контроллер, чтобы я мог организовать свои запросы. Я также только что понял, что если я не выясню, как генерировать свои запросы на лету, мне понадобится (количество опций сортировки) * (количество опций фильтра) в моем переключателе.

Argh, кто-нибудь может указать мне в правильном направлении? Ура!

Ответы [ 5 ]

33 голосов
/ 28 января 2009
  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);
}     
10 голосов
/ 29 января 2009

Если вы ожидаете произвольное количество параметров, вы можете сделать что-то вроде этого.


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


8 голосов
/ 18 июня 2009

Это должен быть комментарий к ответу 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);
    }
}

Теперь вы можете добавить атрибут к вашему действию, например, [QueryStringFilter("attributes")], и он передаст значения строки запроса как FormCollection. Таким образом, ваши действия легче проверяются, так как они больше не зависят от Request синглтона.

1 голос
/ 28 марта 2012

Вместо переключателя вы можете использовать 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

0 голосов
/ 09 ноября 2015

Пожалуйста, проверьте пост ниже, который описывает все процессы http://www.c -sharpcorner.com / UploadFile / 4b0136 / редактирование-кратно-записи, использующих-модель связывания-в-MVC /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...