Razor if statement inside HTML - asp.net-mvc

Why I can do that:
#Code
Dim styleVisible As String = if(Model.IndicateurAchatPeriodique,"block","none")
End Code
<div id="#sectionDCAId" style="display:#styleVisible">...
but not that:
<div id="#sectionDCAId" style="display:#If(Model.IndicateurAchatPeriodique,"block","none")">
I just moved the if instruction inside the HTML but it throw an error. Why the compiler can't understand it?
I don't need solutions, just an explanation. Thanks

The compiler seems to have problems with inline VB.NET Ifs. Not sure if it is a bug or it just isn't quite that clever. I know you haven't asked for a solution, but if you put an extra set of brackets in to help it then it will probably work - as in #(If(Model.IndicateurAchatPeriodique,"block","none"))

Related

multiple Html.Attr on one tag in razor?

how do i use multiple Html.Attr on one tag as follows in a razor view? this doesnt work.
<tr #Html.Attr("style", "color: #FF3D0D;")
#Html.Atrr("data-item", Model.ItemNumber)>
I'm not familiar with the .Attr helper either, but just incase you copied the code directly from your view, there is a typo, you have #Html.Atrr which I'm guessing should be #Html.Attr for data-item
So, it has come to this..
#Html.Atrr("data-item", Model.ItemNumber)
- VS -
data-item="#Model.ItemNumber"
Just one word: don't. Your markup AND every single human being on earth will benefit from the later much straight forward syntax. The HtmlHelper Html.Atrr doesn't help at all, no value.
Also, the following works for me:
<body #Html.Raw("data-test1=\"1\"") #Html.Raw("date-test2=\"2\"")>
.. and renders:
<body data-test1="1" date-test2="2">
You probably should be using #Html.Attr and not #Html.Atrr... or, as others have pointed out, just writing the attributes explicitly.

String.format help needed with mvc 3 razor (vb.net) please?

I've inherited some code... and am trying to convert it to use MVC 3, with Razor, the VBHTML is as follows:
For Each Message As MessageDetailsModel In Model.Messages
#<div id='#Message.HeaderId' class='#Message.HeaderCss' onclick=#(String.Format("shMsgTree('{0}','{1}',{2},'{3}');", Message.HeaderCss, Message.HeaderId, Message.MessageId, Message.UserId))>
... more stuff...
</div>
Next
Stepping through the code, the String.format resolves to this:
shMsgTree('sh_msg_GridItem sh_msg_MessageRead ','divHeader0',40,'{85A433F0-4054-42E7-B778-3EF005E411D3}');
which is what I want on the page, but for some reason, it gets output on the page as this:
shMsgTree('sh_msg_GridAltItem" sh_msg_MessageRead="
The properties on the model are all strings.
Am at a bit of a loss as to how to get it to render. Originally the entire onclick javascript was being returned in the Model, but that didn't render any better either.
Any suggestions would really be welcome. Thanks!
Given our conversation in the comments and the fact that the original Razor is quite hard to read, I think I'd recommend either:
writing a Razor Helper for this small block of code http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx
or writing a normal Extension Method to output the code - http://weblogs.asp.net/jgalloway/archive/2011/03/23/comparing-mvc-3-helpers-using-extension-methods-and-declarative-razor-helper.aspx (this is what I would choose!)
Without stepping through it in code, it's too hard to read the syntax as currently written - so break it out into a separate compact, testable, readable component.
Hope that helps
Stuart
Not sure if this will do it, but your onClickcode needs to be wrapped in quotes, before and after: onClick="#(String.Format(...))"

Why doesn't Visual Studio code formatting work properly for Razor markup?

Or, should I rather ask, when will VS code formatting work properly for Razor markup? The formatting works for most structures, but it seems to choke on 'if' blocks. The code below is as it is formatted by VS. It is very easy to fix this case, with one more indent, but I nicely accepted the formatting in everyday use, and like to use it often for the bulk of my code, so I'd rather avoid manual formatting if possible. Right now I just leave it as VS formats it.
#{
if (User.Identity.IsAuthenticated)
{
<text>Hello </text>
#Html.Display("#ViewBag.UserName") <text> - </text>
#Html.ActionLink("Sign Out", "LogOff", "Account", null, new { style = "font-weight: bold;" })
}
}
I think it's important for readability that, e.g. in the above, the body of the if block is indented, besides just looking nicer.
Be sure to set the editor to use space characters and not tabs. The editor seems to completely lose its mind when tabs are used. This is a shame because all those space characters end up in the actual HTML output, greatly increasing the data transfer size.
What I do is manually supplement the automatic formatting as I type. Not ideal, but hopefully Microsoft will have this figured out for the next service pack.
I found one "solution" that allows you to continue using tab indentation and have correct formatting. It's more of a pattern. The key is to use razor code blocks instead of inline code.
So for example, replace the following:
<div>
<div>
#if (true)
{
<b>Hi</b>
}
</div>
</div>
with:
<div>
<div>
#{
if (true)
{
<b>Hi</b>
}
}
</div>
</div>
The latter will format correctly, but the former won't.
Keep in mind, the formatting isn't perfect, but it's better than before.
It does not work correctly in all cases because it's a difficult problem to solve. Essentially you have 3 different editors (HTML, C#, and Razor) all interacting over the same text buffer. There are some cases (like this one) where the interactions have bugs. But we are working on improving the editor for the next release of Razor.
A better alternative here(rather than using spaces for tabs), is to change the block indenting for HTML and C#/VB to "Block" instead of "Smart". This isn't a full solution, but IMO is a far less painful work-around than using spaces!
In my case it was resharper overriding formatting options.
If your using reshaper and getting this issue try this...
Resharper >> Options >> Razor >> Editor & Formatting >> Untick “Auto-format on enter”
I found another solution for this. Just select all code in file, click Shift + tab to remove all tabs before code, copy and paste it. Visual studio automatically format code. Work on VS 2013 .cshtml file
I know it's not really the answer you're looking for but I've used WriteLiteral to get around my formatting issues.
For example, when I write:
<div>
#foreach (var item in Model) {
if (condition) {
#:</div><div>
}
#item.Label
}
</div>
Visual Studio tries to change it to:
<div>
#foreach (var item in Model) {
if (condition) {
#:
</div><div>
}
#item.Label
}
</div>
Which causes the page to throw an error.
If you use WriteLiteral you can fool the formatter into ignoring the line but it ain't pretty:
<div>
#foreach (var item in Model) {
if (condition) {
WriteLiteral("</div><div>");
}
#item.Label
}
</div>
Right now I'm on VS2013 ASP.NET MVC 5 and I still have that problem. What I found to be a lot helpful is to put the first expression on the same line where the opening block symbol is (#{). That way razor code formatting produces a far better result. Here are the before and after cases:
BEFORE
AFTER
I work with VS2017 15.9.2 and still have the problem.
After change the editor settings to use spaces instead of tabs, the behavior in editing (e.g. copy - paste code lines) is way better, but "Format Document" still add wrong indents by every call.
No solution, but a short update:
It seems as the issue is solved partial in Visual Studio 2019 version 16.0 Preview 2.1
Link to MS for the issue
Further short update:
I have found a (bad and ugly) workaround (to write the whole code to a razor control in ONE line.
You can find the details here Workaround to wrong indentation Razor Controls
You might want to try Improvements to the new Razor editor in Visual Studio - it has greatly improved the formatting quality (still imperfect, though).
I recommend you prevent automatic formatting to trigger by commenting the piece of code where you paste. This way things don't get broken on paste.

What's with "The following line works around an ASP.NET compiler warning" in MVC Views?

I did a quick search on SO for this and didn't come up with anything.
Doesn't
<%-- The following line works around an ASP.NET compiler warning --%>
<%: ""%>
seem like a bit of a hack?
what's the point of this, and is the MS Dev Team doing anything to work towards a resolve?
There is a writeup in the ASP.NET forums about this. Without that line, you might get compiler warnings that look something like "__o is not declared". This work around prevents those from ever appearing.
From the asp.net forums...
ASP.NET Forums
We have finally obtained reliable
repro and identified the underlying
issue. A trivial repro looks like
this:
<% if (true) { %>
<%=1%>
<% } %>
<%=2%>
In order to provide intellisense in <%= %> blocks at
design time, ASP.NET generates
assignment to a temporary __o variable
and language (VB or C#) then provide
the intellisense for the variable.
That is done when page compiler sees
the first <%= ... %> block. But here,
the block is inside the if, so after
the if closes, the variable goes out
of scope. We end up generating
something like this:
if (true) {
object #__o;
#__o = 1;
}
#__o = 2;
The workaround is to add a dummy
expression early in the page. E.g.
<%="" %>. This will not render
anything, and it will make sure that
__o is declared top level in the Render method, before any potential
‘if’ (or other scoping) statement.

Add OnClick Event to Html.RadioButton

What I want to do is to call a JavaScript routine when the user clicks on a radiobutton. I've some fields to enable/disable when this happens. However, when I enter
<%=Html.RadioButton("obp17", "57", ViewData.Eval("obpValue17").ToString().Equals("57"), new {#onclick = "Yes()"})%>
I'm getting a "type or with" expected error when trying to add the onlick event. This should be easy, but none of samples I've found seem to work. The leading "#" is common in all the examples I've found, but something else seems to be missing.
And yes I know the way of checking for "true" is overkill, but it is created with a special purpose code generator, so it wasn't any extra work.
Any thoughts?
Pardon me for causing anyone problems. My problem was ultimately caused by delete the first line of the ASCX file that inherits "System.Web.Mvc.ViewUserControl" Once I put that in, all the problems went away.
The line of code that worked was
<%= Html.TextBox("obpt9",ViewData.Eval("obpt9"), new { onclick = "alert('hi')" })%>
Different line than sample, but they are all the same.
Again, sorry for causing anyone confusion.
tom
Is the page language VB or C#? If it's VB your syntax is wrong for creating the anonymous typed html attributes. See this MSDN reference on how to create an object with an anonymous type in VB.
<%=Html.RadioButton("obp17",
"57",
ViewData.Eval("obpValue17").ToString().Equals("57"),
New With { .onclick = "Yes()" } ) %>
Or change the page language to C#, if that's more appropriate.
Also, note that you could (arguably should) simply give the radio button a class, then add all the handlers at one time with jQuery. Usually you want to keep your javascript separate from your mark up.
<%=Html.RadioButton("obp17",
"57",
ViewData.Eval("obpValue17").ToString().Equals("57"),
New With { .class = "heinz" } ) %>
<script type="text/javascript>
$('.heinz').click( function() {
... implement the logic of Yes() here ...
});
</script>
The general structure Looks like the following:
#Html.RadioButtonFor(t => t.ViewModelVariableName,"RadioButtonValue", new {javascriptEvent = "javascriptMethodName"});
Do you have Yes() function correctly defined in your code ? Replace Yes() to the javascript alert() function ; if that works, then the line of code you posted is OK.
Also, please post Yes() function here, and I think there may be some error there.

Resources