Search code examples
razorasp.net-coreasp.net-core-mvctag-helpersasp.net-core-tag-helpers

Why Is My Razor Code Not Working With Tag Helpers in ASP.NET Core


My question up front is why will razor syntax not work inside of a tag where I am using tag helpers? It is something I can work around and a solution to the problem has been answered HERE, but I still have not been able to find out why this problem occurs.


As an example of this I have a select tag that I am trying to add a disabled attribute to only if the model has a certain property. Here is the html:

<select 
  @(Model.Id != 0 ? "disabled" : "") 
  asp-for="QuestionType" 
  asp-items="Html.GetEnumSelectList<Enums.QuestionTypes>()" 
  id="form-type" data-parsley-required class="form-control">
</select>

Using Razor inside of the select outputs the following

<select 
  asp-for="QuestionType" 
  asp-items="Html.GetEnumSelectList<Enums.QuestionTypes>()" 
  id="form-type" data-parsley-required="" class="form-control">
</select>

Not using Razor gives this

<select 
  id="form-type" data-parsley-required="" class="form-control" 
  data-val="true" data-val-required="The QuestionType field is required." 
  name="QuestionType">
  <option selected="selected" value="0">Drop Down</option>
  <option value="10">Free Response</option>
</select>

While using Razor syntax, it seems to ignore the tag helpers and does not build the HTML as it should (or as is expected). However, using razor inside of attribute values seems to work fine, it's when I use it to try and add things like tag attributes that I get these issues. As stated before, I am just trying to understand why this is happening.


Solution

  • You cannot use a Razor expression inside a tag itself, only within the quotes of an attribute. I'm actually surprised it didn't raise an exception, but it seems it simply opted to treat the tag as plaintext instead. Regardless, you need to do something like the following instead:

    <select 
      disabled="@(Model.Id != 0 ? "disabled" : null)"
      asp-for="QuestionType" 
      asp-items="@Html.GetEnumSelectList<Enums.QuestionTypes>()" 
      id="form-type" data-parsley-required class="form-control">
    </select>
    

    If the value of an attribute is null, Razor will remove it, so you'll end up with disabled="disabled" if Model.Id is not equal to 0, and no disabled attribute at all if it is. You don't need to do anything crazy like the answers in the linked question suggest.

    EDIT

    Thinking about it more, I think it only went through because you broke the tag into multiple lines, so basically Razor treated the surrounding tag as invalid HTML and honed in on the line it could parse (the ternary expression). I'd imagine if you put the tag in a single line, you would in fact get an exception. Either way, it's a syntax error.