Html.RenderPartial Throws System.InvalidException while trying to render a partial view - asp.net-mvc

I am trying to render a partial view using RenderPartial, it keep throwing System.InvalidOperationException. Below is the folder structure that shows the Views folder.
I am accessing Simulation from Index and have tried below combination the error is same for all.
#{Html.RenderPartial("/Shared/Simulation");}
#{Html.RenderPartial("/Views/Shared/Simulation");}
#{Html.RenderPartial("~/Views/Shared/Simulation");}
I know it is some thing silly i am missing here

When using the full path, you need to include the file extension as well.
This should work.
#{ Html.RenderPartial("~/Views/Shared/Simulation.cshtml"); }
Or you can simply not use the full path, but just pass the view name
#{ Html.RenderPartial("Simulation"); }
Razor view engine will look in the ~/Views/Shared directory and render the view as the location follows the convention.

Related

Finding Razor partial views in the area EditorTemplates folder

I am starting to use EditorFor helper method to render my razor partial views, but I couldn't get the partials in the Areas folder to work.
Here is the path to the partial:
~\Areas\Products\Views\Shared\EditorTemplates\_Edit.cshtml
The partial is really simple with only one "div" tag to do the testing.
Try to use in my page view (~\Areas\Products\Views\EditPage.cshtml) as
#Html.EditorFor(m => m.ProductEditModel, "_Edit")
Visual studio tells me that "Cannot resolve template '_Edit'".
Now, if I move the partial to the root view folder:
~\Views\Shared\EditorTemplates\_Edit.cshtml
It works, Visual studio has no problems to resolve the template, and the div is renderred correctly in my browser.
I also tried to customize the RazorViewEngine, did not work either
namespace MySite.Web
{
public class RazorViewEngine : System.Web.Mvc.RazorViewEngine
{
public RazorViewEngine()
: this(null)
{
}
public RazorViewEngine(IViewPageActivator viewPageActivator)
: base(viewPageActivator)
{
AreaPartialViewLocationFormats = new[]
{
"~/Areas/{2}/Views/Shared/EditorTemplates/{0}.cshtml"
}.Union(AreaPartialViewLocationFormats).ToArray();
}
}
}
Just wondering what did I do wrong? BTW, I am using MVC3 at the moment, can't upgrate to MVC4 due to some old components.
When calling a partial view or view from a different area in MVC, specify the full path of the partial view or view. Since MVC is based on convention, by convention it will look in the same area the calling code in the view (or controller) resides for any partial views or views referenced, unless a specific path is used. Try using the full path to reference the partial view when it is located in the products area:
#Html.EditorFor(m => m.ProductEditModel, "~/Areas/Products/Views/Shared/EditorTemplates/_Edit.cshtml")
Since the view referenced is a shared view it doesn't matter if you specify the full path if you are in the same area. However, if you are trying to access a view within a different directory than the view trying to reference it and this directory is not named shared you will need to specify the full path regardless of area. It is similar when the controller calls the view; if a controller from the same area as the referenced view specifies the short name for the view and this view is from a parent directory named different than its own (ignoring the "controller" suffix) the view engine will not find your view. Unless of course the parent directory for the view is in the shared folder.
Whether it's in the controller or a view you can't use the "short name" across areas because the view engine has a convention for where to look when the path isn't used. Areas are meant to do this to keep your code separated, or decoupled if you will, at a high level by default. So any decision to "cross the barrier" should be thought about mindfully, but certainly not discouraged. It's all about convention.
I am answering my own question now.. My page view path was not correct. Since my area is Products, controller is ProductController, my page view should be placed in ~\Areas\Products\Views\Product\EditPage.cshtml, that way, it matches what the view engine expects, and the partial will be corrected resolved.

What is difference between #Html.RenderPartial("_Common.cshtml") and #Html.RenderPartial("_Common")

I am facing one problem in MVC4. If I am not providing .cshtml while calling RenderPartial then it is not calling Partial View.
For Example
#Html.RenderPartial("_Common.cshtml") //it is working
#Html.RenderPartial("_Common") //it is not working
My question is why it is not working?
As Zabavsky mentions, you may have an incorrect filename on your partial view (double extension). Just did that yesterday on a project, so easy to do, but I think you should be using Partial and not RenderPartial
Just to clarify which options should work:
1) The extension of the view file is required if you supply a path.
2) If you do not supply a path, do not supply the extension.
The examples below assume cshtml files.
Use RenderPartial in a code block:
// This looks in default view folder, then shared, checking for .aspx, .cshtml etc
Html.RenderPartial("DefinitionDetails");
// This looks in specified path and requires the extension
Html.RenderPartial("~/Views/Definition/DefinitionDetails.cshtml");
Use Partial for inline Razor syntax:
// This looks in default view folder, then shared, checking for .aspx, .cshtml etc
#Html.Partial("DefinitionDetails")
// This looks in specified path and requires the extension
#Html.Partial("~/Views/Definition/DefinitionDetails.cshtml")
Note: Apparently RenderPartial is slightly faster than Partial, but I also expect fully pathed names will be a faster than letting MVC search for the file.
If you are producing partials in a loop (i.e. from a collection in your view model), it is likely you will need to pass through specific viewmodels:
e.g.
#foreach (var group in orderedGroups)
{
Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", group);
}

Problems returning PartialViews from controller

I am using MVC 4 and I have some areas in my project and some Views and Partial Views within each area:
Areas
AdminArea => one area and so on
Views
Customer
Customer.cshtml => my View
_CustomerDetails.cshtml => my partial View
In my controller, CustomerController I have the following code that fails:
return PartialView("_CustomerDetails", model) => fails to find my partial view.
However, if I call
return PartialView("~/Areas/AdminArea/Views/Customer/_CustomerDetails.cshtml", model)
the code executes successfully.
My Views (not partial views) all work ok. I even have some some partial views (also in the same area) that render ok without specifying the full path, but for some reason, for the most of them the above code fails in constructor saying that:
The partial view '_CustomerDetails' was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Customer/_CustomerDetails.cshtml a.s.o. ... => and is searching in global not in Admin area.
Is there any way to fix this problem without having to specify the full path to my PartialViews in code? (like passing area="Admin" like I do in the .cshtml file).
I am not using any custom ViewEngine and I have called AreaRegistration.RegisterAllAreas() in Global.asax.cs.
Thanks,
Tamash
I am really sorry for even posting this question:
The call from the controller worked fine, but the problem was that I was calling from javascript to get the PartialView through an action and I didn't specify the full name for that action. That's why the partial view wasn't returned since the method responsible for returning it wasn't being called at all.
Sorry about that: the code is a bit complex and I got lost in details around Ajax calls.
seems weird, try adding a view from controller action method i.e right click action method in controller, add view, make a view a partial view and see where it adds it.. check if it is the same location as you are putting, if not there is some structure prob/bug.

partial view rendering

I have a partial view in my Foo folder. I want to show it on my Home/index view. I am using partial render and it is trying to locate it in temp folder. How to write Renderpartial to render foo\partial view ?
regards,
Asif hameed
To get it to render just specify the path in RenderPartial like this:
<%Html.RenderPartial("~/Areas/FooArea/Views/Foo.ascx");%>
Obviously replace my example path with the path to your actual Foo partial view.
If you want to call an action that returns a partial view on another controller (foo) try using Html.RenderAction. It will allow you to pass in an action and a controller.
This post has a decent description of the differences between RenderPartial/RenderAction and when to use each one: http://www.arrangeactassert.com/when-to-use-html-renderpartial-and-html-renderaction-in-asp-net-mvc-razor-views/

Accessing views with absolute paths on ASP.NET MVC

I'm trying to access a view in this way:
return View(#"~\Items\Details.aspx");
and I get this error:
The view '~\Items\Details.aspx' or its master could not be found. The following locations were searched:
~\Items\Details.aspx
On the ItemsController, in the Details action, returning View() works just fine. Why can't I access that view from another controller?
Prefix it with '/Views' should help.
return View("~/Views/Items/Details.aspx");
You can make the Items view a shared one (you put it in the Views/Shared folder), then you can just call View("Items") and it will work.

Resources