强制HttpWebRequest使用HTTP 1.0并在PCL中为Windows 8设置UserAgent

时间:2013-03-25 04:41:13

标签: c# windows-8 windows-phone mvvm-light portable-class-library

我在PCL中创建了一个类,以获取所需的Session-Id和用于登录Web服务器的密钥。 (响应是XML,它在第二个运行Login的方法中解析)我无法控制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&amp; WP8。当我在我的应用程序的Windows 8部分中使用此方法时,我得到了完全不同的结果。

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

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

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

我是MVVM和PCL的新手,所以请原谅我这是一个愚蠢的问题。 感谢。

3 个答案:

答案 0 :(得分:2)

我通过切换到新的 HttpClient (PCL)库并在那里设置Version属性解决了一个非常类似的问题。在NuGet for 'Microsoft HTTP Client Libraries'上搜索(截至今天的测试版,但效果非常好)。

我仍然不明白为什么它总是适用于我使用1.0而且只是零星(Win7和Win8)使用1.1

答案 1 :(得分:0)

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

阅读此主题的评论:

  

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

     

Regretfully,the portable library design has been to support only properties that are globally available-- and the user agent cannot be set on all platforms (e.g., for SilverLight)

不幸的是,大多数the restricted headers都不是PCL,因此无法在大多数平台上进行更改。

As I seen on this thread,更改这些受限标题的唯一方法是使用反射。

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's answer可能是另一种选择,但我还没有尝试过。

答案 2 :(得分:-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*