2011-04-20 57 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(); 
    } 
} 
相關問題