title: ASP.Net MVC and RenderPartial w/ relative paths
body: <p>I've been playing around with ASP.NET MVC and had a question.  Or maybe its a concern that I am doing this wrong.  Just working on a lame site to stretch my wings a bit.  I am sorry this question is not at all concise.</p>
  
  <p>Ok, here's the scenario.  When the user visits home/index, the page should show a list of products and a list of articles.  The file layout is such (DAL is my data access layer):</p>
  
  <pre>
  Controllers
      Home
          Index       
  
  Views
      Home
          Index       inherits from ViewPage
      Product         
          List        inherits from ViewUserControl&lt;IEnumerable&lt;DAL.Product&gt;&gt;
          Single      inherits from ViewUserControl&lt;DAL.Product&gt;
      Article
          List        inherits from ViewUserControl&lt;IEnumerable&lt;DAL.Article&gt;&gt;
          Single      inherits from ViewUserControl&lt;DAL.Article&gt;
  </pre>
  
  <pre><code>Controllers.HomeController.Index produces a View whose ViewData contains two entries, a IEnumerable&lt;DAL.Product&gt; and a IEnumerable&lt;DAL.Article&gt;.
  
  View.Home.Index will use those view entries to call:
  Html.RenderPartial("~/Views/Product/List.ascx", ViewData["ProductList"])
  and Html.RenderPartial("~/Views/Article/List.ascx", ViewData["ArticleList"])
  
  View.Product.List will call
  foreach(Product product in View.Model)
      Html.RenderPartial("Single", product);
  
  View.Article.List does something similar to View.Product.List
  </code></pre>
  
  <p>This approach fails however.  The approach makes sense to me, but maybe someone with more experience with these MVC platforms will recognize a better way.</p>
  
  <p>The above produces an error inside View.Product.List.  The call to <code>Html.RenderPartial("Single",...)</code> complains that "Single" view was not found.  The error indicates:</p>
  
  <pre>
  The partial view 'Single' could not be found. The following locations were searched:
  ~/Views/Home/Single.aspx
  ~/Views/Home/Single.ascx
  ~/Views/Shared/Single.aspx
  ~/Views/Shared/Single.ascx
  </pre>
  
  <p>Because I was calling RenderAction() from a view in Product, I expected the runtime to look for the "Single" view within Views\Product.  It seems however the lookup is relative the controller which invoked the original view (/Controller/Home invoked /Views/Product) rather than the current view.</p>
  
  <p>So I am able to fix this by changing Views\Product, such that:</p>
  
  <pre><code>View.Product.List will call
  foreach(Product product in View.Model)
      Html.RenderPartial(<b>"~/Views/Product/Single.ascx"</b>, product);</code></pre>
  
  <p>instead of</p>
  
  <pre><code>View.Product.List will call
  foreach(Product product in View.Model)
      Html.RenderPartial(<b>"Single"</b>, product);
  </code></pre>
  
  <p>This fix works but.. I do not understand why I needed to specify the full path of the view.  It would make sense to me for the relative name to be interpreted relative to the current view's path rather than the original controller's view path.  I cannot think of any useful case where interpreting the name relative to the controller's view instead of the current view is useful (except in the typical case where they are the same).</p>
  
  <p>Around this time I should have a question mark? To emphasis this actually is a question.</p>