西里尔文POST标题的值

时间:2011-06-23 05:28:44

标签: c# post http-headers webrequest

这是我简单的C#代码:

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());
        }
    }
}

因此,我尝试向Apache Server发送POST请求并获得服务器答案。我不需要任何额外的请求heeaders。问题是我尝试运行此代码我得到了异常:

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 我通过使用Interop组件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]包含任何西里尔字母。谢谢大家!

1 个答案:

答案 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();
    }
}