Why doesn't Visual Studio code formatting work properly for Razor markup? - asp.net-mvc

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.

Related

Going from Webforms to MVC 4

So I'm converting a WebForms application into ASP.NET MVC 4 and I would like to make sure that I'm making correct coding choices and assumptions.
1). Is the MVC equivalent of a user control a partial view?
2). In an aspx page you have a control like
<asp:Label id="X" runat="server">
with the following code in the code behind:
X.Visible = some_condition ? true : false;
Ok so, for MVC is this code equivalent?
View:
<label id="X" style="display: #Model.IsViewable">
Model:
IsViewable = some_condition ? "inline-block" : "none";
1.) Well, kinda, sorta, but no not really. Very different things - a detailed explanation would be lengthy.
2.) Equivalent maybe, but not really a good thing to do. Your model should contain data only. But yes, you can use this data in your razor views to conditionally do things including show or not show things. However, putting the css strings straight into your model data is klunky at best as well as it's usually a good idea to avoid inline styles whenever possible. IsViewable as a boolean would be better, and you can still handle showing or hiding elements (in a different way).

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(...))"

How can I make code indentation behave correctly in vbhtml razor files?

This is driving me round the bend. I'm a long time VB.NET forms developer, quite new to ASP.NET and completely new to MVC. I'm creating vbhtml pages that use the VB.NET Razor syntax, and I seem to be constantly fighting against the UI which is trying to indent my code incorrectly. Take the following example, based on the template page for a new Razor view:
#Code
Layout = Nothing
End Code
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>
#If True Then
#<ul>
#For x = 1 To 2
Next
</ul>
End If '<-- Randomly indented too far
</div>
</body>
</html>
In the above example, as soon as I hit return after Next, End If two lines below randomly jumps two tabs forward from where it should be. In other examples I've hit a circle where pushing one line to the correct place throws another line out of position and vice versa.
I'm so annoyed at this point I'd be happy to disable auto-indentation completely and just manage it myself, but I can't even find out how to do that! Following advice on another thread I disabled indentation for HTML pages but all that stops is indentation of HTML tags - the code blocks still slide around all over the place.
I thought an extension might be causing the problem but I disabled them all and restarted and the problem remains. Am I doing something fundamentally wrong? I find it hard to believe Microsoft would release something so poor so it seems more likely I'm just not using it right.
I found a solution (of a fashion) on another question (I really did search hard before posting this question and couldn't find anything): Why doesn't Visual Studio code formatting work properly for Razor markup?
Essentially the solution seems to be to ensure that your code uses spaces instead of tabs for the whitespace. Whilst increasing the overall size of the page because of increased whitespace, it does lessen the problem (whilst not eliminating it completely). On the linked thread, someone who appears to be connected with Microsoft has acknowledged it is indeed a bug related to the overlapping formatters for HTML and VB.NET which they hope to improve in a new release. I've dropped to 2 spaces per indent to lessen the bandwidth impact.
Thanks to the guys who contributed.
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!

Collapse C# block within cshtml and save it

We have a bit big blocks of C# code within our cshtml files which must be presented in cshtml and nowhere else (obviously it's not a brilliant case but it's another question).
How we can collapse or hide these blocks of code in order to let our designers work more smoothly? We also want to hide these blocks of code during the demos of the progress with markup.
The real issue is that we also must save the visual representation into SVN.
Is there any native VS 2010 functionality for this or plugin? Maybe there is an opportunity to use "partial" cshtml pages where all the markup will be in one file and all C# code will be in another?
Unfortunately VS isn't going to collapse C# blocks of code within #region directive in such files.
Ultimately there is a similar question Regions In ASP.NET Views? but it gives no answer on how to save the collapsed representation when "Collapse Tag" context menu action item was used.
Try using Visual Studio's collapse functionality. By default I believe the keys are:
[Ctrl+M,Ctrl+H] to hide an arbitrary selection, and
[Ctrl+M,Ctrl+U] to unhide the same ( while collapsed ).
This should allow you to temporarily hide any code. More details available on MSDN
Is this what you were looking for?
Having read a little further you wish to save them collapsed, and apparently .cshtml doesn't support #regions. I guess a hacky solution might be the old:
#if(false){
<div>
<!--/*{your long code}*/-->
</div>
}
Or something to that effect, but you get the idea :)
Just select your code, right click and select Collapse Tag
The way that I see it is that cshtml files are meant for a "user control" side of a presentation layer. If you have too much code in your view files, then I would refactor the code and move re-usable components into partial views. I would then include these partial views through
#Html.RenderPartial("PartialViewName", Model.propertyToRender), or I would use
#{ Html.RenderAction("ActionName", "ControllerName") ;}

Does Razor syntax provide a compelling advantage in UI markup?

I notice Scott Guthrie is starting to mention Razor a fair bit on his blog but I'm just not that sure that it's a good fit for my style.
Granted it's a fairly unfamiliar style for someone who's pretty used to a "standard" sort of ASP.Net markup (content place holders and inline code), but it just feels like a lot of additional pages to manage and less clear markup to me.
What are other peoples' feelings on it? Is it something that you believe should be seriously considered when scaffolding new MVC pages or is it just trying to solve a problem that doesn't exist?
[Disclaimer: I'm one of the Microsoft developers on MVC and Razor, so I might be a bit biased :)]
We designed Razor to be a concise templating language that uses only the minimal necessary amount of control characters. I would say that large parts of your views can be expressed with fewer characters than the same code using the "traditional" WebForms syntax.
For example the following code snippet in ASPX syntax:
<% if(someCondition) { %>
<ol>
<% foreach(var item in Model) { %>
<li><%: item.ToString() %></li>
<% } %>
</ol>
<% } %>
Can be expressed as follows in Razor:
#if(someCondition) {
<ol>
#foreach(var item in Model) {
<li>#item.ToString()</li>
}
</ol>
}
While the ASPX version has 21 transition characters (the <% and %>), the Razor version has only three (#)
I would say that the advantages of Razor are as follows:
Concise syntax, which is very similar to the way you write regular C# code (check out the following recent blog post by Phil Haack comparing Asxp with Razor syntax: http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx)
Automatic HTML encoding of output (which helps protect you from html injection attacks)
Built in (though not 100%) validation of your markup which helps you avoid unbalanced tags
The page-related concepts also map easily from what you have in ASPX
As you can see inline code is still allowed
Sections (which can be optional) are equivalent to content placeholders
Layout pages instead of Master pages
The concepts of full and partial views are the same
#functions { ... } blocks instead of <script runat="server"> ... </script>
In addition Razor has a number of useful concepts that I would say are better than what is available in ASPX:
#helper functions for really easy creation of functions that emit markup
#model keyword for specifying your view's model type without having to write a <%# Page ... directive with the full class name
I would like to think that we have tackled a real problem, which is to allow you to more easily write concise and standards-compliant views while at the same time providing you with ways to refactor common code.
Of course, not everyone will prefer the syntax which is why we are also fully supporting the ASPX view engine. In addition you can check out Spark and NHaml, which are two 3rd-party view engines that enjoy significant community following. The following blog post has a good comparison of the different offerings: Link
Personally I really appreciate the reduction in how many escape characters are used. Using <% %> gets very tedious when compared to #{} and is not nearly as syntactically appealing.
Moreover, writing a whole definition for the codebehind and page is simplified to a single #model model.
As also noted by marcind, not having to always include runat=server is very nice also.
Overall, I really appreciate using the Razor engine and find it not only makes things easier on me to develop but also makes code easier to read.

Resources