Skip to content

Instantly share code, notes, and snippets.

@jmcd
Created March 20, 2012 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmcd/2137475 to your computer and use it in GitHub Desktop.
Save jmcd/2137475 to your computer and use it in GitHub Desktop.
Extension to render partials of nested models with correct element name prefix
using System;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class PartialExtension
{
public static MvcHtmlString PartialFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
return html.PartialFor(typeof (TValue).Name, expression);
}
public static MvcHtmlString PartialFor<TModel, TValue>(this HtmlHelper<TModel> html, string partialViewName, Expression<Func<TModel, TValue>> expression)
{
var containingModel = html.ViewData.Model;
var model = expression.Compile()(containingModel);
var oldTemplateInfo = html.ViewData.TemplateInfo;
var newViewData = new ViewDataDictionary(html.ViewData)
{
TemplateInfo = new TemplateInfo
{
FormattedModelValue = oldTemplateInfo.FormattedModelValue,
}
};
var newPrefix = ExpressionHelper.GetExpressionText(expression);
if (oldTemplateInfo.HtmlFieldPrefix.Length > 0)
{
newPrefix = oldTemplateInfo.HtmlFieldPrefix + "." + newPrefix;
}
newViewData.TemplateInfo.HtmlFieldPrefix = newPrefix;
return html.Partial(partialViewName, model, newViewData);
}
}
@model gts.Web.Models.AddressFields
<ul>
<li>
@Html.HumanLabelFor(x => x.Line1)
@Html.TextBoxFor(x => x.Line1)
@Html.ValidationMessageFor(x => x.Line1)
</li>
<li>
@Html.HumanLabelFor(x => x.Line2)
@Html.TextBoxFor(x => x.Line2)
@Html.ValidationMessageFor(x => x.Line2)
</li>
<li>
@Html.HumanLabelFor(x => x.Line3)
@Html.TextBoxFor(x => x.Line3)
@Html.ValidationMessageFor(x => x.Line3)
</li>
<li>
@Html.HumanLabelFor(x => x.Town)
@Html.TextBoxFor(x => x.Town)
@Html.ValidationMessageFor(x => x.Town)
</li>
<li>
@Html.HumanLabelFor(x => x.Postcode)
@Html.TextBoxFor(x => x.Postcode)
@Html.ValidationMessageFor(x => x.Postcode)
</li>
</ul>
@model gts.Web.Models.ContactPointFields
@Html.PartialFor(x=>x.Address)
<ul>
<li>
@Html.HumanLabelFor(x => x.EmailAddress)
@Html.TextBoxFor(x => x.EmailAddress)
@Html.ValidationMessageFor(x => x.EmailAddress)
</li>
<li>
@Html.HumanLabelFor(x => x.TelephoneNumber)
@Html.TextBoxFor(x => x.TelephoneNumber)
@Html.ValidationMessageFor(x => x.TelephoneNumber)
</li>
</ul>
public class OrganisationFields
{
public string Name { get; set; }
public ContactPointFields ContactPoint { get; set; }
}
public class AddressFields
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public string Town { get; set; }
public string Postcode { get; set; }
}
public class ContactPointFields
{
public AddressFields Address { get; set; }
public string EmailAddress { get; set; }
public string TelephoneNumber { get; set; }
}
@model gts.Web.Models.OrganisationFields
<ul>
<li>
@Html.HumanLabelFor(x => x.Name)
@Html.TextBoxFor(x => x.Name)
@Html.ValidationMessageFor(x => x.Name)
</li>
</ul>
@Html.PartialFor(x => x.ContactPoint)
...
<input id="ContactPoint_Address_Postcode" type="text" value="" name="ContactPoint.Address.Postcode">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment