web-dev-qa-db-fra.com

Passage de plusieurs paramètres au contrôleur dans ASP.NET MVC; également, générer des requêtes à la volée dans LINQ-to-SQL

Je travaille sur un système de gestion de problèmes de base afin d'apprendre ASP.NET MVC. Je l'ai eu à un niveau assez décent mais j'ai rencontré un problème.

J'ai un contrôleur nommé Issue avec une vue appelée Open./Issue/Open répertorie tous les problèmes en cours actuellement consignés sur le système. J'ai défini un itinéraire comme suit:

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

Cela fonctionne très bien jusqu'à présent, en utilisant le code suivant dans 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());
}

Cela fonctionne bien (bien que je me demande s’il existe un meilleur moyen de gérer ma définition de la requête qu’un commutateur?), Mais je souhaite maintenant pouvoir effectuer deux opérations dans la vue Problèmes en suspens:

  1. Trier par les rubriques - OK
  2. Filtrer sur certaines rubriques (Technicien, Client, Catégorie, Priorité, Statut) - ??

Je n'arrive pas à comprendre comment passer deux paramètres au contrôleur afin de pouvoir organiser mes requêtes. Je viens également de me rendre compte que si je ne sais pas comment générer mes requêtes à la volée, il me faut le nombre d'options de tri * (le nombre d'options de filtres) dans mon commutateur.

Argh, est-ce que quelqu'un peut me diriger dans la bonne direction? À votre santé!

27
Rob Burke
  1. Supprimer le tri de l'itinéraire. Utilisez simplement une route sans paramètre.
  2. Ajoutez des paramètres de chaîne de requête à la requête pour le tri, le filtre, etc. Ainsi, votre requête ressemblera à:

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

public ActionResult Open(string sort, string filter)

La structure MVC remplira les arguments à partir des paramètres de chaîne de requête. Assurez-vous et utilisez des types nullables (comme chaîne) pour chacun de ces arguments de paramètre de chaîne de requête qui pourraient ne pas être renseignés.

Je pense en fait que c'est une façon "plus correcte" d'écrire l'URL. L'URL elle-même identifie la ressource (problèmes en suspens); les paramètres de la chaîne de requête personnalisent l'affichage de la ressource.

En ce qui concerne le nombre de requêtes, rappelez-vous qu'il n'est pas nécessaire de créer la requête complète en une fois. Vous pouvez utiliser la méthode d'extension .OrderBy pour commander à nouveau un <T> IQueryable existant, et de manière similaire avec .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);
}     
33
Craig Stuntz

Si vous attendez un nombre arbitraire de paramètres, vous pouvez faire quelque chose comme ceci.


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


10
kimsk

Cela devrait être un commentaire pour que kimsks réponde, mais pour une raison quelconque, les commentaires exigent que je sois vérifié, de sorte que je dois le poster au mauvais endroit.

Un meilleur moyen de gérer un nombre arbitraire de paramètres de chaîne de requête consiste à utiliser une variable ActionFilter comme suit:

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);
    }
}

Vous pouvez maintenant ajouter un attribut à votre action, comme suit: [QueryStringFilter("attributes")]. Les valeurs de la chaîne de requête seront alors transmises sous la forme FormCollection. De cette façon, votre action est plus facilement testée, car elle ne dépend plus du singleton Request.

8
ungood

Au lieu du commutateur, vous pouvez utiliser Dynamic Linq qui vous permet de dire:

Issues = Issues.OrderBy("Status");

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

1
gurra777

Veuillez vérifier le message ci-dessous qui décrit tous les processus http://www.c-sharpcorner.com/UploadFile/4b0136/editing-multiple-records-using-model-binding-in-mvc/

0
Valynk