2

我在我的 PCL 中创建了一个类来获取所需的 Session-Id 和一个用于登录网络服务器的密钥。(响应是 XML,在运行登录的第二种方法中解析)我无法控制 WebServer,所以我需要在客户端解决我的问题。

这是我的任务方法:

public static async Task<string> SessionId()
{
    HttpWebRequest SessiondIdRequest = (HttpWebRequest)WebRequest.Create(Constants.SessionIdUrl);

    SessiondIdRequest.Method = "POST";
    SessiondIdRequest.Accept = "application/xml";
    SessiondIdRequest.Headers[HttpRequestHeader.AcceptLanguage] = "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3";
    SessiondIdRequest.ContentType = "application/x-www-form-urlencoded ";


    string appIDviaPOST = "{Here is a String}";
    byte[] byteArray = Encoding.UTF8.GetBytes(appIDviaPOST);

    using (var SessionIdRequestStream = await Task<Stream>.Factory.FromAsync
        (SessiondIdRequest.BeginGetRequestStream, SessiondIdRequest.EndGetRequestStream, SessiondIdRequest))
    {
        await SessionIdRequestStream.WriteAsync(byteArray, 0, byteArray.Length);
    }

   WebResponse SessionIdRequestResponse = await Task<WebResponse>.Factory.FromAsync
       (SessiondIdRequest.BeginGetResponse, SessiondIdRequest.EndGetResponse, SessiondIdRequest);
   var SessionIdRequestResponseStream = SessionIdRequestResponse.GetResponseStream();
    var sr = new StreamReader(SessionIdRequestResponseStream);
    string SessionIdResult = await sr.ReadToEndAsync();

    return SessionIdResult;
}

该任务在 WP7 和 WP8 上运行良好。当我在我的应用程序的 Windows 8 部分中使用此方法时,我得到了完全不同的结果。

我使用 Fiddler 来找出两者之间的差异,我看到的最明显的事情是 WP7&8 使用 HTTP 1.0 并发送 UserAgent,而 Win8 使用 HTTP 1.1 并且不发送 UserAgent。

在 PCL 中,HttpWebRequest 不包含 UserAgent 和 ProtocolVersion 的属性,因此我无法告诉方法强制它(因为它只是一个子集)。

有什么办法可以解决这个问题(除了将整个方法复制到我的 Win8 项目中,我可以在其中设置这些属性)。

我对 MVVM 和 PCL 很陌生,所以请原谅这对你来说是一个愚蠢的问题。谢谢。

4

3 回答 3

2

我通过切换到新的HttpClient (PCL) 库并在那里设置 Version 属性解决了一个非常相似的问题。在NuGet 上搜索“ Microsoft HTTP 客户端库(截至今天为测试版,但运行良好)。

我仍然不明白为什么使用 1.0 总是对我有用,而在使用 1.1 时只是偶尔(Win7 和 Win8)

于 2013-06-09T22:09:39.410 回答
0

信不信由你,使用 PCL 时无法更改 UserAgent 标头。

阅读此线程上的评论:

Microsoft 于 2013 年 2 月 25 日下午 4:05 发布

遗憾的是,可移植库的设计一直只支持全局可用的属性——并且不能在所有平台上设置用户代理(例如,对于 SilverLight)

不幸的是,大多数受限制的标头不是 PCL,因此在大多数平台上都无法更改。

正如我在这个线程上看到的,更改这些受限标头的唯一方法是使用反射。

var httpRequest = (HttpWebRequest) WebRequest.Create(uri);

var userAgent = httpRequest.GetType().GetProperty("UserAgent");
if(null != userAgent) 
{
    userAgent.SetValue(httpRequest, "Your value", null);
}

尽管如此,这远非理想,因为即使它可能在某些平台上工作,在其他一些平台上,您也会收到类似于此的错误:

System.InvalidOperationException:API System.Net.HttpWebRequest.set_UserAgent(System.String)' 不能在当前平台上使用。(见这篇文章)

如果您的项目与支持的平台匹配, ThumbGen 的答案可能是另一种选择,但我还没有尝试过。

于 2013-12-31T14:38:19.757 回答
-1

如果找不到 User-Agent 属性,可以尝试设置 user-agent 标头。

SessiondIdRequest.Headers["User-Agent"] = @"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)";

您也可以尝试构建请求标头,而不是使用提供的属性。

Key              Value
Request          POST http://localhost/index.aspx HTTP/1.0
Content-Length  *length*
于 2013-03-25T05:33:26.657 回答