as far as I understand a ModelBinder can generate class instances out of routedata/formdata.
What I'm looking for is a way to manipulate the data handed over to the view before it is consumed by the view.
What are the possiblities? Do I miss something obvious?
Thanks in advance!
EDIT
I don't want to send clear IDs to the client but encrypt them (at least in edit cases). As it happens very often I want this step as much as possible automated.
I look for something like a ModelBinder or a Attribute to attach to a method/viewmodel/...
Example:
GET
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
}
View
@model EditArticleViewModel
<div>
@Html.HiddenFor(x => x.Id) <!-- x.Id should be encrypted, not just "5" -->
...
</div>
Lg
warappa
You could do something with an action filter:
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);
}
}
}
and apply it to any relevent actions:
[EncryptID]
public ActionResult Edit(int id)
{
var vm = new EditArticleViewModel();
ToViewModel(repository.Get<Article>(id), vm);
return View(vm);
}
When the page is then posted you can use a model binder to decrypt the id.
If you then wanted to apply this across multiple view models you could look at creating a custom data annotation which flags a property to be encrypted. In your action filter you can then look for any properties with this data annotation and encrypt them accordingly.
You could write a custom HiddenFor
helper method that will automatically encrypt the value:
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);
}
}
As an alternative you could use the Html.Serialize helper in the MVCFutures assembly that does this under the covers.
So basically you will write in your view:
@Html.Serialize("id", Model.Id, SerializationMode.Encrypted)
and in your controller:
public ActionResult Edit([Deserialize(SerializationMode.Encrypted)]int id)
{
...
}