Значение заголовка кириллицы POST - PullRequest
2 голосов
/ 23 июня 2011

Вот мой простой код 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());
        }
    }
}

Итак, я пытаюсь отправить запрос 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 Я решил эту проблему с помощью 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 Ответ

4 голосов
/ 23 июня 2011

Вы можете использовать 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();
    }
}
...