Dans son magnifique livre MVC, Steven Sanderson donne un exemple de classeur de modèle personnalisé qui définit et récupère une variable de session, cachant l'élément de stockage de données du contrôleur. J'essaie d'étendre ceci pour répondre à un scénario assez courant: je stocke un objet Utilisateur dans la session et le rend disponible à chaque méthode d'action en tant que paramètre. La classe de Sanderson fonctionnait bien quand les détails de l'utilisateur ne changeaient pas, mais maintenant je dois laisser l'utilisateur éditer leurs détails et sauvegarder l'objet modifié dans la session. Mon problème est que je ne peux pas comprendre comment distinguer un GET d'un POST autrement qu'en vérifiant le nombre de clés dans bindingContext.ValueProvider.Keys, et cela semble si mauvais que je suis sûr que je suis malentendu quelque chose.Extension de mvc ModelBinder personnalisé de Sanderson pour un objet stocké en session
Quelqu'un peut-il me diriger dans la bonne direction? Fondamentalement, toutes les actions doivent avoir accès à l'utilisateur actuel, et l'action UpdateMyDetails doit mettre à jour le même objet, toutes sauvegardées par la session. Voici mon code ...
public class CurrentUserModelBinder : IModelBinder
{
private const string userSessionKey = "_currentuser";
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
var user = controllerContext.HttpContext.Session[userSessionKey];
if (user == null)
throw new NullReferenceException("The CurrentUser was requested from the CurrentUserModelBinder but no IUser was present in the Session.");
var currentUser = (CCL.IUser)user;
if (bindingContext.ValueProvider.Keys.Count > 3)
{
var firstName = GetValue<string>(bindingContext, "FirstName");
if (string.IsNullOrEmpty(firstName))
bindingContext.ModelState.AddModelError("FirstName", "Please tell us your first name.");
else
currentUser.FirstName = firstName;
var lastName = GetValue<string>(bindingContext, "LastName");
if (string.IsNullOrEmpty(lastName))
bindingContext.ModelState.AddModelError("LastName", "Please tell us your last name.");
else
currentUser.LastName = lastName;
if (bindingContext.ModelState.IsValid)
controllerContext.HttpContext.Session[userSessionKey] = currentUser;
}
return currentUser;
}
private T GetValue<T>(ModelBindingContext bindingContext, string key)
{
ValueProviderResult valueResult;
bindingContext.ValueProvider.TryGetValue(key, out valueResult);
bindingContext.ModelState.SetModelValue(key, valueResult);
return (T)valueResult.ConvertTo(typeof(T));
}
}
Avez-vous trouvé la réponse d'autre où? Je dois faire la même chose. – longday
Je suis aussi allé dans la voie proposée par Steven Sanderson, mais maintenant je lis des opinions mitigées sur l'accès aux données dans les classeurs personnalisés. Je n'arrive pas à faire fonctionner mon injection de dépendance dans un classeur de modèle personnalisé. Apparemment, vous ne pouvez pas avoir IoC dans les classeurs de modèles personnalisés ... – autonomatt