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:
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é!
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);
}
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"];
...
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
.
Au lieu du commutateur, vous pouvez utiliser Dynamic Linq qui vous permet de dire:
Issues = Issues.OrderBy("Status");
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/