MVC3 View Routing and partial view not found - asp.net-mvc

I know what my problem is but not sure how to fix it so I was hoping the geniuses here could help. I have a controller that I want to grab a piece of info from the url then redirect to the site. My controller does it's thing and returns the view but the view has a partial in it and the view engine can't find it?
So here is the setup.
The controller is mapped route as:
//marketing/tracking
routes.MapRoute("CampaignTracking",
"{save}/{campaignid}",
new { controller = "CampaignTracking", action = "Index" });
This works great. So next my controller:
public ActionResult Index(Int32 campaignID)
{
var model = new ...snip...
return View("../Customer/Login", model);
}
Now I originally got the error couldn't find view as it was looking in a CampaignTracking folder and I had :
return View("Customer/Login", model);
So I changed it as seen above with the ../ to get to the correct location. Now it finds the Login.cshtml but in login.cshtml it renders a partial and again it is looking to find the partial in the Campaigntracking.
I could abolish the CampaignTracking controller and move the action result into the CustomerController but would prefer to keep it in its own controller as this will likely grow and doesn't really group under customer.
As per nicu Janga
I changed in my controller:
return View(#"~/Views/Customer/Login.cshtml", model);
and in my login.cshtml the partials:
#Html.Partial(#"~/Views/Customer/...etc.cshtml")
but I am wondering why. I can understand how the view engine gets confused coming out of the controller but once corrected with return View(#"~/Views/Customer/Login.cshtml", model); shouldn't the proper path propagate as well to the login.cshtml???
Obviously not but what don't I understand??

You can try this one:
return View(#"~/Views/Customer/Login.cshtml",model);
it works?

Let me see if I can fill in some details for you. First up, let's say we've just added the following controller to an empty project:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
Now, let's also assume that we didn't bother to add the Index.cshtml view, so when we run this, it will tell us the view is missing. Take a look at the message that accompanies that exception:
The view 'Index' or its master was not found or no view engine supports
the searched locations. The following locations were searched:
~/Views/home/Index.aspx
~/Views/home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/home/Index.cshtml
~/Views/home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
These are the exact locations that are searched when MVC is trying to locate a view. For the most part, if you're using C# with MVC, the only two you need to care about are:
~/Views/home/Index.cshtml
~/Views/Shared/Index.cshtml
That means if you don't provide a path when specifying the name of your view, it will always check both of these locations. So if we did this from our HomeController:
return View("Test");
MVC will look for this view at ~/Views/Home/Test.cshtml and then ~/Views/Shared/Test.cshtml. The great thing about this is it's consistent. It always looks for the views in the same way.
Now, let's use a more complicated example (again, assuming we're in our HomeController):
return View("../SomeDirectory/Test.cshtml");
This is going to be looked for in the following ways:
~/Views/Home/../SomeDirectory/Index.cshtml
~/Views/Shared/../SomeDirectory/Index.cshtml
Taking a look at ~/Views/Home/../SomeDirectory/Index.cshtml first , this would actually mean it's searching for the view here: ~/Views/SomeDirectory/Index.cshtml. Obviously, this isn't where your view is, and the same applies to where ~/Views/Shared/../SomeDirectory/Index.cshtml ends up.
The important thing to remember here is ~ means the relative root of your site. It will always work from the root of your site, which means you can always be sure exactly what's going on. By doing this
return View("~/Views/Home/Index.cshtml");
you are telling MVC exactly where to find your view, rather than letting MVC's rules of convention decide for you. That means whenever you specify a location for MVC to find your view, it will only search that location. So return View("~/Views/Home/Index.cshtml") will only search for the view at ~/Views/Home/Index.cshtml. If it cannot find the view there, you'll get the same exception as before, but it will give you a slightly different message:
The view '~/Views/Home/Index.cshtml' or its master was not found or no view
engine supports the searched locations. The following locations were searched:
~/Views/Home/Index.cshtml
Notice how it hasn't searched for the view in the other locations.

Related

Adding a View without a model MVC 5

I need to create a simple view with 3 links on it ( Administration type page ), I tried adding a View called index to a Directory called Administration but when I try to navigate to it it throws a resource not found error. I am brand new to MVC coming from Web Forms so sorry if this is a stupid question ;)
Firts Add a controller which will come with Index method. Right click on Index Method and select Add View.
Add all Html you want to add in that view and your page is ready without adding a Model.
You need to have a controller to render the view.
For instance, if you had an AdminController with a method similar to something like public ActionResult Index() { return View(); } this would render the index view where you could place your html/links etc.
The view itself doesn't need a model this way as you are not supplying anything when returning the View().
You could then navigate to the page by http://xxx/Admin/Index or, 'http://xxx/Admin/'.
It is well worth looking around SO and other various websites for MVC queries!
Good luck.

Failed to return partial view from area

Basically I've just created an Area in my ASP.NET MVC4 application.
It all works great etc, however when I want to return a PartialView as shown below:
return PartialView("_ImportSessionsTable", viewModel);
(not that the above call is called from the area(admin) view)
I get the following error:
The partial view '_ImportSessionsTable' was not found or no view
engine supports the searched locations. The following locations were
searched: ~/Views/ImportSessions/_ImportSessionsTable.aspx
~/Views/ImportSessions/_ImportSessionsTable.ascx
~/Views/Shared/_ImportSessionsTable.aspx
~/Views/Shared/_ImportSessionsTable.ascx
~/Views/ImportSessions/_ImportSessionsTable.cshtml
~/Views/ImportSessions/_ImportSessionsTable.vbhtml
~/Views/Shared/_ImportSessionsTable.cshtml
~/Views/Shared/_ImportSessionsTable.vbhtml
The thing is: as far as I can see it isn't looking for the view in the area folder (admin) which is where I have the view stored. How can I get it to look there? Whenever I call return View(); it works fine so it's only when I specify the view as a string.
How can I get it to look there?
You could specify the full location of the partial to be rendered:
return PartialView("~/Areas/Admin/Views/ImportSessions/_ImportSessionsTable.cshtml", viewModel);
You could also consider overriding where the viewengine searches for views, but that might be a little extreme for what you're looking for. See here: Link

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.

Why is Asp.Net MVC not searching for a view in my Shared directory?

In my /Views/Shared/ folder I created an EntityNotFound.cshtml razor view. In one of my controller actions I have the following call:
return View(MVC.Shared.Views.EntityNotFound, "Company");
This causes the following exception:
System.InvalidOperationException: The view '~/Views/Shared/EntityNotFound.cshtml' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Company/Company.cshtml
~/Views/Company/Company.vbhtml
~/Views/Shared/Company.cshtml
~/Views/Shared/Company.vbhtml
I am confused, because it does not even seem to be attempting to search ~/Views/Shared/EntityNotFound.cshtml. Even if I replace MVC.Shared.Views.EntityNotFound with "EntityNotFound" I get the same error.
Why is Asp.Net MVC not even attempting to find my shared view?
Have a look at the list of overloads for View();
http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.view.aspx
Specifically, when you pass View(string,string); it sees the second string as the name of the master view.
Whats probably happening, is that it can't find the "Company" master view, you'll not the exception messages says
... or its master was not found...
Which means that it is probably finding the NotFoundException.cshtml, but can't correctly find the Company.cshtml that it's looking for as the master.
The correct syntax should be this (don't pass path, MVC is a language by conventions)
return View("EntityNotFound");
Assuming "Company" is a param you wnat to pass to the view, try like this:
ViewBag.ErrorEntity = "Company";
return View("EntityNotFound");
And from the View
<p>Entity not found: #ViewBag.ErrorEntity</p>

Problem returning specific view in asp.net mvc3

I have a view file structure like:
Views
Company
Department
Employee
ManageEmployee.cshtml
and the controller is
public class EmployeeController : Controller
{
public ActionResult Index(int dptId)
{
var loadedEmp = getEmpOf(dptId);
return View("Company/Employee/ManageEmployee", loadedEmp);
}
}
But the controller give me an error - telling that it can't find the view.These are the paths it search.
~/Views/Employee/Company/Employee/ManageEmployees.aspx
~/Views/Employee/Company/Employee/ManageEmployees.ascx
~/Views/Shared/Company/Employee/ManageEmployees.aspx
~/Views/Shared/Company/Employee/ManageEmployee.ascx
~/Views/Employee/Company/Employee/ManageEmployee.cshtml
~/Views/Employee/Company/Employee/ManageEmployee.vbhtml
~/Views/Shared/Company/Employee/ManageEmployee.cshtml
~/Views/Shared/Company/Employee/ManageEmployee.vbhtml
Basically if I'm able to eliminate the Employee section, the engine will find it.
~/Views/Employee/Company/Employee/ManageEmployee.cshtml to this
~/Views/Company/Employee/ManageEmployee.cshtml
Any insights on how to achieve this.
Thanks.
Have you tried:
return View("/Company/Employee/ManageEmployee", loadedEmp);
It looks like the engine is trying to return the view relative to your current location in the site rather than from the root of the site.
View has to be returned from the controller in the following way (for Specific View):
return View("ManageEmployee", loadedEmp);
In MVC, the controller will automatically route to the View name you provided.
loadedEmp should be the object you are passing to the view.
You need to follow MVCs convention of ControllerNameController for your controller and your view structure of ControllerName/...
If you want full control over your structure you'll need to switch to a different framework like FubuMVC.
If you want your own convention of arranging the views folder structures, it would be better you plug in your own view engine.

Resources