title: How can I create a re-usable custom HTML panel in ASP.NET MVC?
body: <p>I am trying to create a re-usable UI element in ASP.NET MVC that wraps around whatever content I choose to place in it. My first thought was to create a partial view, but that doesn't seem to help me in what I am trying to accomplish.</p>
  
  <h2>The Template</h2>
  
  <p>For example I would like to create some re-usable markup similar to this (please excuse the pseudo-code):</p>
  
  <pre><code>&lt;div class="panel panel-default"&gt;
    &lt;div class="panel-body"&gt;
      @RenderBody()
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <h2>A Simple Example</h2>
  
  <p>Then in my views I would like to do something similar to this:</p>
  
  <pre><code>@Render.Partial("MyPanel")
  {
      &lt;img src="image.jpg" /&gt;
  }
  </code></pre>
  
  <p>Assuming that code worked as expected it would generate the following:</p>
  
  <pre><code>&lt;div class="panel panel-default"&gt;
    &lt;div class="panel-body"&gt;
       &lt;img src="image.jpg" /&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <h2>Another Example, with more complex markup</h2>
  
  <p>Theoretically I would like to be able place any and everything I would like within one of the panels. So even more complex markup would still appear legible.</p>
  
  <pre><code>@Render.Partial("MyPanel")
  {
      &lt;form&gt;
        &lt;div class="form-group"&gt;
          &lt;label for="exampleInputEmail1"&gt;Email address&lt;/label&gt;
          &lt;input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
          &lt;label for="exampleInputPassword1"&gt;Password&lt;/label&gt;
          &lt;input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password"&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
          &lt;label for="exampleInputFile"&gt;File input&lt;/label&gt;
          &lt;input type="file" id="exampleInputFile"&gt;
          &lt;p class="help-block"&gt;Example block-level help text here.&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class="checkbox"&gt;
          &lt;label&gt;
            &lt;input type="checkbox"&gt; Check me out
          &lt;/label&gt;
        &lt;/div&gt;
        &lt;button type="submit" class="btn btn-default"&gt;Submit&lt;/button&gt;
      &lt;/form&gt;
  }
  </code></pre>
  
  <p>Just like in the first example, it would wrap everything inside the header and footer of my template:</p>
  
  <pre><code>&lt;div class="panel panel-default"&gt;
    &lt;div class="panel-body"&gt;
      &lt;form&gt;
        &lt;div class="form-group"&gt;
          &lt;label for="exampleInputEmail1"&gt;Email address&lt;/label&gt;
          &lt;input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"&gt;
        &lt;/div&gt;
        .. truncated ..
        &lt;button type="submit" class="btn btn-default"&gt;Submit&lt;/button&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <h2>Known Possibilities</h2>
  
  <ul>
  <li><strong>Partial View.</strong> A partial view seems to make sense, except I have been unable to figure out a way to create a partial that has flexibility beyond the Model it was designed for. I gave two examples, because the contents within my panel could be significantly different each time I use it. I would like to be able throw anything into the body of this partial view; text, markup, more razor code, etc.</li>
  <li><strong>HTML Helper.</strong> This works great when I have specific parameters I would be passing in. I don't see this as practical when needing to enter large amounts of markup, as it would become hard to read/maintain. Also since html would be passed in as a string, I'm not sure how this would work with razor tags?</li>
  <li><strong>2 Partial Views.</strong> Using one as the header and the other as the footer. This works, but it just feels sloppy to me.</li>
  </ul>
  
  <p>I was able to do this in ASP.NET WebForms by creating a custom control. It seems like this is something that should be straight forward in MVC too, but I just haven't quite been able to figure out a good solution yet.</p>