How to get the generated Unique ID prefix for a page's controls

As we know, ASP.NET WebForms will generate a Unique ID (as well as name) to a control to prevent collisions in the control heirarchy. Let's say we have a TextBox control with an assigned ID of "MyTextBox" in the markup. If this textbox is on a page with a Master Page then the TextBox control will be given a Unique ID of "ctl00$MainContent$MyTextBox" or something similar.

What I want to know is, for a given page, is it possible to know what the prefix WILL BE? In my above example I would like to know all controls I create on that page will be assigned with a prefix of "ctl00$MainContent$". I have examined the Page object and I cannot find an easy way to extract this information. Note: inspecting already existing controls on the page (like the TextBox) isn't an option. I simply need to know, at run time, what the prefix would be.

-- EDIT: Why do I need to do this? --

Ultimately I am trying to solve the problem that this post illustrates:

ASP.NET 4.5 TryUpdateModel not picking Form values in WebForm using Master-Page

I'm using the ModelBinding features introduced in ASP.NET 4.5. Problem is, as the above post points out, is that the name value collection found in the form will NOT match up with your model's properties. The built-in FormValueProvider expects a one-to-one match with the form key (name) and the model's properties. Unfortuantely, the form's keys will have the typical "ctl00$MainContent$" prefix to the names.

I have a semi-working solution where I created a custom IValueProvider that compares the end of the form key with the model's property. This works 95% of the time, but there's always a chance of multiple hits.

Ideally, and this is what I'm trying to figure out, if I could determine WHAT the prefix is I can then prefix that the IValueProvider's passed in key, look for that in the form and find the exact match.

So that is why I'm wondering if there's any way to know what the prefix should be for a given page.

1 answer

  • answered 2021-02-20 22:40 Albert D. Kallal

    The real answer is to simply code in such a way that you never have to know this information. that might not always be easy - but that's quite much what we do. You can certainly in code behind get/grab the "id" of the given button.

    so for example, I become VERY tired of having to wire up a little toast message all over the place. So, I put in a little js routine (in the master page).

    But I did need the client ID of a given control.

    Well, the code behind needed (wants) to place the toast message next to whatever I clicked on.

    So my server side "toast" message caller of course will after the server side code is done does the common "script" inject that will run when the page finally makes it final trip back down to the browser, displays the page, and then of course runs that script I injected.

    So, my server side code does this:

    MyToast2(Me, btnUpdate.ClientID.ToString, "Update ok!", "Settings changed")

    So note how I get/grab/pass the "ID" of the control that the server is going to render. You can use ClientID to get the the final "ID" used for that control in code behind.

    So, that btnUpdate is just a simple button placed on the web form. But who cares what super ugly "ID" the server assigns. i just need the "id" of the control so the JavaScript client side can pick up that control - and thus know/get/have the position of the control, and thus I get this result:

    enter image description here

    Or if I am some place else - again I can call that js routine - and that routine needs the current control. so might have this:

    enter image description here

    So, I can now just call a routine and pop up a message - not have to write any new js code for the gallzion notices and little pops I have all over the place.

    so the little javaScript routine of course does this:

      function toastcallm(cntrol, h, t, d) {
                var cmd = $('#' + cntrol);
                var mypos = cmd.position();
       bla bla bla

    But only important was that I get/determine and pass the used server "client" id to that routine - I don't really care what it is , or how to see, or how to list them out. I suppose a better jQuery selector or using wild card might work - but I really don't want to know the control ahead of time - but only that I can get the clientID used when I need it.

    I simply write code that assumes somewhere along the way when I need such a client id, I simply get it and use it.

    So, on the server side? Well, we always build and write code based on the control ID, but you want to get your hands on the actual id? Then you can use in the server code behind:

     (ie: somecontrol.ClientID).