В своей замечательной книге MVC Стивен Сандерсон приводит пример пользовательского связывателя модели, который устанавливает и извлекает переменную сеанса, скрывая элемент хранения данных от контроллера.
Я пытаюсь расширить это, чтобы удовлетворить довольно распространенный сценарий: я сохраняю объект User в сеансе и делаю его доступным для каждого метода действия в качестве параметра. Класс Сандерсона работал нормально, когда данные пользователя не менялись, но теперь мне нужно позволить пользователю редактировать свои данные и сохранить измененный объект обратно в сеанс.
Моя проблема в том, что я не могу понять, как отличить GET от POST, кроме проверки количества ключей в bindingContext.ValueProvider.Kys, и это кажется настолько неправильным. .
Кто-нибудь может указать мне правильное направление? По сути, всем действиям нужен доступ к текущему пользователю, а действию UpdateMyDetails необходимо обновить этот же объект, все при поддержке Session. Вот мой код ...
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));
}
}