title: Dynamically created views: Populate property metadata to nested view for client side validation?
body: <p>I have implemented a base view model for the configuration forms of different modules in my system.</p>
  
  <p>In that base logic I'm iterating the reflected properties of the (user-)derived viewmodel and dynamically create a list of ConfigItem objects </p>
  
  <p>Simplified my object looks as follows:</p>
  
  <pre><code>public class ConfigItem
  { 
       public string Key { get; set; }
       public object Value { get; set; }
       public  Type PropertyType { get; set; } 
       public ConfigType ConfigType { get; set; }
       public string PostId { get; set; } 
  };
  </code></pre>
  
  <p>The "value" property can be an object of a simple or complex type (string, bool image, etc.). </p>
  
  <p>In a nested view I'm rendering all ConfigItems in a loop (in order to decorate each with additional information like tooltips etc.).
  For the binding of the posted form I'm setting the name attribute of the input fields so the values are bound back to the original's viewmodel properties. The validation of DataAnnotation attributes works on server-side. </p>
  
  <p><strong>Now to the problem:</strong></p>
  
  <p>As we all know ASP comes with the neat feature of rendering jquery unobtrusive validation attributes. Unfortunately I'm losing all my metadata when rendering ConfigItems instead of the original properties, thus ASP doesn't know about my attributes like e.g. "Required" or "StringLength". Does anyone have an idea how to somehow "carry-along" the property metadata?</p>
  
  <p>The best thing would be that my ConfigItem's value could be an expression tree like of type Expression>, so I could carry along a "pointer" to the original property. But I couldn't figure out how to technically solve it. If someone could shed a little light on this (or perhaps have some other hints) I highly appreciate that. Thanks! </p>
  
  <p>Update:
  I'm rendering my ConfigItems with a little custom Html-Helper, where I evaluate the model state:</p>
  
  <pre><code>public static MvcHtmlString ConfigItem&lt;TModel&gt;(this HtmlHelper&lt;TModel&gt; htmlHelper, ConfigItem configItem, bool isEditMode = false)
      {
          if (isEditMode)
          {
              if (!htmlHelper.ViewData.ModelState.IsValidField(configItem.PostId))
              {
                  var itemState = htmlHelper.ViewData.ModelState[configItem.PostId];
  
                  if (itemState.Errors.Count &gt; 0)
                  {
                      configItem.ValidationMessage = string.Join("&lt;/br&gt;", Array.ConvertAll(itemState.Errors.ToArray(), i =&gt; i.ErrorMessage));
                  }
              }
              return htmlHelper.Partial(EditorConfigItemPartialPath, configItem);
          }
          else
          {
              return htmlHelper.Partial(DisplayConfigItemPartialPath, configItem);
          }
      }
  </code></pre>
  
  <p>The ConfigItem EditorTemplate does something like this:</p>
  
  <pre><code>@model ConfigItem    
  &lt;div class="value"&gt;
  @switch (Model.DataType)
  {
      case ConfigDataType.String:
          {
              var value = Model.Value == null ? "" : Model.Value;
              @Html.EditorFor(m =&gt; value, "string", Model.PostId)
              break;
          }
      case ConfigDataType.Bool:
          {
              @Html.EditorFor(m =&gt; Model.Value, "", Model.PostId)
              break;
          }
      case ConfigDataType.Image:
          {
              @Html.ConfigImage(Model.Key, m =&gt; Model.Value, Url.Action(ApplicationController.ActionUploadImage), Model.PostId)
              break;
          }
  }
  @if (!string.IsNullOrEmpty(Model.ValidationMessage))
  {
      &lt;span class="@errorClass"&gt;
          @Html.Raw(Model.ValidationMessage)
      &lt;/span&gt;
  }
  &lt;/div&gt;
  </code></pre>