2

So, I've been using MVC 3, Razor 1, and Web.Helpers 1 now for over a year, but recently moved to MVC 4, Razor 2, and Web.Helpers 2. I've noticed some strange things happening with any View that has inline code or web helpers within an HTML attribute. Namely, the code renders outside of the attribute.

Example 1 : (MVC 3, Razor 1, Web.Helpers 1)

<li class="@{ Write(0 == RowCount % 2 ? "even" : "odd"); }">

Would render as :

<li class="even">

or

<li class="odd">

Example 2 : (MVC 3, Razor 1, Web.Helpers 1)

<img alt="@item.PlanNumber" title="@item.PlanNumber" src="@{Html.RenderAction("GetHomeImage", new { street = (string)item.AddrStreet, photo = (string)item.ELEV1, type = (string)item.RecordType, plan = (string)item.PlanNumber, elevation = (string)item.PlanElevation, defaultImage = (string)item.HomeImage });}" border="0" style="padding:2px 2px 2px 2px;" />

Would render as :

<img alt="2473W" title="2473W" src="/Content/_gallery/homes/photos/17411WOODFALLSLANE_S.jpg" border="0" style="padding:2px 2px 2px 2px;" />

When I updated the site to MVC 4, Razor 2, Web.Helpers 2 I see the following

Example 1 renders as :

<lieven class="">

or

<liodd class="">

Example 2 renders as :

<img alt="2473W" title="2473W" /Content/_gallery/homes/photos/17411WOODFALLSLANE_S.jpg src="" border="0" style="padding:2px 2px 2px 2px;" />

I've been able to work around this by changing the HTML.RenderAction to HTML.Action so my code is now : (MVC 4, Razor 2, Web.Helpers 2)

Example 1:

string rowClass = (0 == RowCount % 2) ? "even" : "odd";

                    <li class="@rowClass">

Example 2:

<img src="@Html.Action("GetHomeImage", "FindYourHome", new { street = (string)item.AddrStreet, photo = (string)item.ELEV1, type = (string)item.RecordType, plan = (string)item.PlanNumber, elevation = (string)item.PlanElevation, defaultImage = (string)item.HomeImage })" border="0" style="padding:2px 2px 2px 2px;" alt="@item.PlanNumber" title="@item.PlanNumber" />

which renders both examples correctly, but I'm unsure as to why?

I would very much appreciate any information available which will help me find any other instances in our site, and make me feel a lot better about updating to MVC 4, Razor 2 and Web.Helpers 2.

5
  • Have you tried just using <li class="@{ 0 == RowCount % 2 ? "even" : "odd" }">? Commented Jan 29, 2013 at 15:54
  • Just a comment: MVC principal is to lean away from inline, procedural BS. I recommend rethinking your code to make it more OOP. Commented Jan 29, 2013 at 16:17
  • Also, you can do the even/odd thing in CSS. You don't have to hardcode this stackoverflow.com/questions/5080699/… Commented Jan 29, 2013 at 16:19
  • Unfortunately 25% of our users are on IE8 or less, so we can't take advantage of nth-child yet. I agree that inline code is against what MVC is supposed to be, but that's not gonna happan on our site :) perryhomes.com, mostly for legacy purposes. Commented Jan 29, 2013 at 16:27
  • the first suggestion of using class="@{ 0 == RowCount % 2 ? ...} returns an error code : "cannot be used as a statement" Commented Jan 29, 2013 at 16:31

2 Answers 2

3

Can't test it right now but try this :

<li class="@(0 == RowCount % 2 ? "even" : "odd")">

Notice the parenthesis instead of the braces.

Sign up to request clarification or add additional context in comments.

7 Comments

ok...that worked! but WHY? I don't like this answer...because I don't want to go through my site to find all @{} code in attribute tags and change them to @(). Did something change in the references of MVC?
Note: this worked for Example 1, but not example 2. I'm okay with changing HTML.RenderAction to HTML.Action becuase I believe it renders better in the stream, and I've already made that change. I would just like to find out why, HTML.RenderAction is behaving differently.
For example 2, I'd simply use @Html.RenderAction(...) rather than including it in a code block.
Using @Html.RenderAction(...) returns the error "Cannot implicitly return type 'void' to 'object'" without including it in a code block.
Got confused between Html.RenderAction and Html.Action, RenderAction displays the result directly into the response whereas Html.Action returns a string.
|
1

In response as to "why" the new @(....) syntax works, note that MVC4 included support for "conditional attributes.

See more info here: http://www.davidhayden.me/blog/conditional-attributes-in-razor-view-engine-and-asp.net-mvc-4

1 Comment

So it appears the main issue is the new conditional attributes feature in MVC4 returns a boolean or other non-string-type data, which can cause adverse effects on you page. It appears that the page was having an issue in both handling the string return from the HTML.RenderAction and the void type of the Action itself? Seems like a little vodoo magic work around but luckily I only have a few dozen conditional attributes throughout the site that will need to be changed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.