为什么这个异常声称代码不写数据?

时间:2011-07-09 16:24:39

标签: c# webclient onedrive

如果您运行此代码,它将抛出WebException。内部异常是“无法为不写入数据的操作设置Content-Length或Chunked Encoding”。我不明白问题的本质。任何人都可以将光投射到这个黑暗的角落吗?

using System.Diagnostics;
using System.Net;
using System.Text;

namespace sandpit
{
  static class Program
  {
    static void Main()
    {
      string INITIAL_URI = "http://docs.live.net/SkyDocsService.svc";
      string SOAP = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><GetWebAccountInfoRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://schemas.microsoft.com/clouddocuments\"><BaseRequest><ClientAppId>SkyDrive Service Client</ClientAppId><Market>en-US</Market><SkyDocsServiceVersion>v1.0</SkyDocsServiceVersion></BaseRequest><GetReadWriteLibrariesOnly>false</GetReadWriteLibrariesOnly></GetWebAccountInfoRequest></s:Body></s:Envelope>";
      using (WebClient wc = new WebClient())
      {
        wc.Encoding = Encoding.UTF8;
        wc.Headers["SOAPAction"] = "GetWebAccountInfo";
        wc.Headers["Accept-Language"] = "en-US";
        wc.Headers["Accept"] = "text/xml";
        wc.Headers["Content-Type"] = "text/xml; charset=utf-8";
        string response = wc.UploadString(INITIAL_URI, SOAP);
        Debug.WriteLine(response);
      }
    }
  }
}

4 个答案:

答案 0 :(得分:5)

问题是网络服务器的重定向。

不幸的是,您必须将WebClient子类化以解决此问题。这比它看起来更难,因为Silverlight(任何风味)都不喜欢这样,并抛出一个继承相关的异常,直到你猜你需要覆盖ctor并将其归为SecurityCritical。

public class WebClient2 : WebClient
{
  [SecurityCritical]
  public WebClient2() : base() { }  
  protected override WebRequest GetWebRequest(System.Uri address)
  {
    var wr = base.GetWebRequest(address);
    if (wr is HttpWebRequest)
      (wr as HttpWebRequest).AllowAutoRedirect = false;
    return wr;
  }
}

如果你想要更进一步,你可以在WebClient2上展示AllowAutoRedirect属性并将其全部挂起。

答案 1 :(得分:2)

如何使用此SkyDrive client而不是手动编写SOAP请求:

var client = new SkyDriveServiceClient();
client.LogOn("user", "pwd");
var info = client.GetWebAccountInfo();
Console.WriteLine(info.Title);

对我来说似乎更容易。但是,如果您真的坚持使用WebClient并手动处理协议,您可以通过Fiddler看到与.NET客户端通过线路交换的内容并进行复制。我认为您在使用WebClient进行身份验证时可能会缺少为您的请求提供凭据。

如果您查看网络级别跟踪,您将看到SyDrive服务器需要Passport身份验证,如果您决定使用WebClient路由可能需要进行大量工作,则必须手动处理:

Location: https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=11&ct=1310230173&rver=6.1.6206.0&wp=MBI&wreply=http:%2F%2Fdocs.live.net:101%2FSkyDocsService.svc&lc=1033&id=250206
WWW-Authenticate: Passport1.4 ct=1310230292,rver=6.1.6206.0,wp=MBI,lc=1033,id=250206

答案 2 :(得分:1)

在我的情况下,问题是由同一IIS服务器6进行的重定向,因为会话状态模式设置为“自动检测”而不是“使用cookie”。每个URL请求都被重定向为'AspxAutoDetectCookieSupport = 1'。

答案 3 :(得分:-1)

您只需将网址服务更改为:https://docs.live.net/SkyDocsService.svc

即可