0

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 reference ViewBag. 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.
BLAZORLOVER
  • 1,971
  • 2
  • 17
  • 27

1 Answers1

0

I think it's because you are copying a CSHTML to the output directory; if you turn off Copy to Output Directory, the path to your partial view can become:

~/Views/Shared/_PartialView.cshtml

Or whatever the actual path happens to be.

For Html.Partial("View"), the view needs to be in either in the Shared folder, or the executing controller's folder for the view engine to find it. You can simply define the name of the view without the file extension.

EDIT You can also link the item into the web project at a specified directory using the Add as Link option: https://blogs.msdn.microsoft.com/zainnab/2010/11/12/linked-items-in-projects/

Brian Mains
  • 50,520
  • 35
  • 148
  • 257
  • I've updated my question with clarity around why my view needs to be in the /bin folder. – BLAZORLOVER Jan 29 '19 at 18:20
  • @user666 I think you need to extend the view engine process that controls where to look for views: https://stackoverflow.com/questions/632964/can-i-specify-a-custom-location-to-search-for-views-in-asp-net-mvc If you did that, then the Html.Partial approach could work – Brian Mains Jan 29 '19 at 18:33
  • I have done this already to no avail. Unless I specify the full path, updating the view engine to include the bin directory continues to display an error related to the engine not being able to locate the view. – BLAZORLOVER Jan 29 '19 at 18:38
  • Updated my question to include this attempt. – BLAZORLOVER Jan 29 '19 at 18:40
  • OK. The other feature is - if you need to copy this view, you can add a linked item, which should work for a CSHTML file. See this example of how this can work: https://blogs.msdn.microsoft.com/zainnab/2010/11/12/linked-items-in-projects/ – Brian Mains Jan 29 '19 at 18:46
  • Negative: https://stackoverflow.com/questions/54425335/linked-partial-view-not-found-by-mvc – BLAZORLOVER Jan 29 '19 at 18:48