Ive got a mega annoying problem I have a view with:
#{
if(ViewBag.Section == "Home")
{
<div id="headerfrontPage">
}
else
{
<div id="header">
}
}
And I get a compilation error:
The code block is missing a closing "}" character. Make sure you have
a matching "}" character for all the "{" characters within this block,
and that none of the "}" characters are being interpreted as markup.
How do I conditionally write a div? Its for a hack bascially...
You can use the same construct when you wrap your div's inside element like:
#if (ViewBag.Section == "Home")
{
<text><div id="headerfrontPage"></text>
}
else
{
<text><div id="header"></text>
}
Or you use razor syntax #: like
#if (ViewBag.Section == "Home")
{
#:<div id="headerfrontPage">
}
else
{
#:<div id="header">
}
But for your current situation I would prefer Ron Sijm's solution:
#{
var divName = ViewBag.Section == "Home" ? "headerfrontPage" : "header";
}
<div id="#divName">
I suspect it is because your divs are not closed, so razor assumes that the closing brace is actually part of the div content.
You might try outputting the entire div content within your code there, including the closing tag, or output the div tag with a Response.Write, or something similar, so there is no confusing markup.
EDIT: also, maybe enclosing your div tag in a
<text></text>
might be worth a try.
You could try this:
#{
string divName;
if(ViewBag.Section == "Home")
{
divName = "headerfrontPage";
}
else
{
divName = "header";
}
}
<div id="#divName">
I'm not sure if that will help, it a long shot. But at least imo that looks better...
Try this:
#if (ViewBag.Section == "Home")
{
<text> <div id="headerfrontPage"> </text>
}
else
{
<text> <div id="header"> </text>
}
The simplest way to write this would be:
<div id="#(ViewBag.Section == "Home" ? "headerFrontPage" : "header")">
Or, if you prefer, you can use a local variable:
#{ var headerID = ViewBag.Section == "Home" ? "headerFrontPage" : "header"; }
<div id="#headerID">
Regarding the more general case of unclosed tags in Razor code blocks, you can explicitly mark the opening tag as content:
#if (ViewBag.Section == "Home")
{
#:<div id="headerFrontPage">
}
else
{
#:<div id="header">
}
Related
I'm getting this exception while trying to render PartialView. When I change #{Html.RenderPartial("_ChildReplies", parRep.ChildReplies);}
to
#Html.Partial("_ChildReplies", parRep.ChildReplies) still getting same exception.
#model List<Reply>
#using YourPlace.Models
<ul>
#foreach (var parRep in Model)
{
<li>
Author: #parRep.AuthorName
Comment: #parRep.AuthorName
<div>
#{Html.RenderPartial("_ChildReplies", parRep.ChildReplies);}
</div>
</li>
}
</ul>
The code above looks correct... if you are getting this error, it is probably because something is going wrong inside _ChildReplies partial view which you have not shown in your question...
Good explanation here:
RenderPartial() is a void method that writes to the response stream. A void method, in C#, needs a ; and hence must be enclosed by
{ }.
Partial() is a method that returns an MvcHtmlString. In Razor, You can call a property or a method that returns such a string with just a
# prefix to distinguish it from plain HTML you have on the page.
So you need to either use this:
#{ Html.RenderPartial("_ChildReplies", parRep.ChildReplies); }
Or this:
#Html.Partial("_ChildReplies", parRep.ChildReplies);
I have this code
#if (Model.Name!= null)
{
<div>#Model.Name, <span>#Model.Email</span></div>
}
and I want to highlight the postal code if this condition - IsFlaggedEmail is true:
if (Model.IsFlaggedEmail(out flagComments))
{
<span id="flagged" style="background-color:yellow;font-size:10pt">
}
and I want to display the comments in the title of the span (a tool tip). How can I write this in the cshtml file?
This is what I tried, but I keep getting errors like: "The if block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup."
#if (Model.Name!= null)
{
<div>#Model.Name, #{
string flagComments;
if (Model.IsFlaggedEmail(out flagComments))
{
<span id="flagged" style="background-color:yellow;font-size:10pt">
}
} #Model.Email</span></div>
}
#{ string comments;
if (Model.IsFlaggedEmail(out comments)) {
#section Scripts {
$("#flagged").val('title', comments)
}
}}
Also, can I do something like that directly from jQuery?:
#if (Model.Name!= null)
{
<div>#Model.Name, <span id="flagged">#Model.Email</span></div>
}
#{ string flagComments;
if (Model.IsFlaggedEmail(out flagComments)) {
#section Scripts {
$('#flagged').css('background-collor', 'yellow')
$('#flagged').attr('title', #flagComments);
}
}}
No javascript needed.
You can use something like:
#if (Model.Name != null)
{
string flagComments;
bool isFlagged = Model.IsFlaggedEmail(out flagComments);
<div>
#Model.Name, <span id="#Html.Raw(isFlagged? "flagged": "")">#Model.Email</span>
</div>
And for styling it is better to use CSS. (You have an ID flagged).
Also try to avoid spreading html building across if statements. It is always better to keep tags matching inside one clause.
I have this helper:
public class PanelSection : IDisposable
{
protected HtmlHelper _helper;
private string f;
public PanelSection(HtmlHelper helper, string title, string subTitle, bool footer)
{
_helper = helper;
f = footer ? "" : "</div>"; //If footer is true, we end body ourselves, if footer is false, we end both - body and panel automatically
_helper.ViewContext.Writer.Write(
"<div class='panel panel-default'><div class='panel-heading'><h2>" + title + "</h2></div><div class='panel-body'>"
);
if (!string.IsNullOrEmpty(subTitle))
_helper.ViewContext.Writer.Write(
"<h4>" + subTitle + "</h4><hr/>"
);
}
public void Dispose()
{
_helper.ViewContext.Writer.Write("</div>" + f);
}
}
If footer is set to True, that means I will end panel-body myself, so on dispose it writes one less div. This should let me have panel-footer when I need it, or have table outside of body. But on when I do this I get
Parser Error Message: Encountered end tag "div" with no matching start tag.
My razor code looks like this:
using (Html.BeginPanel(#Resources.Contract, #Resources.CreateNew, true))
{ //starts panel, starts panel body
<b>Body content</b>
</div> //end of body
<div class="panel-footer">
#Resources.Back
</div>
} //end of panel
Obvious solution would be to simply not open panel body on that helper, and for panel body use different helper. But I'm still interested why it gives me that error. It should generate good html without any errors, but it looks like it process everything before changing helper into html, sees an extra div and throws parse error. Why is that? Is there any way to make this work?
Unbalanced razor tags can be output using the #: syntax.
Providing everything else compiles you can output the razor as follows:
using (Html.BeginPanel(#Resources.Contract, #Resources.CreateNew, true))
{
//starts panel, starts panel body
<b>Body content</b>
#:</div> //end of body
<div class="panel-footer">
#Resources.Back
</div>
} //end of panel
Note the #:</div>.
For a C# MVC 5 application we have the following partial view:
#using some.using.here
#using some.using.here
#using some.using.here
#{
var treeItem = TempData["SELECTED_TREEITEM"] as ITreeItem;
string path = treeItem.GetIdPath(TempData.GetParentId());
User user = Session["somesessionkey"] as User;
}
<!-- Selected item from URL -->
#if (treeItem != null)
{
<input type="hidden" id="routeData" data-key="#treeItem.Key" data-treepath="#path" data-area="#TempData["SELECTED_AREA"]" data-mode="#TempData["SELECTED_MODE"]">
}
<input type="hidden" id="defaultAsset" data-default="#(user != null ? (user.DefaultAsset != null ? methodcall(value).ToString() : string.Empty) : string.Empty)" />
<input type="hidden" id="newPeriodHrs" data-newperiodhrs="#(user != null ? user.NewPeriodHrs : 48)" />
However, no matter what I do, Resharper keeps complaining with the following message:
Views\Shared\_RouteData.cshtml:18 Closing brace expected
To save you from counting, line 18 is at the end of the file.
Contrary to what Resharper might suggest, the whole project compiles and runs fine.
But is there still some kind of syntax issue I'm missing? Or is Resharper just plain wrong in this case?
I'm running Resharper 8.2 (C# edition).
(please excuse my poor attempt at removing sensitive information from the code, I left all braces and such intact)
Turns out the solution is really sneaky, a single slash is missing in this piece:
#if (treeItem != null)
{
<input type="hidden" id="routeData" data-key="#treeItem.Key" data-treepath="#path" data-area="#TempData["SELECTED_AREA"]" data-mode="#TempData["SELECTED_MODE"]">
}
It should look like this: data-mode="#TempData["SELECTED_MODE"]" />
I'm trying to dynamically set an attribute(data-status) for a div if a condition is met.
I am currently using the #Html.Raw helper however it's not making its way in to the element.
I have also attempted to use Response.Write() however it just writes everything to the top of the page.
Is there a best way to actually embed this in to the code or maybe create/set a new attribute?
#foreach (var r in Model)
{
<div class="marker"
data-date="#r.date_finished"
data-name="#r.name"
#if (r.complete == "CP")
{
#Html.Raw("data-status='complete'");
}
>
</div>
}
This should do it:
<div class="marker"
data-date="#r.date_finished"
data-name="#r.name"
#{if (r.complete == "CP") { <text>data-status='complete'</text> }}>
Notice the usage of <text> tag. This is a special tag which Razor uses to output content as is.
When I run into this scenario I use a tertiary expression:
<div #(r.complete == "CP" ? "data-status='complete'" : "") >
If your logic is more complex you could also use a static helper method.
<div #r.RenderComplete() >
public static class RExtension{
public static string RenderComplete( this R r){
// logic here
}
}