input name and id changes when set runat=server

2019-01-09 11:50发布

问题:

In my form I need to insert different inputs of type "text". The inputs must be html controls with name and id's. Because I send this form to a external url.

For the validation I do runat=server in all inputs and then I can use requiredfieldvalidator.

But the problem is when I look in the source after visiting the page the name and id's are all changed. for example

<input id="first_name" class="formright" type="text" name="first_name" runat="server" />

changes to

<input name="ctl00$cphContent$first_name" type="text" id="ctl00_cphContent_first_name" class="formright">

I have to use html controls because the external postbackurl looks at the name and id values to find the control. So I can't use asp controls. It is because of that I used html controls with runat=server

I appreciate any help

回答1:

This is because you're using MasterPages.

Controls contained within a content page take on a dynamic ID based on the Master Page hierarchy in order to avoid duplication of IDs.

If you need to reference the control IDs and names in client-side script, you can use <%= first_name.ClientID %>.

If you're using .NET4 you can use ClientIDMode="Static" to make the generated IDs consistent, although this comes with its own ID-conflict caveats when, for example, using multiple instances of the same user control on a page. Rick Strahl outlines those here.

However, if you're using ASP.NET validators then everything should be fine. Instead of using an HTML input you should use an ASP.NET TextBox control:

<asp:TextBox id="first_name" runat="server" CssClass="formright" />


回答2:

ClientIDMode="Static"

This usefully locks the ID of any runat="server" control, however it does not lock the 'name' attribute of a html input element.

Seeing in this instance the only reason to have the runat="server" attribute on the input is to use .Net validation, I would suggest using an external JS library such as jQuery to handle this.

If however, like me, you need to alter the value attribute, the only work around I can see is a rather messy one. If you remove the runat="server" from the input, you can place a server control, such as a literal, within the value="" attribute.

For example:

<input id="first_name" class="formright" type="text" name="first_name" value="<asp:Literal id="litFirstNameValue" runat="server" />"  />

Please don't have a go at me for such bad coding practises, it's intended as a last resort workaround to keep the name attribute from changing to a .Net style name.

Does anyone else know of another way to fix the name? (The form element is not defined as runat="server", but it's embedded within the normal .Net form, which is why the server is attaching it to the main form tree)



回答3:

ClientIDMode only affects IDs. if you also need to manage name attribute then it's useless. In my case I solved this on the client side with jQuery.

$(function(){

    $("#inputname").prop("name",$("#inputname").prop("id"));

});


回答4:

Add ClientIDMode="Static" to the control, e.g.

<asp:TextBox ID="first_name" runat="server" ClientIDMode="Static" />

This is new feature in .NET 4. Official documentation.



回答5:

You can do validation in the asp page:

 <asp:Label runat="server" AssociatedControlID="txtFullName" CssClass="hidden"></asp:Label>
        <asp:TextBox runat="server" ID="txtFullName" CssClass="user" MaxLength="25"></asp:TextBox>
        <asp:RegularExpressionValidator
            ID="regFullName"
            runat="server"
            CssClass="has-error"
            ControlToValidate="txtFullName"
            ValidationExpression="[a-zA-Z-'\s]+"
            ValidationGroup="ValidationGroupName"
            Display="Dynamic"
            OnServerValidate="regFullName">
        </asp:RegularExpressionValidator>

If you want to validate in JS you can try this answer: How can I access runat="server" ASP element using javascript?

Or if you want to use this id in client side do it like this:

protected override void OnPreRender(EventArgs e)
{
    first_name.ClientIDMode = ClientIDMode.Static;
}


回答6:

Here is the same answer as @saplumbaga but in pure Javascript :

  • This fix every inputs :

    window.addEventListener("load", function () {
        var fix = function(el) { el.setAttribute("name", el.getAttribute("id")); };
        var els = document.getElementsByTagName("input");
        for (var i = 0; i < els.length; i++) {
            fix(els[i]);
        }
        els = document.getElementsByTagName("select");
        for (var i = 0; i < els.length; i++) {
            fix(els[i]);
        }
        els = document.getElementsByTagName("textarea");
        for (var i = 0; i < els.length; i++) {
            fix(els[i]);
        }
    });
    
  • For a single input :

    window.addEventListener("load", function () {
        var el = document.getElementById("MyID");
        el.setAttribute("name", el.getAttribute("id"));
    });