更改WebResource.axd的请求URL

9

我的网站应用程序(http://www.something.com/social/competition/)目前是这样请求WebResource.axd文件的:

<script src="/WebResource.axd?d=xxx" type="text/javascript"></script>

由于我们在Netscaler中使用urlrewiting,将所有对“/ social”文件夹的请求转发到包含此应用程序的单独服务器农场,因此“/”根路径将无法正确解析,因为它将从something.com应用程序请求资源。
因此,我需要更改所请求脚本的URL,以便明确请求:
<script src="/social/WebResource.axd?d=xxx" type="text/javascript"></script>

或者使用相对路径请求它:

<script src="WebResource.axd?d=xxx" type="text/javascript"></script>

到目前为止,我已经尝试了覆盖render方法、使用控制适配器和其他各种方法,但还没有取得什么进展。请帮忙。

1个回答

11

经过深入研究,结果发现几乎无法覆盖这些文件的呈现过程。因此,唯一的选择是使用肮脏、恶劣的Hack手段!

protected void Page_Load(object sender, EventArgs e)
    {
        //Initialises my dirty hack to remove the leading slash from all web reference files.
        Response.Filter = new WebResourceResponseFilter(Response.Filter);
    }

public class WebResourceResponseFilter : Stream
{
    private Stream baseStream;

    public WebResourceResponseFilter(Stream responseStream)
    {
        if (responseStream == null)
            throw new ArgumentNullException("ResponseStream");
        baseStream = responseStream;
    }

    public override bool CanRead
    {
        get { return baseStream.CanRead; }
    }

    public override bool CanSeek
    {
        get { return baseStream.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return baseStream.CanWrite; }
    }

    public override void Flush()
    {
        baseStream.Flush();
    }

    public override long Length
    {
        get { return baseStream.Length; }
    }

    public override long Position
    {
        get
        {
            return baseStream.Position;
        }
        set
        {
            baseStream.Position = value;
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return baseStream.Read(buffer, offset, count);
    }

    public override long Seek(long offset, System.IO.SeekOrigin origin)
    {
        return baseStream.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        baseStream.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        //Get text from response stream.
        string originalText = System.Text.Encoding.UTF8.GetString(buffer, offset, count);

        //Alter the text.
        originalText = originalText.Replace("/WebResource.axd", "WebResource.axd");
        //Write the altered text to the response stream.
        buffer = System.Text.Encoding.UTF8.GetBytes(originalText);
        this.baseStream.Write(buffer, 0, buffer.Length);

    }

这个代码截获了页面的流并将所有出现的 "/WebResource.axd" 替换为 "WebResource.axd"。由于它是相对路径,所以解析非常好!

我想到了另一个解决方法,需要将Web应用程序安装到模拟 "/social" 关键字重定向的虚拟目录中。这将导致asp.net更新 HttpRuntime.AppDomainAppVirtualPath 以在页面上的引用中包含 "/social" 并因此正确解析。

大喊一声!


2
原始文本 = originalText.Replace(HttpContext.Current.Request.ApplicationPath+"/", VirtualPathUtility.MakeRelative(HttpContext.Current.Request.Url.AbsolutePath, "~/"));这行代码将把所有绝对链接转换为相对链接,获取正确的 ../ 元素。 - Emanuele Greco
我阅读了这个问题,尝试并使用了这段代码,并投了赞成票。这只是一个改进通用情况下发布的代码的一般建议。 - Emanuele Greco
由于内容切换,该应用程序不知道“/social”路径,因此在这种情况下无法工作。 - James Law
@JamesLaw - 我也遇到了同样的问题,我无法理解你关于模仿“/social”关键字的第二个建议。目前我们有一个负载均衡器,它向我们的站点发出请求。因此,站点的URL变成了根+主机名,我们正在使用reportviewer控件,它会自动调用webresource.axd来加载控件。你能否就此提出一些建议? - Punit
2
@Punit,你需要在IIS中创建一个虚拟应用程序,并将你的代码托管在那里。例如,在我的情况下,我会创建一个名为“social”的虚拟应用程序,它指向该应用程序,因此使http://localhost/social/表现为应用程序根目录。 - James Law
我曾认为这是我的救星,直到我遇到了使用异步回发的页面问题。在这种情况下,服务器端会创建一个特殊格式的响应,其中包含某个部分的大小值。该大小值在内容之前发送,因此很难捕获和更改。由于您要删除一个字符,因此大小肯定会发生变化。请参见https://weblogs.asp.net/leftslipper/sys-webforms-pagerequestmanagerparsererrorexception-what-it-is-and-how-to-avoid-it。 - Greg Vogel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接