首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ResolveClientUrl在ASP.Net 4和3.5中的工作方式不同

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

Stack Overflow用户
提问于 2011-05-23 15:25:39
回答 3查看 4.1K关注 0票数 4

对不起,如果我的问题标题没有准确地描述我的问题--如果你能想到一个更好的标题,并且拥有更改这个标题的权限,那么请随时修改它!

我想我无意中发现了ASP.Net 3.5和4.0之间的一个小变化。

编辑:我已经确认行为Twix3.5和4.0有了变化--见我的答案

以下是情况:-

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

在大多数情况下,该控件是以正常方式使用的--即将其包括在其他页面的标记中,但我有一个实例,需要获得HTML,以便使用Ajax在客户机上呈现。

我实现这一目标的方法是编写一个asmx web服务,该服务以编程方式创建一个新的Page并动态地“`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下编译和运行时,您只看到一个蜘蛛(另一个图像有错误的URL)。

我能给出的唯一解释是,ResolveClientUrl方法(图像控件将使用该方法来计算当前执行页面中图像的相对路径)是不同的。图像url以“../映像/xxx.png”的形式出现,这意味着图像控件‘认为’它在一个页面中执行‘{appRoot}/文件夹/处理程序’这样的路径,但它认为它运行在3.5以下的上下文'{appRoot}/handler‘中。

我希望这对你来说是有意义的--如果我没有非常清楚或简洁地描述这个问题,我很抱歉。

有人能告诉我们如何:-

  • 恢复3.5行为(显然不恢复到3.5框架!)
  • 或一种在web服务中生成
  • 的更好方法?

来源

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

Web服务

代码语言:javascript
复制
    [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

代码语言:javascript
复制
    <%@ 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

代码语言:javascript
复制
    <%@ 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" />
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-08 17:31:43

oSo在这里至少有部分的答案。

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

答:

行为的变化(据我所知)是它对待PathInfo的方式不同。

若要演示,请创建以下页面。

代码语言:javascript
复制
<%@ 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中的错误是,如果您当前正在浏览url 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") (正确)会返回“./xxx”。

票数 5
EN

Stack Overflow用户

发布于 2011-06-03 03:47:06

我不确定对ResolveClientUrl方法的更新,但我知道它们更新了.NET 4.0到3.5之间控件的呈现方式。您可能需要尝试更新您的web.config以包括:

代码语言:javascript
复制
<pages controlRenderingCompatibilityVersion="3.5" />

退房:http://www.asp.net/learn/whitepapers/aspnet4/breaking-changes#0.1__Toc256770141

此外,您也可以尝试在web服务中使用RenderControl,如下所示:

代码语言:javascript
复制
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);

control.RenderControl(hw);
return sb.ToString();

Rick有一篇可能有用的文章:http://www.west-wind.com/weblog/posts/2004/Jun/08/Capturing-Output-from-ASPNet-Pages (可能有点过时.)

希望这能有所帮助!

票数 2
EN

Stack Overflow用户

发布于 2011-06-01 07:53:20

尝试从ImageUrl值中移除前导倾斜符号。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6099336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档