I have the following:
Html.RenderPartial("~/bin/Views/SharedViews/_PartialView.cshtml", model.SharedViewModel);
This partial view is coming from another project that I have set as a reference; that partial view is set to Copy to Output Directory because MVC doesn't allow you to reference partial views outside of your web project. I am leveraging a reusable MVC component so I am copying this view from one project to the bin directory of the primary project:
Project.Common
> Helpers
>> _PartialView.cshtml (Copy to Output Directory = true)
Project.FirstProject
> References
>> Project.Common
> bin
>> (copied) _PartialView.cshtml
I see the file in the bin folder; the MVC rendering engine is locating it as well, too. I've validated this by changing the path and observing an error related to the view not being found. So - MVC finds the view, but throws this error:
_PartialView.cshtml(1): error CS0103: The name 'model' does not exist in the current context'
Contents of _PartialView.cshtml
:
@model Common.ViewModel
@if (Model.Check)
{
<p>success!</p>
}
If I modify the contents to be just HTML:
<p>test</p>
I get the same error. If I then modify the invocation to use Html.Partial
instead of RenderPartial
, I get the same error.
What's going on here?
If I then remove the viewmodel from the invocation, I get:
The view at '~/bin/Views/_PartialView.cshtml' must derive from WebViewPage, or WebViewPage.'
With both RenderPartial
and Partial
.
Adding @inherits System.Web.Mvc.WebViewPage
to the top of the partial view gets the html rendering, but doesn't fix the cshtml The name model does not exist
error.
Updating the View Engine to include the bin folder and referencing the view without the full path specified isn't working - the view engine cannot locate the view even after implementing the following:
public class CommonAccessibleViewEngine : RazorViewEngine
{
public CommonAccessibleViewEngine()
{
// added to leverage reusable pagination component (and other reusable view components)
// MVC by default doesn't allow you to reference Views outside of your immediate project. By setting views to copy to output directory and then modifying the engine as follows,
// we're telling the view engine to expand its scope to include these referenced views in addition to its default scope.
var newFormats = new string[2] { "~/bin/Views/YourFolder/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
this.PartialViewLocationFormats = newFormats;
this.ViewLocationFormats = newFormats;
}
}
With this in Application_Start:
ViewEngines.Engines.Add(new CommonAccessibleViewEngine());
Linking the view also does not work:
Linked Partial View Not Found By MVC
Workaround:
- Ensure the Partial view includes
@inherits System.Web.Mvc.WebViewPage
- this allows you to referenceViewBag
.Model
is still not accessible. - Use a custom view engine (as above) to specify the location of the file (
bin
for me) - Assign whatever Model your Partial view expects as a ViewBag property:
ViewBag.PartialViewModel = partialViewModel;
- Cast ViewBag in the Partial View:
@{ var Model = (Common.ViewModel)ViewBag.PartialViewModel; }
- Go balder from the fact that Microsoft makes a core tenant of quality programming - reusability - such a nightmare to figure out within MVC.