2

要求序列化一个类并将其发送到服务器。

开发环境:

MonoDevelop 3.0.6

运行时: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 对象时,变量 foo 中用于转义双引号的反斜杠被转换为正斜杠,从而破坏了 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 类发送到服务器,但是还有其他代码(hack)在单声道 mac 上不起作用

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> 

但是这些方法都不起作用,并且在创建请求时编码会丢失。

任何使它起作用的想法将不胜感激。

更新:

我已经尝试了很多东西,包括使用一些 3rd 方开源代码进行测试,但在发送编码的 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);
                    }
                }
            }
        }
4

1 回答 1

0

我已经尝试了很多东西,包括使用一些 3rd 方开源代码进行测试,但在发送编码的 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);
            }
        }
    }
}
于 2016-10-05T01:43:04.377 回答