RenderSection and EditorForModel in asp.net MVC - asp.net-mvc-3

This is my _Layout.cshtml
<html>
<head>
#RenderSection("Script", false)
</head>
...
</html>
This is a simple edit page edit.cshtml
#model Shop.Models.Product
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.EditorForModel()
and this is ~/Views/Shared/EditorTemplates/Product.cshtml
#model Shop.Models.Product
#section Script {
<script>alert("hello");</script>
}
...
#section Script{...} does not work in Product.cshtml because of EditorForModel. How can do it?

Sections work only in views, not in partials. An editor template is a special kind of partial. It's bad practice to put javascript in partials anyway, so I would simply declare the section in the Edit.cshtml view.
But if you very much insist on putting your scripts in the middle of your markup, since Razor doesn't support sections in partials, you could implement custom helpers to achieve that.

Related

asp.net mvc 3, add <meta /> to <header> from any part of application

My question is: How can I add meta tag from my view or partial view? Basically I want to, from the view, write a meta tag, and I want it to be displayed in the header. Is it possible?
Thank you
H
You can use sections to do this.
In you layout page you need to define the section:
<head>
#RenderSection("Head", required: false)
</head>
This section can then be used in any page that uses this layout page:
#section Head {
<meta ... >
}

MVC 3 Rendering a section in a area

I am trying to render a section that is defined in _layout file from my custom area.
In my area I have the _ViewStart which points to the _layout in the root site.
The section that I am trying to use is in the head tag, but in my area it is put in the body.
Page that are rendered at the root level work fine.
~/Views/Shared/_Layout.cshtml
<head>
#RenderSection("header", true)
</head>
<body>
....
</body>
~/Areas/UserMedia/Views/_ViewStart.cshtml
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
~/Areas/UserMedia/Views/ManageProjectMedia.cshtml
#{
ViewBag.Title = "ManageProjectMedia";
}
#section header{
{
<!-- scripts and styles -->
}
<div>
... page content
</div>
On your question you pointed out a code sample whose path is ~/Views/_layout.cshtml and on your _ViewStart.cshtml file under your area, you have the following code :
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
I am sure you will find the seven difference here :)
Seven difference thing was a joke but anyway. Your _Layout.cshtml is sitting under ~/Views/ but you're referencing _Layout.cshtml which is under ~/Views/Shared/.

MVC 3 - Nested layouts - sections don't render in Areas

Problem:
Given this nested layout structure:
~/Views/Shared/_layoutBase.cshtml
~/Views/Shared/_layout.cshtml
Where _layoutBase.cshtml is the layout for _layout.cshtml.
Any sections defined in the layout files render their content fine in pages under ~/Views/...
However, for views in an area, the sections are never rendered.
Setup:
_layoutBase:
<script type="text/javascript">
#RenderSection("footerScripts", false)
</script>
</body>
</html>
_layout.cshtml:
#section footerScripts{
#RenderSection("footerScripts", false)
}
"content" view:
#section footerScripts{
$(function () {
SetFocusOnForm("CaptchaCode", "NextButton");
});
}
The content of section footerScripts never gets rendered in a view in an area. It does get rendered in a view that is under the ~/Views folder.
Area _ViewStart.cshtml:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Question:
Can you see anything wrong?!
I am unable to reproduce the problem. Here's my setup and steps I did.
Create a new ASP.NET MVC 3 application using the Internet Application Template
Add ~/Views/Shared/_LayoutBase.cshtml:
<!DOCTYPE html>
<html>
<body>
#RenderBody()
<script type="text/javascript">
#RenderSection("footerScripts", false)
</script>
</body>
</html>
Replace the contents of ~/Views/Shared/_Layout.cshtml with this:
#{
Layout = "~/Views/Shared/_LayoutBase.cshtml";
}
#section footerScripts{
#RenderSection("footerScripts", false)
}
#RenderBody()
Right click on the project and add an Admin area
Add a TestController to this admin area and add a corresponding ~/Areas/Admin/Views/Test/Index.cshtml view:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#section footerScripts{
alert('ok');
}
Run the application and navigate to /admin/test/index
The alert is shown
The Reason Why:
I have got up this morning and saw the problem straight away:
I had the #section blocks in a Partial View. In MVC 3, that WON'T work!!
ARGH!
I really appreciate Darin's effort, that effectively provided proof that sections do work in Areas as expected. But the real cause was this.
I forgot they were in a Partial View, because I have a mvc 3 wizard that uses partial views for steps. It works so well and consistently, using ajax if javascript is available, that you forget what you are doing.
Please give Darin a vote, but this is the real answer.

meta tag in ASP.NET MVC 3

How can I put meta tag to work only for one page. If I want to put it .aspx file, where is right place.
Thanks.
Since you haven't said yet, I'm assuming you're using the Razor engine (the "default" for new MVC3 projects). In that case, you just need to insert a new section into your layout view, and only render that section if you need to insert a meta tag.
For example, working from the stock New ASP.NET MVC 3 Project template, you would edit your Views\Shared\_Layout.cshtml file, and before the closing </head> tag, do something like this:
#this.RenderSection("MetaContent", false)
</head>
Then, in any of your views that you needed to, add this:
#section MetaContent
{
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
}
If you're still using the ASPX layout engine for some reason, you can accomplish the same thing using the <asp:ContentPlaceHolder> tags in your master page and <asp:Content> tags in your views.
EDIT:
Since you're using the ASP.NET Forms layout engine still, here's the same basic idea as above in aspx syntax:
In your master page, you add the tag:
<asp:ContentPlaceHolder ID="MetaContent" runat="server" />
</head>
And in your .aspx views, you add a new content section (you should already have at least two -- a title and a body):
<asp:Content ID="Meta" ContentPlaceHolderID="MetaContent" runat="server">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
</asp:Content>
I was going to suggest exactly what Michael said (+1). Another option would be to put a boolean in the ViewBag, something like:
ViewBag.ForceIE8Mode = true;
For pages that you want to force into IE8 Mode.
and then in your view, wrap the meta tag in a conditional. either
#if(ViewBag.ForceIE8Mode == true) {
<meta... />
}
or
<% if(ViewBag.ForceIE8Mode == true) { %>
<meta... />
<% } %>

Page title problem when setting ViewBag variable from razor section in asp.net mvc

Consider fallowing declaration in view
#section sideaction
{
...
ViewBag.Title=Model.Title;
...
}
And in main layout i have this
<head>
<title> #ViewBag.Title</title>
....
...
</head>
..
...
<body>
..
#RenderSection("sideaction",required:false)
..
</body>
I am not getting title from view, i know that view will be processed before layout but i recognized that head section is processed before render section which is causing this problem.
One more thing , ViewBag.Title=Model.Title is just an example , the real Model is IEnumrable object and i am iterating and finding proper title. I can iterate in controller to find title but there is already iteration in view. For big collections one iteration is more efficient.
Any ideas?
You cannot set a ViewBag value in a section.
Use this:
#{
ViewBag.Title = Model.Title;
}
directly in the view to set a title.
Even it doesn't work, notice that the code has to be like this:
#section sideaction
{
#{
ViewBag.Title = Model.Title;
}
}
But as other people mentioned earlier, you can't do it this way inside a section.
You should put it directly inside your view:
#{
ViewBag.Title = Model.Title;
}
By the way, if you persist to change title of a page from inside a section, use javaScript/jQuery, e.g:
#section sideaction
{
<script type="text/javascript">
$(function () {
document.title = '#Model.Title';
});
</script>
}
Note: pay attention that it has to be '#Model.Title' (inside quotes).

Resources