2011-06-23 62 views
2

這裏是我的簡單的C#代碼:西里爾POST頭的價值

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Net; 
using System.IO; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     {       
      WebRequest req = WebRequest.Create("http://192.168.1.35:8888/"); 
      req.Method = "POST"; 
      req.ContentLength = 0; 

      req.Headers.Add("s", "АБВ12"); 
      req.Headers.Add("username", "user"); 
      req.Headers.Add("password", "pass"); 

      System.Net.WebResponse resp = req.GetResponse();    
      System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()); 
      Console.WriteLine(sr.ReadToEnd()); 
     } 
    } 
} 

於是,我嘗試發送POST請求Apache服務器,並得到服務器的答案。我不需要任何額外的請求頭。問題是我試圖運行這段代碼,我得到了異常:

System.ArgumentException was unhandled 
    Message=Specified value has invalid Control characters. 
Parameter name: value 
    Source=System 
    ParamName=value 
    StackTrace: 
     at System.Net.WebHeaderCollection.CheckBadChars(String name, Boolean isHeaderValue) 
     at System.Net.WebHeaderCollection.Add(String name, String value) 
     at Test.Program.Main(String[] args) in D:\Test\Test\Test\Program.cs:line 17 
     at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

看來我需要將頭值轉換爲ISO-8859-1編碼。那麼,我怎樣才能讓這個程序正常工作呢?對不起我的英語不好。我希望能爲你提供幫助。 在此先感謝!


樣品要求,在我的情況下正常工作:

 
POST/HTTP/1.1 
s: АБВ12 
username: user 
password: pass 
Content-Length: 0 
Accept: */* 
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5) 
Host: 127.0.0.1 
Connection: Keep-Alive 

UPD 我已經通過互操作組件WinHttpRequest解決這個問題:

WinHttp.WinHttpRequest oHTTP = new WinHttp.WinHttpRequest(); 
oHTTP.Open("POST", "http://127.0.0.1:8888/"); 
oHTTP.SetRequestHeader("s", args[0]); 
oHTTP.SetRequestHeader("username", "user"); 
oHTTP.SetRequestHeader("password", "pass"); 
oHTTP.Send(); 

ARGS [0]包含任何西里爾字符。感謝大家!

回答

4

您可以使用Uri.EscapeDataString轉義請求標頭中的非ASCII字符。下面的代碼(用一個簡單的WCF服務來模擬接收端)顯示瞭如何做到這一點。請注意,您還需要在服務器端忽略標題值(如下所示)。

public class StackOverflow_6449723 
{ 
    [ServiceContract] 
    public class Service 
    { 
     [WebGet(UriTemplate = "*", ResponseFormat = WebMessageFormat.Json)] 
     public Stream GetHeaders() 
     { 
      StringBuilder sb = new StringBuilder(); 
      foreach (var header in WebOperationContext.Current.IncomingRequest.Headers.AllKeys) 
      { 
       sb.AppendLine(string.Format("{0}: {1}", header, Uri.UnescapeDataString(WebOperationContext.Current.IncomingRequest.Headers[header]))); 
      } 
      WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain; charset=utf-8"; 
      return new MemoryStream(Encoding.UTF8.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"); 

     WebRequest req = WebRequest.Create(baseAddress + "/foo"); 
     req.Headers.Add("s", Uri.EscapeDataString("АБВ12"));    
     req.Headers.Add("username", "user"); 
     req.Headers.Add("password", "pass"); 
     WebResponse resp = req.GetResponse(); 
     StreamReader sr = new StreamReader(resp.GetResponseStream()); 
     Console.WriteLine(sr.ReadToEnd()); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
+0

感謝您的回覆,卡洛斯!對不起,但我沒有寫我無法控制服務器端(例如我寫了本地地址)。問題是你的代碼不起作用,但它很好。請求已發送到服務器,但未被「識別」,因爲它試圖在數據庫中查找's'標頭值的值。我在Visual FoxPro中有一個與該Web服務器正常工作的程序(請參閱我的問題更新中的正確請求示例)。 因此,它似乎使用特定的crarcterset將其發送到服務器。 – kseen