2013-02-18 1 views
2

Требование сериализовать класс и отправить его на сервер.Отправка сериализованного объекта json с экранированной строкой с использованием HttpWebRequest на mono

Dev среда:

MonoDevelop 3.0.6

Runtime: Mono 2.10.9 (тарболом)

GTK 2.24.10 

GTK# (2.12.0.0) 

Операционная система:

Mac OS X 10.7.4 

Класс содержит строка со скрытой двойной кавычкой в ​​ней.

class CustomClass 
{ 
    public string foo = "hi!\""; 
} 

Вопрос заключается в том, что, когда я сериализовать его, кодировать и создать объект URI, обратный слэш используется, чтобы избежать двойных кавычек в переменной обув превращается в косую черту, тем самым нарушая JSON.

Ниже приведены значения различных переменных экземпляра URI

Uri: 
http://myserver/hello_world/0/{"foo":"hi!/""} 

AbsoluteUri: 
http://myserver/hello_world/0/%7B%22foo%22%3A%22hi%21/%22%22%7D 

OriginalString: 
http://myserver/hello_world/0/%7B%22foo%22%3A%22hi%21%5C%22%22%7D 

HttpWebRequest отправить значение "http://myserver/hello_world/0/{"foo":"hi!/""}" на сервер, но для моего требования он должен использовать OriginalString, чтобы получить правильный ответ от сервера.

Если я проверить код на .NET OriginalString посылается на сервер класса HttpWebRequest, но есть дополнительный код (хак), который не работает на моно макинтош

string paq = requestUri.PathAndQuery; 
FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic); 
ulong flags = (ulong)flagsFieldInfo.GetValue(requestUri); 
flags &= ~((ulong)0x30); // Flags.PathNotCanonical|Flags.QueryNotCanonical 
flagsFieldInfo.SetValue(requestUri, flags); 

Кодекса :

object messageObject = new CustomClass(); 

//try 1 
//string jsonString = Uri.EscapeUriString(JsonConvert.SerializeObject(message2)); 

//try 2 
//string jsonString = Uri.EscapeDataString(JsonConvert.SerializeObject(message2)); 

//try 3 

string jsonString = System.Web.HttpUtility.UrlEncode(JsonConvert.SerializeObject(messageObject)); 

Uri uri = new Uri(string.Format("http://myserver/hello_world/0/{0}", jsonString)); 

//try 4: 
//HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.AbsoluteUri); 

//try 5 
//HttpWebRequest request =(HttpWebRequest)WebRequest.Create(string.Format("http://myserver/hello_world/0/{0}",jsonString)); 

//try 6 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.OriginalString); 

try 
{ 
    using (HttpWebResponse resp = request.GetResponse() as HttpWebResponse) 
    { 
     var reader = new StreamReader(resp.GetResponseStream()); 
     string jsonResponse = reader.ReadToEnd(); 
    } 
} 
catch (WebException wex) 
{ 
    Debug.WriteLine(wex.ToString()); 
} 

Как вы можете видеть, что я попытался с помощью Uri.EscapeUriString, Uri.EscapeDataString и System.Web.HttpUtility.UrlEncode и используя AbsouluteUri и OriginalString для создания WebRequest экземпляра, а также создать его, используя строку.

Я также попытался использовать следующий код в конфиге.

<uri> 
    <schemeSettings> 
     <clear/> 
     <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/> 
    </schemeSettings> 
</uri> 

Но ни один из методов не работает, и кодировка теряется при создании запроса.

Любые идеи, чтобы заставить это работать, будут оценены.

Update:

Я попробовал много вещей, в том числе тестирование с некоторыми третьей стороной с открытым исходным кодом, но все-таки столкнулись с той же проблемой при отправке в закодированном URL.

Я изменил код для использования WebClient вместо WebRequest, но все равно не повезло.

Итак, решение, которое работало на меня как на MonoMac, так и на MonoTouch (симулятор, я его не тестировал на устройстве), заключался в создании запроса с использованием TcpClient.

using (TcpClient tc = new TcpClient()) { 
tc.Connect ("myserver", 80); 

using (NetworkStream ns = tc.GetStream()) { 
    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns)) { 
        using (System.IO.StreamReader sr = new System.IO.StreamReader(ns)) { 
         sw.Write("GET /hello_world/0/%7B%22foo%22:%22hi!%5C%22%22%7D HTTP/1.1 Host:myserver \r\n\r\n"); 
         sw.Flush(); 
         string line; 
         while ((line=sr.ReadLine())!=null) 
          Console.Write (line); 
        } 
       } 
      } 
     } 
+0

опыт Кроме того, такое же поведение на MonoTouch –

+0

Что 'Foo = @ "привет!" "";' Получить вас? – ruffin

+0

@ruffin, Спасибо за ответ. Это дает мне тот же результат в Uri, но AbsoluteUri и OriginalString отличается. HttpWebRequest по-прежнему отправляет значение '' http: // myserver/hello_world/0/{"foo": "hi! /" "}" 'На сервер ' URI http: // myserver/hello_world/0/{ "Foo": "Привет /" "} OriginalString HTTP: // MyServer/hello_world/0 /% 7B% 22foo% 22% 3A% 22hi% 21% 5C% 22% 22% 7D AbsoluteUri Http: // MyServer/hello_world/0 /% 7B% 22foo% 22:% 22hi /% 22% 22% 7D' –

ответ

0

Я пробовал много вещей, включая тестирование с некоторыми третьей стороной с открытым исходным кодом, но все-таки столкнулись с той же проблемой при отправке в закодированном URL.

Я изменил код для использования WebClient вместо WebRequest, но все равно не повезло.

Итак, решение, которое работало на меня как на MonoMac, так и на MonoTouch (симулятор, я его не тестировал на устройстве), заключался в создании запроса с использованием TcpClient.

using (TcpClient tc = new TcpClient()) { 
tc.Connect ("myserver", 80); 

using (NetworkStream ns = tc.GetStream()) { 
    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns)) { 
     using (System.IO.StreamReader sr = new System.IO.StreamReader(ns)) { 
      sw.Write("GET /hello_world/0/%7B%22foo%22:%22hi!%5C%22%22%7D HTTP/1.1 Host:myserver \r\n\r\n"); 
      sw.Flush(); 
      string line; 
      while ((line=sr.ReadLine())!=null) 
       Console.Write (line); 
      } 
     } 
    } 
}