Why when I have certain HTML in my C# statements does Razor complain about invalid expressions and terms?
And how can I fix this?
For example; in my _layout.cshtml:
#if (Team.Id == ViewBag.TeamId)
{
</div>
<div class="row">
}
Razor actually tries to understand your HTML. Unfortunately it can't be highly intelligent and recognise dynamic code or code outside of the expression.
Since
</div>
<div>
is invalid HTML, it complains.
You can avoid this problem by using #:
This forces razor to bypass its "HTML recognition", and simply print whatever you're asking for.
E.g.
#if (Team.Id == ViewBag.TeamId)
{
#:</div>
#:<div class="row">
#:
}
You can also use #Html.Raw("YOUR HTML"); inside an if statement to add HTML code
Related
At times I need to have the css class for div to have values, at other times I don't want to have class attribute or it's properties
<div>
<div class="highligh">
I have tried using a function as such
<div #GetCssClass(Model.IsThisPropertyHighlighted)>#Model.ThisProperty
but the problem is I can either get
<div > or <div class="">
Neither of them is satisfactory,
of course I also get <div class="highligh"> which is the only satisfactory case.
Please avoid calling functions in razor view.
Instead create a property in the model and in your razor view you can simply specify.
<div class="#Model.NewProperty">
If NewProperty is null class attribute will not be rendered at all.
I've been going over the asp.net Contoso University tutorial and there are two specific transitions between C# code and HTML markup (using "#:") that are not understood to me:
1)
#:<td>
I've read that when ASP.NET sees the opening HTML tag it automatically treats the code as HTML markup. If so, why is the "#:" used here?
2)
#course.CourseID #: #course.Title
Why is the "#:" in the middle of the code line and not in the beggining?
The full view code is below.
Thanks in advance for anyone who tries to help.
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<table>
<tr>
#{
int cnt = 0;
List<ContosoUniversity.ViewModels.AssignedCourseData> courses = ViewBag.Courses;
foreach (var course in courses)
{
if (cnt++ % 3 == 0)
{
#:</tr><tr>
}
#:<td>
<input type="checkbox"
name="selectedCourses"
value="#course.CourseID"
#(Html.Raw(course.Assigned ? "checked=\"checked\"" : "")) />
#course.CourseID #: #course.Title
#:</td>
}
#:</tr>
}
</table>
</div>
In short,It is used to tell that render this text as plain html, do not consider it c# code.
In your specific case it is used to add space between CourseId and Course Title in View here:
#course.CourseID #: #course.Title
#course.CourseID is c# code, when #: comes it is plain text now, then again when #course.Title comes it is considered c# code, so #: is to specify that it is plain html not c# code.
1) You are right about HTML tags behavior. They could use <td> instead of #:<td>.
2) You are right also about #course.CourseID #: #course.Title. It's unclear also to me why they chose to use this pattern. It would work the same if they used #course.CourseID #course.Title.
You may try yourself and see you are getting same results and output.
I would simply suggest you not take their example work as an absolute single way of using ASP.NET Razor.
I'm wondering if there is a good (or good enough) way to remove invalid or incorrectly placed HTML tags from an HTML string in C#?
Example 1: <div> </div> </div> should be changed to <div> </div>
Example 2: <div> </section> </div> should be changed to <div> </div>
Basically the transformed html string should be W3C validated markup. I understand that this may be a bit difficult to do, perhaps there is a library that does the job well?
Thanks!
I'd recommend using HTMLTidy.
Since you're using C#, there's the tidy.net project. I think there are dlls that you can just reference and use in your C# code.
Or, you can just use the command line stuff for HTMLTidy.
I ended up fixing the root issue that generated an invalid HTML string. In such a scenario, it is exceedingly better to fix the main problem - if possible - than the symptoms.
I am trying to do this using Razor templating:
#if(isNew)
{
<div class="new">
}
...
#if(isNew)
{
</div>
}
The error is:
cannot resolve the symbol 'div'
Razor doesn't like the ending div tag inside the IF clause, how can I get this to work? Is there an escape I have to use?
Razor doesn't like it when you split start/end tags up like this as it can't parse the HTML properly, so you have to escape them as plain text:
#if(isNew)
{
#:<div class="new">
}
...
#if(isNew)
{
#:</div>
}
The more conventional approach would be to repeat the markup inside the div (using partials or otherwise) - which approach is more desirable, I would say, is dependent upon the nature of the markup in between the conditional divs:
#if(isNew)
{
<div class="new">
<!-- some markup or partial view -->
</div>
}
else
{
<!-- some markup or partial view -->
}
I would prefer this approach if either:
The contained markup can be usefully contained in a partial such that it is reusable elsewhere.
The conditional wrapping markup is more than a couple of lines, at which point escaping markup becomes messy.
I should also add the option of using helper methods:
#helper MainMarkup()
{
<!-- some markup or partial view -->
}
#if(isNew)
{
<div class="new">
#MainMarkup()
</div>
}
else
{
#MainMarkup()
}
This is useful if you want to use the second option above but avoid repeating markup or nesting too many partials (particularly if this markup is only relevant for this view).
I am working on some template generation stuff with Razor, and I wish to accomplish the following syntax:
<div>
#(Html.Use<LinkItem>("Story1",
{
<span>Something cool</span>
#(item.Text)
}))
</div>
or, even better
<div>
#(Html.Use<LinkItem>("Story1",
<span>Something cool</span>
#(item.Text)
))
</div>
Using Templated Razor Delegates, I got this:
<div>
#(Html.Use<LinkItem>("Story1",
#<span>Something cool</span>
#<a href="#item.Href">
#item.Text
</a>
))
</div>
The problem is, I dont wanna have to add a # before each tag in the block, and a <text> tag doesent look too good either.
Is it possible to achieve what I am looking for? Or maybe there are other ways?
The closest you could get is with <text> nodes:
#(Html.Use<LinkItem>("Story1", #<text>
<span>Something cool</span>
#(item.Text)
</text>))
Personally I prefer using display templates:
#Html.DisplayFor(x => x.SomeCollectionProperty)
and then I define the corresponding display template which is automatically rendered for each element of the collection (~/Views/Shared/DisplayTemplates/SomeItem.cshtml)
#model SomeItem
<span>Something cool</span>
#Model.Text