Anton Palyok
Anton Palyok

Reputation: 1549

ASP.NET MVC Html Helper doesn't render attribute ID when name starts with a number

I found some strange behavior of HTML helpers for me.
It works fine in MVC 1
But have a problem in MVC 2 and MVC 3

So, I have next layout:
in MVC 2:

<%= Html.Hidden("123Test", "Without ID") %>
<%= Html.Hidden("Test123", "With ID") %>

or in MVC 3:

@Html.Hidden("123Test", "Without ID")
@Html.Hidden("Test123", "With ID")

They both generates next markup:

<input name="123Test" type="hidden" value="Without ID" />
<input id="Test123" name="Test123" type="hidden" value="With ID" />

As you can see when name starts with number then ID would not be rendered.

So my question: is there exists some setting that switch off this behavior?
Or it can be addressed to MVC developers?

Upvotes: 0

Views: 717

Answers (1)

Russ Cam
Russ Cam

Reputation: 125498

They are using the HTML 4.01 specification that states that an id cannot start with a number

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

The offending code is the CreateSanitizedId() method on TagBuilder

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

public static string CreateSanitizedId(string originalId, string invalidCharReplacement) {
    if (String.IsNullOrEmpty(originalId)) { 
        return null;
    }

    if (invalidCharReplacement == null) { 
        throw new ArgumentNullException("invalidCharReplacement");
    } 

    char firstChar = originalId[0];
    if (!Html401IdUtil.IsLetter(firstChar)) { 
        // the first character must be a letter
        return null;
    }

    StringBuilder sb = new StringBuilder(originalId.Length);
    sb.Append(firstChar); 

    for (int i = 1; i < originalId.Length; i++) {
        char thisChar = originalId[i]; 
        if (Html401IdUtil.IsValidIdCharacter(thisChar)) {
            sb.Append(thisChar);
        }
        else { 
            sb.Append(invalidCharReplacement);
        } 
    } 

    return sb.ToString(); 
}

This would need addressing to allow this when using HTML 5 proposed specification, which will allow an id to start with a number

The id attribute specifies its element's unique identifier (ID). The value must be unique amongst all the IDs in the element's home subtree and must contain at least one character. The value must not contain any space characters.

Upvotes: 3

Related Questions