Asp MVC 3: измененные значения отправлены на просмотр
Насколько я понимаю, ModelBinder может генерировать экземпляры классов из routedata / formdata.
То, что я ищу, - это способ манипулировать данными, передаваемыми представлению, до того, как они будут использованы представлением.
Каковы возможности? Я что-то упускаю очевидное?
Заранее спасибо!
РЕДАКТИРОВАТЬ
Я не хочу отправлять ясные идентификаторы клиенту, но шифрую их (по крайней мере, в случаях редактирования). Как это часто бывает, я хочу максимально автоматизировать этот шаг.
Я ищу что-то вроде ModelBinder или Атрибут для присоединения к методу /viewmodel/...
Пример:
ПОЛУЧИТЬ
public ActionResult Edit(int id)
{
var vm = new EditArticleViewModel();
ToViewModel(repository.Get<Article>(id), vm);
return View(vm); // id is something like 5 and should be encryped before being used by the view
}
Посмотреть
@model EditArticleViewModel
<div>
@Html.HiddenFor(x => x.Id) <!-- x.Id should be encrypted, not just "5" -->
...
</div>
LG Warappa
2 ответа
Вы можете сделать что-то с фильтром действий:
public class EncryptIDAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var vm = filterContext.Controller.ViewData.Model as EditArticleViewModel;
if(vm != null)
{
vm.ID = SomeMethodToEncrypt(vm.ID);
}
}
}
и применить его к любым соответствующим действиям:
[EncryptID]
public ActionResult Edit(int id)
{
var vm = new EditArticleViewModel();
ToViewModel(repository.Get<Article>(id), vm);
return View(vm);
}
После публикации страницы вы можете использовать связыватель модели для расшифровки идентификатора.
Если вы затем захотите применить это к нескольким моделям представлений, вы можете посмотреть на создание пользовательской аннотации данных, которая помечает свойство для шифрования. В вашем фильтре действий вы можете найти любые свойства с этой аннотацией данных и соответствующим образом зашифровать их.
Вы можете написать кастом HiddenFor
вспомогательный метод, который автоматически зашифрует значение:
public static class HiddenExtensions
{
public static MvcHtmlString HiddenForEncrypted<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex)
{
var metadata = ModelMetadata.FromLambdaExpression(ex, htmlHelper.ViewData);
var name = ExpressionHelper.GetExpressionText(ex);
var value = metadata.Model;
var encryptedValue = SomeFunctionToEncrypt(value);
return htmlHelper.Hidden(name, encryptedValue);
}
}
В качестве альтернативы вы можете использовать помощник Html.Serialize в сборке MVCFutures, которая делает это под крышками.
Так что в основном вы будете писать по вашему мнению:
@Html.Serialize("id", Model.Id, SerializationMode.Encrypted)
и в вашем контроллере:
public ActionResult Edit([Deserialize(SerializationMode.Encrypted)]int id)
{
...
}