微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ResolveClientUrl在ASP.Net 4和3.5中的工作方式不同

[抱歉,如果我的问题标题不能准确描述我的问题 – 如果你能想到一个更好的标题并有权更改它,那么请随时改变它!].

我认为我偶然发现ASP.Net 3.5和4.0之间的细微变化.

[编辑:我已经确认twix 3.5和4.0的行为发生了变化 – 请参阅我的回答]

这是场景: –

我有一个ASP.Net 3.5 Web应用程序.
我有一个简单的用户控件{appRoot} /Controls/Widgets/MyPictureAndTextWidget.ascx,它基本上包含一些文本和另一个用户控件({appRoot} /Controls/Widgets/MyPicture.ascx).

在大多数情况下,此控件以正常方式使用 – 即将其包含在其他页面标记中,但我有一个实例,我需要使用Ajax获取要在客户端上呈现的HTML.

我实现这一目标的方法是编写一个asmx Web服务,以编程方式创建一个新的页面并动态地“LoadControl”用户控制,然后从字符串构建器中的页面呈现中捕获输出 – 特别是不优雅但它有效!请参见底部的来源.

但是,在将项目升级到Asp.Net 4.0之后,上面的代码不再像过去那样工作了;渲染时的图像有src =“../ images / xxx.png(注意不需要的’../’).

如果你想为自己运行它,我已经创建了一个小的演示应用程序http://cid-916198839f3e806c.office.live.com/self.aspx/Public/TestingImageWTF.zip.当您使用3.5编译应用程序时,它可以工作(即您在测试页面上看到2张蜘蛛图片)但是当您在4.0下编译并运行时,您只能看到1个蜘蛛(另一个图像的URL错误).

我能想到的唯一解释是ResolveClientUrl方法(Image控件将使用该方法来计算当前正在执行的页面中图像的相对路径)的行为方式不同.图像URL显示为“../ images/xxx.png”这一事实意味着图像控件“认为”它正在一个页面中执行,该页面在运行时具有类似“{appRoot} / folder / handler”的路径4.0以下,但它认为它在3.5下的上下文'{appRoot} / handler’中运行.

我希望这对你有意义 – 抱歉,如果我没有非常清楚或简明地描述问题.

任何人都可以告诉我们如何: –

>恢复3.5行为(显然没有恢复到3.5框架!)
>或者首先在Web服务中生成HTML的更好方法是什么?

来源

完整的测试应用程序可以从这里下载http://cid-916198839f3e806c.office.live.com/self.aspx/Public/TestingImageWTF.zip

网络服务

[WebMethod]
    [ScriptMethod]
    public string GetWidgetHtml(int number)
    {
        var pageHolder = new Page
                             {
                                         //AppRelativeVirtualPath = "~/" // I tried playing with this but it made no difference!
                             };
        for (int i = 0; i < number; i++)
        {
            var viewControl = (MyPictureAndTextWidget) pageHolder.LoadControl(@"~/Controls/Widgets/MyPictureAndTextWidget.ascx");
            pageHolder.Controls.Add(viewControl);
        }

        var output = new StringWriter();

        HttpContext.Current.Server.Execute(pageHolder,output,false);

        StringBuilder sb = output.GetStringBuilder();
        string fulloutput = sb.ToString();
        return fulloutput;
    }

以下是我的用户控件的内容

控制/小工具/ MyPictureAndTextWidget.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyPictureAndTextWidget.ascx.cs" Inherits="TestingImageWTF.Controls.Widgets.MyPictureAndTextWidget" %>
    <%@ Register TagName="Picture" TagPrefix="widget" Src="~/Controls/Widgets/MyPictureWidget.ascx" %>

    <div style="background:#EEEEEE; border:1px dashed;">
        <h4>My control</h4>
        Some text from the widget ....: 
        <br /><widget:Picture runat="server" />
    </div>

控制/小工具/ MyPictureWidget.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyPictureWidget.ascx.cs" Inherits="TestingImageWTF.Controls.Widgets.MyWidget" %>

    <script runat="server">
        protected void Page_Load(object sender,EventArgs e)
        {
            image.ImageUrl = "~/images/spider.png";
        }
    </script>
    <asp:Image ID="image" runat="server" />

解决方法

o如果答案是这里至少部分.

问题:ResolveClientUrl在ASP.Net 4和3.5中的工作方式是否有所不同?

答:是的.

行为的变化(我所知道的)是它以不同的方式对待PathInfo.

要演示,请进行以下页面.

<%@ Page Language="C#" AutoEventWireup="true"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
    <form id="form1" runat="server">
        DateTime.Now.Ticks: <%= DateTime.Now.Ticks %>
        <br />
        <asp:HyperLink runat="server" NavigateUrl="~/PathInfoLinkTest.aspx">This links to ~/PathInfoLinkTest.aspx</asp:HyperLink>
        <br />
        <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/PathInfoLinkTest.aspx/foo/bar">This links to ~/PathInfoLinkTest.aspx/foo/bar</asp:HyperLink>
        <br />
        ResolveClientUrl("~/PathInfoLinkTest.aspx/foo/bar") = <%= ResolveClientUrl("~/PathInfoLinkTest.aspx/foo/bar") %>
    </form>
</body>
</html>

并在.Net4和.Net 3.5下运行.

你会看到3.5以下:
ResolveClientUrl(“〜/ PathInfoLinkTest.aspx / foo / bar”)=’PathInfoLinkTest.aspx / foo / bar’

而在4.0以下你得到
ResolveClientUrl(“〜/ PathInfoLinkTest.aspx / foo / bar”)=’bar’

这些变化似乎是一个错误修复,以回应这些人所遇到的问题.

> http://channel9.msdn.com/Forums/TechOff/256519-Am-I-crazy-here-but-there-appears-to-be-an-oversight-in-ASPNET
> http://forums.asp.net/t/1138135.aspx/1

本质上,3.5中的错误是,如果您当前正在浏览网址http://host/app/page.aspx/foo/bar并且您想要链接到http://host/app/page2.aspx,那么客户端上呈现的URL应为../../page2.aspx.

Asp.Net 4得到了正确的答案!Asp.Net 3.5没有 – 它将链接的URL输出为’page2.aspx'(因此,当点击时,浏览器将请求页面’http://host/app/page.aspx /foo/bar/page2.aspx’.如果您在.Net 3.5中运行上述页面并多次点击第二个超链接,您可以看到此错误的表现形式 – 然后查看浏览器的地址栏!

不幸的是,错误修复破坏了我的代码 – 因为我的代码依赖于.Net 3.5的(不正确的)行为:Web服务请求始终具有Pathinfo(Web服务方法名称),因此当控件呈现自身时,调用ResolveClientUrl( “〜/ xxx”)(正确)put返回“../xxx”.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐