Allow "invalid" html markup in partial view in MVC 3 - asp.net-mvc-3

I have a problem with generating html with razor engine. In my case I have a app where a stored procedure lists a nested tree and have calculated how many submenus, how many siblings etc there are. And I need to have some logic in my partial view. And razor engine doesn't seem to like it since it seems to be invalid markup. How can I fix this to it prints out what I want?
<ul class="menu">
#foreach (var item in Model.NestedMenus)
{
if (item.StartNode > 0)
{
if (item.SubMenus > 0)
{
<li style="submenu">
}
else
{
<li style="menu">
}
#item.MenuName
}
else
{
</li>
}
}
</ul>
Must I use some old school Response.Write or summet? :)
/L

You need to prefix the lines with #: to prevent Razor from trying to parse the markup.
Otherwise, it will need to parse the markup in order to end the code block outside the top layer of markup.

Related

How can I add c# code within HTML tags in ASP.Net Core

I'm migrating my site from ASP.net Framework (4.7.2) to Asp.net Core (5). One issue that I can't seem to figure out is that in my original site I had c# in a few of my HTML tags to set the css class(es). For instance:
<div class="carousel-item propertyCarousel #if (firstImage) { <text>active</text> } #if (slideNumber > 2) { <text>bonus-image</text> } " data-slide-number="#slideNumber.ToString("D2")">
Because of tag helpers, asp complains about the code. So I disabled tag helpers in the _ViewImports.cshtml and it no longer complains, but then sometimes the code just doesn't work. For instance in the above example I never get a div with the 'active' class despite verifying the conditions are correct (i.e. that 'firstImage' is true for the first image).
Since the previous commenter did not really answered the question, I'm going to go ahead and say that you need to use brackets for it to work.
This works because it's in a variable:
<div class="#htmlClass"></div>
But when you need the result of an expression from within your HTML attribute like:
<div class="#myvar == true ? "active" : string.Empty"></div>, does not work. What you should do is wrap it in brackets like this :
<div class="#(myvar == true ? "active" : string.Empty)"
This will output: <div class="active"> if the result of the expression was true.

Umbraco Beginning Razor - list all news items

Hi I have a node events and have 6 types 'eventItem' which are children. On my homepage I want to list all nodes of type eventItem and list the eventDate.
Thanks
Using razor you could do something like the following:
#{
dynamic eventFolder = Library.NodeById(1234);
<ul>
#foreach (var event in eventFolder.Children)
{
<li>#event.eventDate.ToShortDateString() - #event.Name</li>
}
</ul>
}
Obviously, replace "1234" with the actual Id of the event folder and then place the razor script inside a macro and put the macro on your home page's template and you should be good to go.

Is there an easier way to write this html/razor code

<ul>
#{int i=0;}
#foreach (var entry in Model.PhoneNumberEntries)
{
<li>
<span>#entry.PhoneNumber<span>
#Html.TextBoxFor(m=>Model.PhoneNumberEntries[i].PhoneNumber)</li>
i++;
}
</ul>
This seems a little too verbose for me... is there way to get around creating the counter with having to resort to the standard for loop?
This seems a little too verbose for me... is there way to get around
creating the counter with having to resort to the standard for loop?
Yeah it seems too verbose to me as well. Even the loop seems too verbose as you don't need it if you use editor templates.
<ul>
#Html.EditorFor(x => x.PhoneNumberEntries)
</ul>
and then obviously you would define a custom editor template that will automatically be rendered for each element of the PhoneNumberEntries collection (~/Views/Shared/EditorTemplates/PhoneNumberEntry.cshtml):
#model PhoneNumberEntry
<li>
<span>#Model.PhoneNumber</span>
#Html.EditorFor(m => m.PhoneNumber)
</li>
You don't even need to write loops as templates work by convention.
Notice that the name and the location of the editor template is important. It should be located either inside ~/Views/Shared/EditorTemplates if you want to share this template between views belonging to different controllers in your application and it is the location where ASP.NET MVC will first look for it. Or you could also put it inside ~/Views/XXX/EditorTemplates where XXX is the name of the current controller. Then name of the editor template must be the name of the type used as agrument for the collection property.
So if you had no your main view model:
public IEnumerable<FooBarViewModel> FooBars { get; set; }
the name of the corresponding template would be FooBarViewModel.cshtml and obviously it will be strongly typed to FooBarViewModel.
Try this:
<ul>
#for (int i=0; i++; i < Model.PhoneNumberEntries.Count)
{
<li>#Html.TextBoxFor(m=>Model.PhoneNumberEntries[i].PhoneNumber)</li>
}
</ul>

Orchard - How to show more fields of a content item in a summery view

Let's say I have a product to which I've added an image field called SmallImage.
When I show a list of products, I want the small image to be in the view.
When I go to the list of divisions I get the default summary view, like so:
<article class="content-item #contentTypeClassName">
<header>
#Display(Model.Header)
#if (Model.Meta != null) {
<div class="metadata">
#Display(Model.Meta)
</div>
}
</header>
#Display(Model.Content)
#if(Model.Footer != null) {
<footer>
#Display(Model.Footer)
</footer>
}
</article>
How does #Display(Model.Content) generate the HTML?
Where is the .cshtml file I can put #Html.Image(Model.SmallImage) into?
EDIT
Ok, I found the property off the model: Model.ContentItem.Product.SmallImage.FileName, so I just need to know where the template file is.
THX!
Dan
Bonus Question:
Using the designer tools in any list view. Go to Zone[Content].Content.List. Under Shape is says there are two alternate views. One is MyTheme/Views/List.Html. If you click on "create" it says The relative virtual path 'Orchard.Core.Shapes.CoreShapes::List' is not allowed here. Does that mean that there really isn't an alternate for this view?
I manually created the file that was giving me the error in the bonus question and this gets me the image. (List-url-products.cshtml)
<div>
#foreach(var item in Model)
{
<div>#item.Title.ToString()</div>
var division = item.ContentItem.Division;
var smallImage = (Contrib.ImageField.Fields.ImageField) division.ListImage;
if(smallImage.FileName != null)
{
<div>#Html.Image(smallImage.FileName, null, new { Width=smallImage.Width, Height=smallImage.Height }) </div>
}
}
</div>

Using ActionLInk from inside a helper template cshtml page

Why doesn't Html.ActionLink work in the below code? This is a page in the app_code folder,
that I am trying to call from index.cshtml
LogOnUserControl.cshtml
#helper DisplayUserControl(){
if (Request.IsAuthenticated ) {
<span>Welcome <strong>#User.Identity.Name</strong>!</span>
<span>[ {#Html.ActionLink("","","")} ]</span>
}
else {
<span>[{#Html.ActionLink("","","") }]</span>
}
}
this is the line of code from index.cshtml. The call itself works, if I remove the Html.ActionLink statements the site loads fine. Is it that you can't use them in a nested page like this? How else can I generate dynamic links?
index.cshtml
#LogOnUserControl.DisplayUserControl()
What's the idea with this action links? Why are you passing empty strings as arguments? I suppose you want to generate SignIn, SignOut links, don't you?
Also if you want to use HTML helpers inside shared helpers that you put in the App_Code folder you will need to pass them as arguments because they are not available:
#using System.Web.Mvc.Html
#helper DisplayUserControl(System.Web.Mvc.HtmlHelper html) {
if (html.ViewContext.HttpContext.User.Identity.IsAuthenticated) {
<span>
Welcome
<strong>
#html.ViewContext.HttpContext.User.Identity.Name
</strong>
!
</span>
<span>[#html.ActionLink("SignOut", "Login")]</span>
}
else {
<span>[#html.ActionLink("SignIn", "Login")]</span>
}
}
and to call the helper:
#LogOnUserControl.DisplayUserControl(Html)
Personally I never use such helpers (the ones you put in the App_Code folder). Can't see any use for them when you have partial views, editor/display templates and Html.Action helpers.
So for example you could define a partial (~/Views/Shared/_LogOnUserControl.cshtml):
#if (User.IsAuthenticated) {
<span>
Welcome
<strong>
#User.Identity.Name
</strong>
!
</span>
<span>[#Html.ActionLink("SignOut", "Login")]</span>
}
else {
<span>[#Html.ActionLink("SignIn", "Login")]</span>
}
which you would include in your layout:
#Html.Partial("_LogOnUserControl")

Resources