In order to access a razor view in a folder other than the standard one (MVC 5 VS 2013) I found out (in this forum) two solutions: add the web config in that folder or add the following at the top of the view: "#inherits System.Web.Mvc.WebViewPage"
I tried both approaches and it works, but the view, however, is displayed by itself, alone, without the _layout, the menu, nav bar, etc...
I'm wondering if is it possible to display the view as part of the app framework.
The layout path must be specified in the view. The alternative, and what exists by default in the Views folder is to use a _ViewStart.cshtml file to set the layout, and then any view in that folder or a nested folder will use that layout unless told otherwise.
The easiest solution then, is to just specify the layout in your view:
#{
Layout = "~/path/to/_Layout.cshtml";
}
Or, you can create _ViewStart.cshtml in your other views folder and add the above code there. Not sure if that will actually work with a non-standard views folder, though, but you're welcome to try it.
Related
I am trying to have a fix menu on some of my views. For example I have a view called 'Kitchen' and then I have sub views in there. I need to have a fix menu to each view there.
I have been able to menu to each view file but how do I make a separate file for menu on some particular views. I am using razor as template engine.
You have two options:
Use a different shared template (like ...\Views\Shared\_Layout.cshtml) for the views that need a menu. This template can itself use another (like ...\Views\Shared\_Layout.cshtml) for content common with all pages. So this my setting Layout to the relative path to the template.
Use a partial view: another Razor file that is included into the views are renders the menu:
#Html.Partial("_TheMenu", menuModel)
the model parameter, if no model needed, isn't requited.
I have an ASP.NET MVC 4 site with areas and I have some System views that I want to share between the areas. Each area has its own separate layout. When I access a System view (by explicitly specifying area = ""), it uses the layout page from the main _ViewStart.cshtml file. The problem is, I want to use the layout of the Area instead.
I have tried removing the Layout declaration from the main _ViewStart.cshtml file and even removing the _ViewStart.cshtml file altogether, but all that does is make my System view render with no layout at all.
I also ran across this post that explains you can put complex logic in your _ViewStart.cshtml file to do this. I tried, but had problems when trying to render partial views on the same page (that are area specific). It would seem that I need to "reset" the area parameter within _ViewStart.cshtml, but I haven't figured out how to do that.
How do I make a main view (from /Views/ folder) take on the layout of the area that called the view? Keep in mind, I don't want to hard code it to the layout of a specific area.
The obvious thing to do would be to make a copy of the System views and their controller in each area, but I am trying to avoid having duplicated files (DRY).
I managed to get this working by using a customized _ViewStart.cshtml that sets the area back to where it was via ViewContext.RouteData.DataTokens. In my case, the area is determined by the TenantType enum in the ApplicationContext (a set of values stored in HttpContext.Current.Items), so getting at it wasn't too difficult.
var appContext = new ApplicationContext();
var area = appContext.CurrentTenant.TenantType.ToString();
this.ViewContext.RouteData.DataTokens["area"] = area;
Layout = "~/Areas/" + area + "/Views/Shared/_Layout.cshtml";
So basically, we are calling a shared controller named SystemController which simply returns View(). That directs it to look for a controller in the common /Views/ControllerName folder, which is where my shared view is.
When it calls _ViewStart.cshtml, it sets the Area back to the current area (which in my case is determined by looking up the domain name in the database). This allows the Area _Layout.cshtml page to use the partial views that are stored in the Area/Shared folder.
Finally, we set the layout page explicitly to the current area's layout.
I have the following project structure:
/Views/Shared/_Layout;
/Areas/Area1/Views/ControllerName/Index;
...
/Areas/AreaN/Views/ControllerName/Index.
Is there any way to force all areas to use the _Layout as a base layout?
Is there any way to do it without adding the _ViewStart file (for example, via the routing configuration)?
See Also:
How do I specify different Layouts in the ASP.NET MVC 3 razor ViewStart file?
You just have to add a file named:
_ViewStart.cshtml
Under each area views folder:
/Areas/Area1/Views/_ViewStart.cshtml
And edit the file to point to the root layout like this:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
In order for this to work, you do not have to specify a value in the view's layout property, if you do, you would be overriding the global layout
Note: As Tony mentioned, you could edit each view's layout property to point to the root layout, however this is not the recommended way to do it since you would be coupling your views with your layout and change it would be painful
Edit 1
If you would like to use code to set the default view's layout, perhaps you should consider writing a custom view engine.
Try to google about custom RazorViewEngine and RazorView
This article could be a good start point
http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx
I have not done something like this but I hope I'm pointing you in the right direction
Expanding on the answer by Jupaol....
At least in VS2013, the _ViewStart.cshtml file is added by default when creating the area, so it's already there, and you can change the contents as he notes to point to the root _Layout.cshtml. You can then remove the _Layout.cshtml in the area, since it is no longer used (and a potential source of confusion now)
However, by so doing any routing performed in that root _Layout.cshtml will need to consider areas.
The default _Layout.cshtml has a number of ActionLink helpers that need a slight modification:
Add the RouteValueDictionary param to any ActionLink calls by setting Area="". Note that empty string refers to the root level. This will allow these links to work correctly when invoked from within an area, still work when invoked from the root.
e.g.:
<li>#Html.ActionLink("Home", "Index", "Home", new { Area = "" }, null)</li>
You specify a layout using:
#{
Layout = "_Layout";
}
If you want to make this easier to change all at once. Perhaps you could just set it as a view bag variable and pass it in on the controller. To make it even easier you could create a base controller that the other controllers inherit from and have it assign the layout to the view bag there.
Not sure why routing would need to change or perhaps I am not understanding. Hope this helps :)
I am busy changing the default T4 Templates that gets generated when I click on the "Add View" dialog from my Controller. I know how to change the templates. But the following i can not wrap my head around.
I want to be able to generate the following when the user clicks on Add View.
A partial view that only contains the Form part of the view that is generated by default
A View that calls the partial view generated above.
Is it possible to generate 2 files like this using the T4 Templates ?
thanks in advance
Why? Are you going to be routinely doing this exact same thing over and over again? If so, then a T4 template may make sense. If you're doing it once or twice, then just modify the files by hand.
I know there are a few questions that have been answered but I didn't find something specific to my case.
I'm using the mobile capabilities of MVC4. So I created a _layout.mobile.cshtml and the corresponding views.
The error above happens when I go in with a mobile device. As you can see, it is trying to display the regular _layout.cshtml instead of the _layout.mobile.cshtml. So I'm assuming it is also trying to display the view (say Index.mobile.cshtm) which doesn't have the section in question. Basically it is mixing the regular layout with the mobile views.
This doesn't happen all the time. If I recycle the pool it works again for a while and then all of the sudden it goes back to having the error and it will continue until I recycle the pool again.
Has anyone seen this problem before that can shed some light?
Thanks
John
In the _ViewStart.cshtml available under the Views folder, change the Layout value to your custom layout. I think this may help.. (Make sure that you are returning View instead of partial view)
for example
#{
Layout = "~/Views/Shared/_layout.mobile.cshtml";
}
In case if you want to change the layout for a specific page you can explicitly define it at the top of the page as a page directive.
in the index.cshtml there is a section being called defined in the original layout file "_LayoutHome.cshtml" that is not defined in the new bootstrap layout.
specifically: #RenderSection("featured", required: false)
So the solution is to either add this section to the new layout (look for it in the original layout and paste it) or simply delete it from the index.cshtml.
I had also face the same problem I removed
#section featured {
From View
Another way to do this is to use a conditional block in your _ViewStart.cshtml page. For example, you may have two layouts depending on the device regular user. Using pseudo-code for the reading of the device/browser type bit, it would look something like this:
#{
if(userIsMobile)
{
Layout = "~/Views/Shared/_MobileLayout.cshtml";
}
else
{
Layout = "~/Views/Shared/_Layout.cshtml";
}
}
I have used this to display or hide sections or menu items as needed for different classes of user; it should work as well for device-specific layouts.
Joey Morgan