~ Paths resolved differently after upgrading to ASP.NET 4
We're upgrading a large system to ASP.NET 4, and we've discovered a strange issue with the way paths starting with ~
are resolved for some of our Ajax requests. Our Ajax requests use Server.Execute, and the pages they execute have paths that start with ~. However, in ASP.NET 4, it seems like this path is being resolved incorrectly, treating "MyService.aspx/MyMethod" as if MyService.aspx was a folder. This is different to ASP.NET 3.5.
I've created a small sample to show the issue.
I've managed to reproduce the issue in a small sample:
~/Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<html>
<head runat="server">
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.6.4");
</script>
</head>
<body>
<script type="text/javascript">
$(function () {
$.ajax({
type: "POST",
url: "WebService1.asmx/HelloWorld",
success: function (msg) {
alert(msg.text);
}
});
});
</script>
</body>
&开发者_如何学Golt;/html>
WebService1.asmx.cs
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
var tw = new StringWriter();
tw.WriteLine("VirtualPathUtility.ToAbsolute(\"~/Images/Blah.png\"): " + VirtualPathUtility.ToAbsolute("~/Images/Blah.png"));
tw.WriteLine("VirtualPathUtility.ToAppRelative(\"~/Images/Blah.png\"): " + VirtualPathUtility.ToAppRelative("~/Images/Blah.png"));
// Hack to use ResolveClientUrl without including a Server.Execute in the sample
tw.WriteLine("new Image().ResolveClientUrl(\"~/Images/Blah.png\"): " + new Image().ResolveClientUrl("~/Images/Blah.png"));
return tw.ToString();
}
}
If you run this same code on ASP.NET 3.5 and ASP.NET 4, you'll get different outputs:
3.5
---------------------------
VirtualPathUtility.ToAbsolute("~/Images/Blah.png"): /MyTest1/Images/Blah.png
VirtualPathUtility.ToAppRelative("~/Images/Blah.png"): ~/Images/Blah.png
new Image().ResolveClientUrl("~/Images/Blah.png"): Images/Blah.png
4.0
---------------------------
VirtualPathUtility.ToAbsolute("~/Images/Blah.png"): /MyTest1/Images/Blah.png
VirtualPathUtility.ToAppRelative("~/Images/Blah.png"): ~/Images/Blah.png
new Image().ResolveClientUrl("~/Images/Blah.png"): ../Images/Blah.png
The first two calls are the same, but the ResolveClientUrl
call behaves differently. Note: We're not actually calling ResolveClientUrl
like this, it's inside an ASPX page that is Server.Execute
'd, I just did this to keep the sample small - the issue appears to be the same.
So... Is this a bug? Is there any way I can make this work the same as in ASP.NET 4 to avoid having to move things around so that the paths work correctly?
Looks like this may be a deliberate change (bug fix?) in ASP.NET 4.0, so that paths are returned correctly so that browsers would interpret them, eg.
/MyFolder/MyPage.aspx/Something/Something
In ASP.NET, the URLs would be incorrect, because they'd be based off /MyFolder/MyPage.aspx
.
I don't think the ASP.NET 3.5 behaviour was really ever correct, it's just what we used because that's how it was, so it's now become broken.
My solution for now, is to move the asmx files up one level, so they're a level above the pages their content is being written in to. This is a bis nasty, and only works if your pages are in a folder, but it's easier than rewriting how this works!
精彩评论