2

我们在工作中遇到了一个超级烦人的问题。在我们的 Silverlight 应用程序进行登录 POST 后,我们发送的下一个 GET 失败并出现 NotFoundException。这仅在使用 Silverlight 5 运行时发生并且仅在 Internet Explorer 9 中发生。我现在已经使用 Silverlight 4 以及 Chrome、Firefox、Opera 和 Safari 进行了测试,IE9/SL5 是唯一不好的组合。

以下是我们登录 POST 的标题:

POST /login HTTP/1.1
Accept: application/xml
Referer: http://localhost:8080/censored.xap?timestamp=1326148328000
Accept-Language: en-CA
Content-Length: 38
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: localhost:8080
Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=DEFEAFD35E9B067A79F772C166937750

以下是我们下一个 GET 的标头:

GET /user/current HTTP/1.1
Accept: application/xml
Referer: http://localhost:8080/censored.xap?timestamp=1326148328000
Accept-Language: en-CA
Content-Length: 38
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: localhost:8080
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=5C57C93458E80E5975470F703B4A483C

请注意,Content-Type 和 Content-Length 是相同的,即使:

  • 不允许在 GET 上使用 Content-Type 或 Content-Length
  • GET 请求中的内容长度实际上是不同的,因此显然是旧值

还有其他人遇到这个吗?

更新:仅在使用 BrowserHttp 时发生。

这是一些示例客户端代码:

using System;
using System.IO;
using System.Net;
using System.Net.Browser;
using System.Windows.Controls;

namespace NetworkTest
{
public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        HttpWebRequest request = (HttpWebRequest)WebRequestCreator.BrowserHttp.Create(new Uri("http://localhost:59050/Home/Login"));
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.BeginGetRequestStream(result =>
            {
                var rq = result.AsyncState as HttpWebRequest;

                using (var stream = rq.EndGetRequestStream(result))
                {
                    StreamWriter writer = new StreamWriter(stream);
                    writer.WriteLine("username=test&password=test");
                    writer.Flush();
                    writer.Close();
                }

                rq.BeginGetResponse(
                    r =>
                    {
                        try
                        {
                            rq.EndGetResponse(r);
                        }
                        catch
                        {
                        }
                    }, rq);
            }, request);
    }
}
}

示例服务器代码(来自 ASP MVC 3):

using System.Web.Mvc;

namespace TestServer.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Login(string test)
        {
            return RedirectToAction("Index");
        }
    }
}

您最终会看到一个 POST 登录,这是一个成功的请求。您被重定向回索引页面,并且 GET 仍然包含来自 POST 的 Content-Type 和 Content-Length,因此它失败了。

完整的解决方案可在http://www.mikecousins.com/files/NetworkTest.zip

4

1 回答 1

1

这个对我有用。

这是我对您的项目所做的步骤。

  1. 设置特定端口 59050,因为您对 URL 进行了硬编码,但使用了自动分配的端口。
  2. 将 Silverlight 项目添加到 WebServer(从 Casini 运行优于从文件运行。)
  3. 更改 _Layout.cshtml 如下以添加 SL 对象

    @ViewBag.Title NetworkTest html, body { height: 100%; 溢出:自动;} 身体 { 填充:0;边距:0;} #silverlightControlHost { 高度:100%; 文本对齐:居中;} function onSilverlightError(sender, args) { var appSource = ""; if (sender != null && sender != 0) { appSource = sender.getHost().Source; }

            var errorType = args.ErrorType;
            var iErrorCode = args.ErrorCode;
    
            if (errorType == "ImageError" || errorType == "MediaError") {
                return;
            }
    
            var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";
    
            errMsg += "Code: " + iErrorCode + "    \n";
            errMsg += "Category: " + errorType + "       \n";
            errMsg += "Message: " + args.ErrorMessage + "     \n";
    
            if (errorType == "ParserError") {
                errMsg += "File: " + args.xamlFile + "     \n";
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
            else if (errorType == "RuntimeError") {
                if (args.lineNumber != 0) {
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " + args.charPosition + "     \n";
                }
                errMsg += "MethodName: " + args.methodName + "     \n";
            }
    
            throw new Error(errMsg);
        }
    </script>
    

    我的 MVC 应用程序

    @Html.Partial("_LogOnPartial")
  4. @Html.ActionLink("首页", "索引", "首页")
  5. @Html.ActionLink("关于"、"关于"、"首页")
  6. @RenderBody()

4.选中Web选项卡中的“Silverlight”以启用Silverlight调试。5. 将断点置于 MainPage.xaml.cs 中的 rq.EndGetResponse()(第 34 行)。6. 运行应用程序(注意:这个断点会被命中。)

我正在使用 SL5 和 IE9 进行测试。

于 2012-04-04T09:30:56.457 回答