从呈现的控件 ID 中删除 ctl00$ContentBody$

发布于 2024-07-19 09:37:17 字数 469 浏览 6 评论 0原文

我对现有的应用程序进行了一些更改,该应用程序以前只是简单的 HTML 和 Javascript。 为了添加服务器端功能,我选择了 ASP.NET,并利用了母版页概念。 不幸的是,在一个巨大的 Web 表单上,控件 ID 全部被“ctl00$ContentBody$”前缀破坏。 我在所有 INPUT 控件上添加了 runat="server",这就是更改 ID 的原因。 现在 ID 已更改,Javascript(写得非常糟糕,我什至无法阅读,而且我对 JS 很有经验)完全损坏了。

那么,如何防止这些废话被渲染到 HTML 中呢? 我希望能够以某种方式创建一个继承 HtmlGenericControl 的类(我没有使用 Web 控件,我只是在每个输入标记上添加了一个 runat="server"),并以某种方式覆盖将此“容器 id”粘贴在的逻辑ID 和 NAME 属性的开头。 然后我可以使用 web.config 中的 tagMapping 进行全局更改。 这可能吗?

I made some changes to an existing application that was previously just straight HTML and Javascript. To add server-side functionality, I chose ASP.NET, and took advantage of the Master Page concept. Unfortunately, on one huge web form, the control IDs are all mangled with the "ctl00$ContentBody$" prefix. I tacked a runat="server" on all the INPUT controls which is what altered the IDs. Now that the IDs have been changed, the Javascript (which is so poorly written I can't even read it, and I'm quite experienced with JS) is completely broken.

So, how can I prevent this nonsense from being rendered into the HTML? I was hoping to somehow be able to create a class that inherits HtmlGenericControl (I am not using Web controls, I just tacked on a runat="server" to every input tag) and somehow override the logic that sticks this "container id" at the beginning of the ID and NAME attributes. Then I could use tagMapping in web.config to make the global change. Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

当梦初醒 2024-07-26 09:37:18

目前还算小小的安慰,但这个“功能”将在 Asp.Net 4.0 中得到修复。 您将获得可设置的 ClientID 属性。

除此之外,其他的反应都很好。
使用 <%= control.ClientID %>

或放入 JQuery 并使用 $("[id$='myId'])

或者,在您的输入标记上,不要放置 runtime='server'。您应该能够通过 Form 成员检索值(就像 。

或者,跳过 Asp.Net WebForms 并跳至 Asp.Net MVC,这使您可以完全控制生成的 HTML 标记。您必须更多地改变做事的方式,但这可能会更少 让你沮丧。

Small consolation for right now, but this "feature" will be fixed in Asp.Net 4.0. You will get settable ClientID property.

Other than that, the other responses are good.
Use <%= control.ClientID %>

or throw in JQuery and use $("[id$='myId'])

Or, on your input tags, don't put runtime='server'. You should be able to retrieve the values via the Form member (just like in traditional asp)

Or, skip Asp.Net WebForms and skip to Asp.Net MVC, which gives you complete control of the HTML markup that is generated. You have to change how you are doing things a bit more, but that might be less frustrating for you.

淑女气质 2024-07-26 09:37:18

我尝试了这段代码,由于某种原因它重新组织了整个页面:

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    Dim Html As New StringWriter()
    Dim Render As New HtmlTextWriter(Html)
    MyBase.Render(Render)
    writer.Write(Html.ToString().Replace("name=""ctl00$ContentBody$", "name=""").Replace("id=""ctl00_ContentBody_", "id="""))
End Sub

如果您想查看示例,请提交 URL

I tried this piece of code and for some reason it reorganises the entire page:

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    Dim Html As New StringWriter()
    Dim Render As New HtmlTextWriter(Html)
    MyBase.Render(Render)
    writer.Write(Html.ToString().Replace("name=""ctl00$ContentBody$", "name=""").Replace("id=""ctl00_ContentBody_", "id="""))
End Sub

If you wish to see the example ill submit the URL

泪痕残 2024-07-26 09:37:18

我知道没有办法删除控件 ID 前面的命名容器。 过去,我使用了一种方便的方法在 javascript 中查找此类 id,该方法遍历标签名称并使用正则表达式来匹配以 $realID 结尾的 ID,其中 realID 是我在标记中赋予控件的 id。 现在,我将使用 jQuery 使用如下选择器来实现此目的:

 $('[id$="realID"]')

基本上与我旧的便捷方法执行相同的操作,但它内置于框架中。

I know of no way to remove the naming container from being prepended to the control id. In the past I've used a convenience method to look up such ids in javascript that iterates through the tag names and uses a regular expression to match the one that ends with $realID, where realID is the id that I gave to the control in mark up. Now, I would use jQuery for this using a selector like:

 $('[id$="realID"]')

Which basically does the same thing as my old convenience method, but it's built into the framework.

羁绊已千年 2024-07-26 09:37:18

据我所知,由于您所说的原因,无法删除它们; 以确保它们是独一无二的。 我认为你有两个选择:

  1. 创建一个 JS 变量并将其添加到所有 JS 调用的前面,以便它查找正确的 ID
  2. 使用 <%= control.ClientID %>; 在你的 javascript 中,所以它使用新的 ID。

对于#1,如果您的任何输入位于任何其他服务器标记内,它将不起作用。 这很容易出现很多问题,所以如果可以的话我会选择#2。

2 取决于页面本身上的 javascript,或者如果 JS 是外部的,则您需要能够传入 ID。 该代码未经测试,仅作为示例,但这就是我的意思:

function alertValue(textID){
     alert(document.GetElementById(textID).value);
}

<input id="txtBox" runat="server" type="Button" text="Click Me" onClick="alertValue('<%= txtBox.ClientID %>');" />

这实际上取决于您的 JS 的实现方式。

As far as I know there is no way to remove them for the very reason you said; to ensure they are unique. The way I see it you have two options:

  1. Create a JS variable and prepend it to all of your JS calls so it looks for the correct ID
  2. Use <%= control.ClientID %> in your javascript so it uses the new ID.

With #1 if any of your inputs are within any other server tag it won't work. This is prone to many problems so I would go with #2 if you can.

2 depends on either the javascript being on the page itself or if the JS is external you need to be able to pass in ID's. This code isn't tested and is only for an example but here is what I mean:

function alertValue(textID){
     alert(document.GetElementById(textID).value);
}

<input id="txtBox" runat="server" type="Button" text="Click Me" onClick="alertValue('<%= txtBox.ClientID %>');" />

It really depends how your JS is implemented.

旧人 2024-07-26 09:37:18

由于您似乎只是尝试从最终输出中删除客户端 ID,因此您也许能够覆盖页面上的渲染事件并使用正则表达式来删除它们。 您可以在下面的帖子中看到一个示例。

重写 ASP.NET 页面输出

获得文本后与您合作很可能会编写类似...的内容

output = Regex.Replace(
    output, 
    @"id\=""ctl00\$[^\""]*""", 
    string.Empty, 
    RegexOptions.IgnoreCase
    );

,然后将最终输出写入 HtmlTextWriter。

希望有帮助。

Since it appears you're just trying to remove client ID's from the final output, you might be able to to override the render event on your page and use a Regular Expression to remove them. You can see an example in the post below.

Rewrite ASP.NET page output

After you get the text you're working with you could most likely write something like...

output = Regex.Replace(
    output, 
    @"id\=""ctl00\$[^\""]*""", 
    string.Empty, 
    RegexOptions.IgnoreCase
    );

And then write the final output to the HtmlTextWriter.

Hope that helps.

一江春梦 2024-07-26 09:37:18

伙计们,我需要的是快速而肮脏的东西。 感谢 HBoss,我能够想出一个非常简单的解决方案。 在相关页面的代码隐藏中,我刚刚添加了这个子例程......

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    Dim Html As New StringWriter()
    Dim Render As New HtmlTextWriter(Html)
    MyBase.Render(Render)
    writer.Write(Html.ToString().Replace("name=""ctl00$ContentBody$", "name=""").Replace("id=""ctl00_ContentBody_", "id="""))
End Sub

Quick and dirty was what I needed, folks. And thanks to HBoss I was able to come up with a very simple solution. On the code-behind of the page in question, I just added this subroutine...

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    Dim Html As New StringWriter()
    Dim Render As New HtmlTextWriter(Html)
    MyBase.Render(Render)
    writer.Write(Html.ToString().Replace("name=""ctl00$ContentBody$", "name=""").Replace("id=""ctl00_ContentBody_", "id="""))
End Sub
在你怀里撒娇 2024-07-26 09:37:18

检查一下:http://clientidless.codeplex.com/ - 您可以关闭几乎所有控件的 ClientID。
这是演示: http://show-demos.net/NoClientId/ - 按“不带 ID 渲染” ”或“使用 ID 渲染”以查看页面大小如何变化。 查看源代码以查看差异。

Check this: http://clientidless.codeplex.com/ - you can turn off ClientID to almost any control.
Here is demo: http://show-demos.net/NoClientId/ - press "render without IDs" or "render with IDs" to see how page size changes. View source to see the difference.

玩套路吗 2024-07-26 09:37:18

我想为此添加两分钱:

我这样做了(在接受的答案中),但认为重写渲染控件以写入新的 TextWriter,然后将其内容写入页面的 OutputStream 对我来说似乎是一种资源浪费。 我发现这可以通过创建一个小类来覆盖 HtmlTextWriter 类来完成。 通过这种方式,我们可以直接写入流,并且仅在将文本用作属性时尝试替换文本。

public class CleanHtmlTextWriter : HtmlTextWriter
{
    private const string MASTER_PAGE_ID = "ctl00";
    private const string CONTENT_NAME = "MainContent";

    public CleanHtmlTextWriter(TextWriter writer)
        : base(writer)
    {
    }

    public override void WriteAttribute(string name, string value)
    {
        if (name == "name")
            value = value.Replace(CONTENT_NAME + "$", "").Replace(MASTER_PAGE_ID + "$", "");

        if (name == "id")
            value = value.Replace(CONTENT_NAME + "_", "").Replace(MASTER_PAGE_ID + "_", "");

        base.WriteAttribute(name, value);
    }
}

然后你可以像这样使用它:

protected override void Render(HtmlTextWriter writer)
{
    base.Render(new CleanHtmlTextWriter(writer));
}

I'd like to add my two cents to this one:

I did it this way (in the accepted answer), but thought overriding the Render control to write to a new TextWriter and then write the contents of that to the Page's OutputStream seems like a waste of resources to me. I worked out that this can be done by making a little class to override the HtmlTextWriter class. This way we write directly to the stream and we only try to replace the text when it is used as an attribute.

public class CleanHtmlTextWriter : HtmlTextWriter
{
    private const string MASTER_PAGE_ID = "ctl00";
    private const string CONTENT_NAME = "MainContent";

    public CleanHtmlTextWriter(TextWriter writer)
        : base(writer)
    {
    }

    public override void WriteAttribute(string name, string value)
    {
        if (name == "name")
            value = value.Replace(CONTENT_NAME + "$", "").Replace(MASTER_PAGE_ID + "$", "");

        if (name == "id")
            value = value.Replace(CONTENT_NAME + "_", "").Replace(MASTER_PAGE_ID + "_", "");

        base.WriteAttribute(name, value);
    }
}

Then you can use it like this:

protected override void Render(HtmlTextWriter writer)
{
    base.Render(new CleanHtmlTextWriter(writer));
}
谈情不如逗狗 2024-07-26 09:37:18

实际上,为了借鉴乔希的答案,我发现下面的第一个解决方案存在其他输入控制元素和回发无法正常工作的问题。 因此,我没有进行空白更改,而是选择了下面的第二个解决方案来更改 JavaScript 而不是元素名称。

Josh 的解决方案

代码隐藏:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    StringWriter Html = new StringWriter();
    HtmlTextWriter Render = new HtmlTextWriter(Html);
    base.Render(Render);
    writer.Write(Html.ToString()
        .Replace("name=\"ctl00$ContentBody$", "name=\"")
        .Replace("id=\"ctl00_ContentBody_", "id=\""));
}

解决方案 1,存在回发问题(注意:我无法更改可能解决此解决方案的 ID):

代码隐藏:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    var html = new StringWriter();
    var render = new HtmlTextWriter(html);
    base.Render(render);
    writer.Write(html.ToString()
        .Replace("name=\"ctl00$contentBody$rbl",
                 "name=\"ctl00_contentBody_rbl"));
}

解决方案 2,更改 JavaScript:

aspx 文件中的 JavaScript,其中单选按钮列表使用约定“rbl[name]”:

if (!validateRadioButtonList("<% =rblTitle.ClientID %>"))

代码隐藏:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    var html = new StringWriter();
    var render = new HtmlTextWriter(html);
    base.Render(render);
    writer.Write(html.ToString()
        .Replace("validateRadioButtonList(\"ctl00_contentBody_rbl", 
                 "validateRadioButtonList(\"ctl00$contentBody$rbl"));
}

Actually to piggy back on Josh's answer, I found the first solution below to be problematic with other input control elements and PostBacks not working correctly. So rather than making a blank change I opted for the second solution below to change the JavaScript rather than the element name.

Josh's Solution:

Code-Behind:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    StringWriter Html = new StringWriter();
    HtmlTextWriter Render = new HtmlTextWriter(Html);
    base.Render(Render);
    writer.Write(Html.ToString()
        .Replace("name=\"ctl00$ContentBody$", "name=\"")
        .Replace("id=\"ctl00_ContentBody_", "id=\""));
}

Solution 1, with PostBack issues (NOTE: I could not change the ID which might resolve this solution):

Code-Behind:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    var html = new StringWriter();
    var render = new HtmlTextWriter(html);
    base.Render(render);
    writer.Write(html.ToString()
        .Replace("name=\"ctl00$contentBody$rbl",
                 "name=\"ctl00_contentBody_rbl"));
}

Solution 2, to change JavaScript:

JavaScript in aspx file where Radio Button Lists use the convention 'rbl[name]':

if (!validateRadioButtonList("<% =rblTitle.ClientID %>"))

Code-Behind:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
    var html = new StringWriter();
    var render = new HtmlTextWriter(html);
    base.Render(render);
    writer.Write(html.ToString()
        .Replace("validateRadioButtonList(\"ctl00_contentBody_rbl", 
                 "validateRadioButtonList(\"ctl00$contentBody$rbl"));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文