目录
第一章、异常问题
1.1、序列化
序列化的问题不是很大,并没有什么东西可讲的了,详细的见第三章的DEMO。
1.2、反序列化
1.2.1、问题一
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'KeenRay.HTTP.Json+ServiceResponseInfoStruct' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.Path '', line 1, position 1.
1.2.2、问题二
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'KeenRay.HTTP.Json+Contour' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '[0].data.detect_list[0].contour[0]', line 1, position 431.
第二章、解决办法
主要解决反序列化的异常问题。
2.1、办法一(解决问题一)
导致问题一的原因,是因为没有将对象ServiceResponseInfoStruct写成泛型数组的形式。该解析方法会发生异常:
ServiceResponseInfoStruct serviceResponseInfoStruct = new ServiceResponseInfoStruct();
Data data = new Data();
serviceResponseInfoStruct.data = data;
serviceResponseInfoStruct = Newtonsoft.Json.JsonConvert.DeserializeObject<ServiceResponseInfoStruct>(strReponseJsonData)
你要写成泛型数组的形式,才可以完美解析:
List<ServiceResponseInfoStruct> serviceResponseInfoStruct = new List<ServiceResponseInfoStruct>();
serviceResponseInfoStruct = Newtonsoft.Json.JsonConvert.DeserializeObject<ServiceResponseInfoStruct>(strReponseJsonData)
2.2、办法二(解决问题二)
仔细比对问题一和问题二的差异地方,发现contour这个数组存在问题,可能是我初始化contour泛型数组出错。因此我需要仔细排查。仔细排查了好久,还是没有找出问题的关键。
于是比对了一下文档与数据结构。文档如下:
数据结构如下:
#region Service数据结构
public class ServiceResponseInfoStruct
{
public Data data = new Data();//有疑问
//public List<Data> data = new List<Data>();
//public Data data { get; set; }
public string imagePath { get; set; }
public string message { get; set; }
public string source { get; set; }
public int status_code { get; set; } //文档是Int类型,不过上一版本一直用的是string类型。
}
public class Data
{
public float abnormal_score { get; set; }
public float cost { get; set; }
public bool is_normal { get; set; }
public bool is_pa { get; set; }
public List<DetectList> detect_list = new List<DetectList>();
//public List<DetectList> detect_list { get; set; }
}
public class DetectList
{
public string disease { get; set; }
public float prob { get; set; }//必须加public
public int width { get; set; }
public int height { get; set; }
public int x1 { get; set; }
public int y1 { get; set; }
public int x2 { get; set; }
public int y2 { get; set; }
public List<Contour> contour = new List<Contour>();
public List<Mask_points> mask_points = new List<Mask_points>();
//public List<Contour> contour { get; set; }
//public List<Mask_points> mask_points { get; set; }
}
public class Contour
{
public int x { get; set; }
public int y { get; set; }
}
public class Mask_points
{
public int x { get; set; }
public int y { get; set; }
public float value { get; set; }
}
#endregion
最终发现是文档的contour并不是我们定义的泛型数组 public List<Contour> contour = new List<Contour>();而是一个二维数组。因此,我们把public List<Contour> contour = new List<Contour>() 改成 public int[ , ] contour { get; set; },就能解决问题二的错误。
第三章、实用的DEMO
本DEMO提供了Json.cs、HttpClient.cs、HttpService.cs 三个例子。工程太复杂,不再罗列工程。这三个例子提供了数据结构、客户端、服务端,完全够用了。
3.1、Json.cs:
public class Json
{
#region Client数据结构:请求参数
[Serializable]
public class ClientRequestInfoStruct
{
public Callback callback { get; set; }
public Image image { get; set; }
}
public class Callback
{
public string url { get; set; }
//public string futureReserved { get; set; }//预留字段,此外该字段还可以方便清晰识别出该数据结构。
}
public class Image
{
public string method { get; set; }
public string source { get; set; }
}
#endregion
#region Service数据结构
public class ServiceResponseInfoStruct
{
public Data data = new Data();//有疑问
public string imagePath { get; set; }
public string message { get; set; }
public string source { get; set; }
public int status_code { get; set; }
}
public class Data
{
public float abnormal_score { get; set; }
public float cost { get; set; }
public bool is_normal { get; set; }
public bool is_pa { get; set; }
public List<DetectList> detect_list = new List<DetectList>();
}
public class DetectList
{
public string disease { get; set; }
public float prob { get; set; }
public int width { get; set; }
public int height { get; set; }
public int x1 { get; set; }
public int y1 { get; set; }
public int x2 { get; set; }
public int y2 { get; set; }
public int[,] contour { get; set; }
public List<Mask_points> mask_points = new List<Mask_points>();
}
public class Mask_points
{
public int x { get; set; }
public int y { get; set; }
public float value { get; set; }
}
#endregion
}
3.2、HttpClient.cs:
public class HttpClient
{
#region 属性
public enum EnumHttpVerb
{
GET,
POST,
PUT,
DELETE
}
/// <summary>
/// 端点路径:保存需要连接服务器的IP和端口号
/// </summary>
public string EndPoint { get; set; }
/// <summary>
/// 请求方式
/// </summary>
public EnumHttpVerb Method { get; set; }
/// <summary>
/// 文本类型(1、application/json 2、txt/html)
/// </summary>
public string ContentType { get; set; }
/// <summary>
/// 请求的数据(一般为JSon格式)
/// </summary>
public string PostData { get; set; }
#endregion
public void startClient(string strDicomPath)
{
try
{
/*请求数据:client的Json格式数据*/
ClientRequestInfoStruct clientRequestInfoStruct = new ClientRequestInfoStruct();
Callback callback = new Callback();
Image image = new Image();
clientRequestInfoStruct.callback = callback;
clientRequestInfoStruct.image = image;
clientRequestInfoStruct.callback.url = @"http://127.0.0.1:8001";//回传的URL
clientRequestInfoStruct.image.method = "local";//本地请求。
clientRequestInfoStruct.image.source = strDicomPath;//本地请求的图片路径。
LogHelper.Debug("KeenRay.HTTP.Client.cs::startClient() 回传的URL = " + clientRequestInfoStruct.callback.url);
LogHelper.Debug("KeenRay.HTTP.Client.cs::startClient() 本地请求的图片路径 = " + strDicomPath);
/*请求参数:HTTP服务请求,这四个参数往往需要设置*/
EndPoint = @"http://127.0.0.1:8000/api/v1/ai_task";//请求URL
Method = EnumHttpVerb.POST;//POST请求。
ContentType = "application/json";
PostData = JsonConvert.SerializeObject(clientRequestInfoStruct);
LogHelper.Debug("KeenRay.HTTP.Client.cs::startClient()请求的 URL = " + EndPoint);
LogHelper.Debug("KeenRay.HTTP.Client.cs::startClient()请求的 PostData数据 = " + PostData);
/*开启请求,并返回请求响应信息*/
string strJsonData = HttpRequest(EndPoint);
LogHelper.Debug("KeenRay.HTTP.Client.cs::startClient() Client 请求响应信息: " + strJsonData);
}
catch(Exception ex)
{
LogHelper.Error("KeenRay.HTTP.Client.cs::startClient()图像智能识别URL请求异常,请查看端口以及Dicom路径--" + ex.ToString());
}
}
/// <summary>
/// http请求url
/// </summary>
/// <param name="parameters">parameters例如:?name=LiLei</param>
/// <returns></returns>
public string HttpRequest(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create(parameters);
request.Method = Method.ToString();
request.ContentLength = 0;
request.ContentType = ContentType;
if (!string.IsNullOrEmpty(PostData) && Method == EnumHttpVerb.POST)
{
var bytes = Encoding.UTF8.GetBytes(PostData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = string.Format("请求数据失败. 返回的 HTTP 状态码:{0}", response.StatusCode);
throw new ApplicationException(message);
}
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
return responseValue;
}
}
}
3.3、HttpService.cs:
public class HttpService
{
public delegate void HttpCallBackFunDelegate();
private HttpCallBackFunDelegate httpCallBackFunDelegate = null;
/// <summary>
/// 回调函数
/// </summary>
/// <param name="temp"></param>
public void SetHttpDelegateFun(HttpCallBackFunDelegate temp)
{
this.httpCallBackFunDelegate = temp;
}
/// <summary>
/// Service接收的Json数据。
/// </summary>
public List<ServiceResponseInfoStruct> serviceResponseInfoList = new List<ServiceResponseInfoStruct>();
public class HttpProcessor
{
public TcpClient socket;
public HttpServer srv;
private Stream inputStream;
public StreamWriter outputStream;
public String http_method;
public String http_url;
public String http_protocol_versionstring;
public Hashtable httpHeaders = new Hashtable();
private static int MAX_POST_SIZE = 10 * 1024 * 1024; // 10MB
public HttpProcessor(TcpClient s, HttpServer srv)
{
this.socket = s;
this.srv = srv;
}
private string streamReadLine(Stream inputStream)
{
int next_char;
string data = "";
while (true)
{
next_char = inputStream.ReadByte();
if (next_char == '\n') { break; }
if (next_char == '\r') { continue; }
if (next_char == -1) { Thread.Sleep(1); continue; };
data += Convert.ToChar(next_char);
}
return data;
}
public void process()
{
// we can't use a StreamReader for input, because it buffers up extra data on us inside it's
// "processed" view of the world, and we want the data raw after the headers
inputStream = new BufferedStream(socket.GetStream());
// we probably shouldn't be using a streamwriter for all output from handlers either
outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));
try
{
parseRequest();
readHeaders();
if (http_method.Equals("GET"))
{
handleGETRequest();
}
else if (http_method.Equals("POST"))
{
handlePOSTRequest();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.ToString());
writeFailure();
}
outputStream.Flush();
// bs.Flush(); // flush any remaining output
inputStream = null; outputStream = null; // bs = null;
socket.Close();
}
public void parseRequest()
{
String request = streamReadLine(inputStream);
string[] tokens = request.Split(' ');
if (tokens.Length != 3)
{
throw new Exception("invalid http request line");
}
http_method = tokens[0].ToUpper();
http_url = tokens[1];
http_protocol_versionstring = tokens[2];
Console.WriteLine("starting: " + request);
}
public void readHeaders()
{
Console.WriteLine("readHeaders()");
String line;
while ((line = streamReadLine(inputStream)) != null)
{
if (line.Equals(""))
{
Console.WriteLine("got headers");
return;
}
int separator = line.IndexOf(':');
if (separator == -1)
{
throw new Exception("invalid http header line: " + line);
}
String name = line.Substring(0, separator);
int pos = separator + 1;
while ((pos < line.Length) && (line[pos] == ' '))
{
pos++; // strip any spaces
}
string value = line.Substring(pos, line.Length - pos);
Console.WriteLine("header: {0}:{1}", name, value);
httpHeaders[name] = value;
}
}
public void handleGETRequest()
{
srv.handleGETRequest(this);
}
private const int BUF_SIZE = 4096;
public void handlePOSTRequest()
{
// this post data processing just reads everything into a memory stream.
// this is fine for smallish things, but for large stuff we should really
// hand an input stream to the request processor. However, the input stream
// we hand him needs to let him see the "end of the stream" at this content
// length, because otherwise he won't know when he's seen it all!
Console.WriteLine("get post data start");
int content_len = 0;
MemoryStream ms = new MemoryStream();
if (this.httpHeaders.ContainsKey("Content-Length"))
{
content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);
if (content_len > MAX_POST_SIZE)
{
throw new Exception(
String.Format("POST Content-Length({0}) too big for this simple server",
content_len));
}
byte[] buf = new byte[BUF_SIZE];
int to_read = content_len;
while (to_read > 0)
{
Console.WriteLine("starting Read, to_read={0}", to_read);
int numread = this.inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read));
Console.WriteLine("read finished, numread={0}", numread);
if (numread == 0)
{
if (to_read == 0)
{
break;
}
else
{
throw new Exception("client disconnected during post");
}
}
to_read -= numread;
ms.Write(buf, 0, numread);
}
ms.Seek(0, SeekOrigin.Begin);
}
Console.WriteLine("get post data end");
srv.handlePOSTRequest(this, new StreamReader(ms));
}
public void writeSuccess()
{
outputStream.WriteLine("HTTP/1.0 200 OK");
outputStream.WriteLine("Content-Type: text/html");
outputStream.WriteLine("Connection: close");
outputStream.WriteLine("");
}
public void writeFailure()
{
outputStream.WriteLine("HTTP/1.0 404 File not found");
outputStream.WriteLine("Connection: close");
outputStream.WriteLine("");
}
}
public abstract class HttpServer
{
public string JsonData
{
get;
set;
}
protected int port;
TcpListener listener;
bool is_active = true;
public HttpServer(int port)
{
this.port = port;
}
public void listen()
{
listener = new TcpListener(port);
listener.Start();
while (is_active)
{
TcpClient s = listener.AcceptTcpClient();
HttpProcessor processor = new HttpProcessor(s, this);
Thread thread = new Thread(new ThreadStart(processor.process));
thread.Start();
Thread.Sleep(1);
}
}
public abstract void handleGETRequest(HttpProcessor p);
public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);
}
public class MyHttpServer : HttpServer
{
public MyHttpServer(int port): base(port)
{
}
public override void handleGETRequest(HttpProcessor p)
{
//Console.WriteLine("request: {0}", p.http_url);
p.writeSuccess();
}
public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
{
Console.WriteLine("POST request: {0}", p.http_url);
string data = inputData.ReadToEnd();
JsonData = data;
}
}
HttpServer httpServer = null;
Json jsonConvert = new Json();
/// <summary>
/// Service监听接收端口port的信息。
/// </summary>
public void startService(int port)
{
try
{
LogHelper.Debug("KeenRay.HTTP.Client.cs::startService() Service响应的端口号 = " + port.ToString());
httpServer = new MyHttpServer(port);
Thread thread = new Thread(new ThreadStart(httpServer.listen));
thread.IsBackground = true;
thread.Start();
}
catch(Exception ex)
{
LogHelper.Error("KeenRay.HTTP.Client.cs::startService() Service监听异常,请查看是否有可用的端口号 = " + ex.ToString());
}
}
///<summary>
/// 启动Service,接收端口port的信息。
/// </summary>
public void ServiceResponse()
{
try
{
bool blJsonDataIsNull = false;
httpServer.JsonData = null;//一旦次线程接收到Json信息,就会给这个JsonData赋值。
while (!blJsonDataIsNull)
{
Thread.Sleep(50);
LogHelper.Debug("KeenRay.HTTP.HttpService.cs::ServiceResponse() 当前Service端while之内 响应的信息 = " + httpServer.JsonData);
if (httpServer.JsonData != null)//接收到的信息
{
blJsonDataIsNull = true;
serviceResponseInfoList = ServiceResponseInfoConvertToJson(httpServer.JsonData);
}
}
httpCallBackFunDelegate();
}
catch(Exception ex)
{
LogHelper.Error("KeenRay.HTTP.Client.cs::startService()图像智能识别URL响应异常,请查端口是否一致、或Json数据格式是否正确" + ex.ToString());
}
}
/// <summary>
/// 1、Service接收的Json信息后,反序列化,将受到的信息转成 Service数据结构。
/// 2、以下注释的代码,建议保留。
/// </summary>
/// <param name="strReponseJsonData"></param>
/// <returns></returns>
public List<ServiceResponseInfoStruct> ServiceResponseInfoConvertToJson(string strReponseJsonData)
{
List<ServiceResponseInfoStruct> ServiceResponseInfoStructList = new List<ServiceResponseInfoStruct>();
try
{
//LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之前,不带转义字符响应的信息 = " + strReponseJsonData);
//strReponseJsonData = strReponseJsonData.Replace("\\", "\\\\");
strReponseJsonData = "[" + strReponseJsonData + "]";
//LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之前,带转义字符响应响应的信息 = " + strReponseJsonData);
ServiceResponseInfoStructList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ServiceResponseInfoStruct>>(strReponseJsonData);//反序列化:将Json数据转成数组。
if (ServiceResponseInfoStructList.Count == 0)
{
return ServiceResponseInfoStructList;
}
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList.imagePath = " + ServiceResponseInfoStructList[0].imagePath);
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList.message = " + ServiceResponseInfoStructList[0].message);
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList.source = " + ServiceResponseInfoStructList[0].source);
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList.status_code = " + ServiceResponseInfoStructList[0].status_code);
if (ServiceResponseInfoStructList[0].data != null)
{
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() ServiceResponseInfoStructList[0].data 不为空");
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList[0].data.abnormal_score = " + ServiceResponseInfoStructList[0].data.abnormal_score.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList[0].data.cost = " + ServiceResponseInfoStructList[0].data.cost.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList[0].data.is_normal = " + ServiceResponseInfoStructList[0].data.is_normal.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList[0].data.is_pa = " + ServiceResponseInfoStructList[0].data.is_pa.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, ServiceResponseInfoStructList[0].data.detect_list的大小 = " + ServiceResponseInfoStructList[0].data.detect_list.Count);
int count = 0;
foreach (DetectList temp in ServiceResponseInfoStructList[0].data.detect_list)
{
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后," + "第" + count.ToString() + "个疾病的数据");
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, detect_list" + "[" + count + "]");
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.disease = " + temp.disease.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.width = " + temp.width.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.height = " + temp.height.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.prob = " + temp.prob.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.x1 = " + temp.x1.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.y1 = " + temp.y1.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.x2 = " + temp.x2.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.y2 = " + temp.y2.ToString());
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后, temp.prob = " + temp.prob.ToString());
if (temp.contour.GetLength(0) > 0)
{
for (int i = 0; i < temp.contour.GetLength(0); i++)
{
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后," + "第" + count.ToString() + "个疾病的轮廓坐标:temp.contour" + "[" + i.ToString() + "]" + "(x,y)= " + "(" + temp.contour[i, 0].ToString() + "," + temp.contour[i, 1].ToString() + ")");
}
}
else
{
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后," + "第" + count.ToString() + "个疾病的轮廓坐标无数据");
}
if (temp.mask_points.Count > 0)
{
for (int i = 0; i < temp.mask_points.Count; i++)
{
string x = temp.mask_points[i].x.ToString();
string y = temp.mask_points[i].y.ToString();
string value = temp.mask_points[i].value.ToString();
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后," + "第" + count.ToString() + "个疾病的热力图坐标:temp.mask_points" + "[" + i.ToString() + "]" + "(x, y,value) = " + "(" + x + "," + y + "," + value + ")");
}
}
else
{
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service解析之后," + "第" + count.ToString() + "个疾病的热力图坐标无数据");
}
count++;
}
}
else
{
LogHelper.Debug("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() ServiceResponseInfoStructList[0].data 为空");
}
}
catch (Exception ex)
{
LogHelper.Error("KeenRay.HTTP.Jcon.cs::ServiceResponseInfoConvertToJson() Service无法解析,解析Json数据发生错误 = " + ex.ToString());
}
return ServiceResponseInfoStructList;
}
}
第四章、Json序列化总结
不得不说,结合前面几篇博客https://blog.csdn.net/xpj8888/article/category/8884986,对Json的理解更高了一步。但我们还需要注意C#如何构造数据结构,这样才能完美地对Json数据进行序列化和反序列化。因此,我们要注意的以下问题。
4.1、序列化
- 请求的数据结构clientRequestInfoStruct,要与第三方的API的数据结构一致。
- 数据结构clientRequestInfoStruct字段不分先后顺序。
- 数据结构clientRequestInfoStruct字段区分大小写,比如clientRequestInfoStruct.callback.url不能写成clientRequestInfoStruct.callback.URL。
- 数据结构clientRequestInfoStruct字段的赋值,也分大小写。比如clientRequestInfoStruct.image.method = "local"不能写成clientRequestInfoStruct.image.method = "Local"。
- 若是数据结构clientRequestInfoStruct的字段是自定义的字段,必然要进行初始赋值。比如 ClientRequestInfoStruct clientRequestInfoStruct = new ClientRequestInfoStruct();
Callback callback = new Callback();
Image image = new Image();
clientRequestInfoStruct.callback = callback;
clientRequestInfoStruct.image = image;
4.2、反序列化
- 必须用泛型数组List<ServiceResponseInfoStruct> ServiceResponseInfoStructList才能反序列化。该类的列表元素,也是如此。
- 该用int型数组public int[,] contour { get; set; }时候,不要写成泛型数组,不然会出错。
- 注意数据结构的字段数目。
- 注意数据结构的字段属性,比如不要把int类型写成string、float等等类型。
- 注意初始化数据结构的对象,比如data 对象就需要进行初始化 public Data data = new Data();
- 注意初始化数据结构的字段名称的大小写,要与Json数据相应的字段一一对应,差一点都不行。
- 数据结构的字段位置,无前后之分。
- 若你的反序列有问题,你可以先验证JSON数据 https://www.json.cn 的无误后,然后再自己建一个demo进行测试。
- 本文,已在医学Dicom图的AI诊断上,进行实际项目中应用。