I found it to be pretty nice to do it like this (usage in the view):
@Html.HiddenJsonFor(m => m.TrackingTypes)
Here is the according helper method Extension class:
public static class DataHelpers
{
public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
return HiddenJsonFor(htmlHelper, expression, (IDictionary<string, object>) null);
}
public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
{
return HiddenJsonFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
{
var name = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var tagBuilder = new TagBuilder("input");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("name", name);
tagBuilder.MergeAttribute("type", "hidden");
var json = JsonConvert.SerializeObject(metadata.Model);
tagBuilder.MergeAttribute("value", json);
return MvcHtmlString.Create(tagBuilder.ToString());
}
}
It is not super-sofisticated, but it solves the problem of where to put it (in Controller or in view?) The answer is obviously: neither ;)