14

I want to conditionally render a readonly attribute in an <input>. In the ASP.NET Core dialect of Razor the interpretation of attributes is a little different opposed to System.Web.Mvc.

In System.Web.Mvc I used to do:

<input name="Name" class="form-control" @(Model.MyCondition ? "readonly" : "") />

In ASP.NET Core, the same does not work: no error, but the attribute isn't rendered either.

<input asp-for="Name" class="form-control" @(Model.MyCondition ? "readonly" : "" ) />

Once the attribute is present in the HTML it is enforced, so I cannot do something with the value of the attribute. This snippet would cause the input to always be read-only:

<input asp-for="Name" class="form-control" readonly="@(Model.MyCondition ? "readonly" : "" )" />

Now, I can work around by creating a tag helper that would respond to the is-readonly tag, but that seems very convoluted for something so simple.

How do I conditionally render a no-value attribute without resorting to a custom tag helper?

2
  • I test in razor page it works on my side , when MyCondition is true it shows the readonly attribute , could you please share the steps to reproduce ? Commented Apr 25, 2019 at 6:20
  • Here's a link to an answer of mine that solves the same problem, just omit the value part. Commented Mar 30, 2022 at 7:06

3 Answers 3

17

If you set the value to null when your condition isn't matched (instead of an empty string) then the attribute will not be rendered, as follows:

<input asp-for="Name" class="form-control" readonly="@(Model.MyCondition ? "readonly" : null )" />
Sign up to request clarification or add additional context in comments.

6 Comments

This does not seem to work for me. It still renders the "readonly" attribute without a value
This definitely works for me with ASP.NET Core 3.1; I even inspected the raw source to confirm. That said, I was using the disabled value instead of readonly (but they should work the same). I was also using the asp-for attribute, if that makes any difference.
@Pluto This is strange because any attribute="@(nullValuedVariable)" renders attribute="" for me in .net core 3.1 mvc.
this worked perfect in .net core 7 + MVC thx!
|
0

What I do is create an @if statement. I find it more transparent.

@if (Model.MyCondition)
{
  <input asp-for="Name" class="form-control" readonly="readonly" />
}
else
{
  <input asp-for="Name" class="form-control" />
}

4 Comments

I get you got downvoted because this doesn't answer the question exactly, but this is a simple way to accomplish what I needed and I was blinded by trying to force conditional attributes to be the solution like other front-end frameworks support when ASPNET Razor never had that feature as a first class citizen and everyone's answer is just an ugly hack.
I don't understand your downvote if my solution accomplishes what you needed. It might not be the way you wanted, but I'm not a mind reader to know your preferences, I was just trying to help you achieve your goal.
I did not downvote, but I saw your answer had some and I was explaining why I thought it did. I actually upvoted you.
Then, my bad, sorry for the misunderstanding.
0
@{
    var htmlAttributes = (MyModel.MyCondition == true) ? (object)new
    {
        @@readonly = "readonly"
    } : null;
}

@Html.TextBoxFor(m => m.Nom,  htmlAttributes)

Comments

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.