注意:代码在F#中,但标记C#,因为它是从.net转换为json 时.net上的一般编码和转义字符问题,请查看在页面底部的输出处。
以下请求最终导致错误请求,请查看任何差异,尤其是Encoding.Default.GetString
,然后再编码回System.Text.Encoding.ASCII.GetBytes
。
上下文:对象被序列化并写入PUT请求的主体,最终被视为错误的请求400. JSON被正确序列化,我可以看到带有Console.WriteLine
的字符串
let update (schema: Article) : Article =
let url = "http://example.com"
use memoryStream = new MemoryStream()
(new DataContractJsonSerializer(typeof<Article>)).WriteObject(memoryStream, schema)
let d = Encoding.Default.GetString(memoryStream.ToArray()) // I suspect problem may be here
let data : byte[] = System.Text.Encoding.ASCII.GetBytes(d); // or here
let request = WebRequest.Create(url) :?> HttpWebRequest
request.Method <- "PUT"
request.ContentType <- "application/json;charset=UTF-8"
request.Accept <- "application/json;charset=UTF-8"
request.ContentLength <- (int64)data.Length
use requestStream = request.GetRequestStream()
requestStream.Write(data, 0, data.Length)
requestStream.Flush()
requestStream.Close()
let response = request.GetResponse() :?> HttpWebResponse
use reader = new StreamReader(response.GetResponseStream())
use memoryStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(reader.ReadToEnd()))
let result = (new DataContractJsonSerializer(typeof<Article>)).ReadObject(memoryStream) :?> Article
reader.Close()
response.Close()
request.Abort()
result
进一步发现
我能够获得Charles Proxy,我看到正向斜杠已经在输出序列化的json中转义到服务器。
实际输出:使用转义斜线\ /
\/publication\/d40a4e4c-d6a3-45ae-98b3-924b31d8712a\/altasset\/c42d0df7-a563-4bb5-b7fa-313e6a98032f\/
预期输出:它们应该只有正斜杠,不能转义字符。
/公开/ d40a4e4c-d6a3-45ae-98b3-924b31d8712a ....
我想在编码过程中导致角色被转义的东西,有没有办法解决它?
修改
我还注意到memoryStream.ToArray()
返回byte[]
所以我没有通过编码,而是尝试了以下内容,但它没有任何区别。
let data : byte[] = memoryStream.ToArray()
requestStream.Write(data, 0, data.Length)
在Charles代理中,我看到破管消息。
答案 0 :(得分:1)
添加对Newtonsoft.Json NuGet包的引用,并将其添加到F#文件的顶部:
open Newtonsoft.Json
然后尝试将此作为更新方法的主体(它显式使用UTF-8编码而不是ASCII或平台默认值):
let url = "http://example.com"
let serialized = JsonConvert.SerializeObject(schema)
let data : byte[] = Encoding.UTF8.GetBytes(serialized)
let request = WebRequest.Create(url) :?> HttpWebRequest
request.Method <- "PUT"
request.ContentType <- "application/json;charset=UTF-8"
request.Accept <- "application/json;charset=UTF-8"
request.ContentLength <- (int64)data.Length
use requestStream = request.GetRequestStream()
requestStream.Write(data, 0, data.Length)
requestStream.Flush()
requestStream.Close()
let response = request.GetResponse() :?> HttpWebResponse
use reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)
let result = JsonConvert.DeserializeObject<Article>(reader.ReadToEnd())
reader.Close()
response.Close()
request.Abort()
result
除非您正在使用的服务器也在使用DataContractJsonSerializer(它逃脱&#34; /&#34; as&#34; \ /&#34;),否则你可能会更好Newtonsoft。在UTF-8编码问题出现之前修复UTF-8编码问题并没有什么坏处(它看起来不像是在发送/接收任何非ASCII文本,但在现实世界中不可避免地会发生这种情况)。 / p>