Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Bind PartialView / RenderPartialView to Model Child Objects Automatically

0.00/5 (No votes)
23 Aug 2017 1  
Automatically bind MVC HTML RenderPartial and Partial view pages to your model's child objects without having to use HTMLFieldPrefix.

Introduction

Tired of fighting with PartialViews that won't bind to your model? This simple set of functions handles automatically fixing the HTML prefix and allows PartialPages to bind without any further effort.

Using the Code

Simply add the following class into your solution and then instead of using Html.Partial or Html.RenderPartial, call it like the functions below:

Usage:

@Html.RenderPartialFixChildPrefix("_PartialView", model.ChildObject)

or:

@Html.PartialFixChildPrefix("_PartialView", model.ChildObject)

Extension Class:

 public static class PartialExtensions
    {
        public static void RenderPartialFixChildPrefix
        (this HtmlHelper htmlHelper, string partialViewName, 
         object model, ViewDataDictionary viewData = null)
        {
            if (model == null)
            {
                throw new Exception("Null models cannot be processed correctly. 
                                          Initialize empty object for create calls.");
            }

            using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
            {
                string oldPrefix = FixPartialPrefixIfNeeded(htmlHelper, model, ref viewData);
                htmlHelper.RenderPartial(partialViewName, model, viewData);
                viewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
            }
        }

        private static string FixPartialPrefixIfNeeded
        (HtmlHelper htmlHelper, object model, ref ViewDataDictionary viewData)
        {
            var oldPrefix = viewData == null ? "" : viewData.TemplateInfo.HtmlFieldPrefix;

            // Only change prefix if we're using a difference Model for the partial view
            if (model != htmlHelper.ViewData.Model)
            {
                var modelPropertyName = GetPropertyNameFromParentObj(htmlHelper.ViewData.Model, model);

                if (viewData == null)
                {
                    viewData = new ViewDataDictionary()
                    {
                        TemplateInfo = new TemplateInfo()
                    };
                }

                viewData.TemplateInfo.HtmlFieldPrefix = modelPropertyName;
            }
            return oldPrefix;
        }

        public static MvcHtmlString PartialFixChildPrefix
        (this HtmlHelper htmlHelper, string partialViewName, 
         object model, ViewDataDictionary viewData = null)
        {
            if (model == null)
            {
                throw new Exception("Null models cannot be processed correctly. 
                Initialize empty object for create calls.");
            }

            using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
            {
                string oldPrefix = FixPartialPrefixIfNeeded(htmlHelper, model, ref viewData);
                var result = htmlHelper.Partial(partialViewName, model, viewData);
                viewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
                return result;
            }
        }

        private static string GetPropertyNameFromParentObj(object parentObj, object objToFind)
        {
            var props = parentObj.GetType().GetProperties();

            foreach (var p in props)
            {
                string name = p.Name;
                var value = parentObj.GetType().GetProperty(p.Name).GetValue(parentObj, null);

                if (objToFind == value)
                {
                    return p.Name;
                }
            }

            return "";
        }
}

History

  • 8/22/2017 -- Initial posting - Allen Biehle c/o Vertical AIT (Vertical Automation and Information Technology, LLC)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here