2011-04-20 56 views
4

以下代码的意图是通过HTTP发布以字节顺序标记(BOM)开头的数据。WebClient.UploadString方法不发出BOM。为什么?

var client = new WebClient(); 
client.Encoding = new UTF8Encoding(true /* encoderShouldEmitUTF8Identifier */); 
client.UploadString(url, data); 

然而,根据提琴手有在请求体的开始没有BOM。即使我使用UnicodeEncoding而不是UTF8Encoding,BOM也不会发送。

所以问题是,我做错了什么?

:我知道,我可以通过组合使用WebClient.UploadDataEncoding.GetPreamble方法,但是我很奇怪,为什么UploadString如我所料不工作绕过这个问题。

+0

对于Windows文件,不是BOM是一个字节顺序标记吗?为什么'字符串'通过HTTP发送(不管编码)发送BOM? – 2011-06-20 12:57:33

回答

1

你没有做错什么,它只是WebClient.UploadString 不叫Encoding.GetPreamble - 它只是在你传递的字符串调用Encoding.GetBytes。在HTTP请求中,如果传递字符串,通常会在内容类型头(charset参数)中指示编码,而不是在文件中内联(参见下面的示例)。 UploadString可以做到这一点(它是为“常见案例”量身定做的)。正如你所提到的,如果你想要额外的东西,你可以直接上传字节。

public class StackOverflow_5731102 
{ 
    [ServiceContract] 
    public class Service 
    { 
     [WebInvoke] 
     public Stream Process(Stream input) 
     { 
      StringBuilder sb = new StringBuilder(); 
      foreach (var header in WebOperationContext.Current.IncomingRequest.Headers.AllKeys) 
      { 
       sb.AppendLine(string.Format("{0}: {1}", header, WebOperationContext.Current.IncomingRequest.Headers[header])); 
      } 

      string contentType = WebOperationContext.Current.IncomingRequest.ContentType; 
      Encoding encoding = Encoding.GetEncoding(contentType.Substring(contentType.IndexOf('=') + 1)); 
      WebOperationContext.Current.OutgoingResponse.ContentType = WebOperationContext.Current.IncomingRequest.ContentType; 
      return new MemoryStream(encoding.GetBytes(sb.ToString())); 
     } 
    } 

    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     foreach (var encoding in new Encoding[] { new UTF8Encoding(true), new UnicodeEncoding(false, true) }) 
     { 
      Console.WriteLine("Sending encoding = {0}", encoding.WebName); 
      WebClient client = new WebClient(); 
      client.Headers[HttpRequestHeader.ContentType] = "text/plain; charset=" + encoding.WebName; 
      client.Encoding = encoding; 
      string url = baseAddress + "/Process"; 
      string data = "hello"; 
      string result = client.UploadString(url, data); 
      Console.WriteLine(result); 

      Console.WriteLine(string.Join(",", encoding.GetBytes(data).Select(b => b.ToString("X2")))); 
     } 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
相关问题