REST服务器(六)C# Json序列化与反序列化

目录

第一章、异常问题

1.1、序列化

1.2、反序列化

1.2.1、问题一

 1.2.2、问题二

第二章、解决办法

2.1、办法一(解决问题一)

2.2、办法二(解决问题二)

第三章、实用的DEMO

3.1、Json.cs:

3.2、HttpClient.cs:

3.3、HttpService.cs:

第四章、Json序列化总结

4.1、序列化

4.2、反序列化



第一章、异常问题

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、序列化

  1. 请求的数据结构clientRequestInfoStruct,要与第三方的API的数据结构一致。
  2. 数据结构clientRequestInfoStruct字段不分先后顺序。
  3. 数据结构clientRequestInfoStruct字段区分大小写,比如clientRequestInfoStruct.callback.url不能写成clientRequestInfoStruct.callback.URL。
  4. 数据结构clientRequestInfoStruct字段的赋值,也分大小写。比如clientRequestInfoStruct.image.method = "local"不能写成clientRequestInfoStruct.image.method = "Local"。
  5. 若是数据结构clientRequestInfoStruct的字段是自定义的字段,必然要进行初始赋值。比如                        ClientRequestInfoStruct clientRequestInfoStruct = new ClientRequestInfoStruct();
    Callback callback = new Callback();
    Image image = new Image();
    clientRequestInfoStruct.callback = callback;
    clientRequestInfoStruct.image = image;

4.2、反序列化

  1. 必须用泛型数组List<ServiceResponseInfoStruct> ServiceResponseInfoStructList才能反序列化。该类的列表元素,也是如此。
  2. 该用int型数组public int[,] contour { get; set; }时候,不要写成泛型数组,不然会出错。
  3. 注意数据结构的字段数目。
  4. 注意数据结构的字段属性,比如不要把int类型写成string、float等等类型。
  5. 注意初始化数据结构的对象,比如data 对象就需要进行初始化 public Data data = new Data();
  6. 注意初始化数据结构的字段名称的大小写,要与Json数据相应的字段一一对应,差一点都不行
  7. 数据结构的字段位置,无前后之分。
  8. 若你的反序列有问题,你可以先验证JSON数据 https://www.json.cn 的无误后,然后再自己建一个demo进行测试。
  9. 本文,已在医学Dicom图的AI诊断上,进行实际项目中应用。

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Django中,序列序列是指将数据转换为特定格式以便传输或存储,并将特定格式的数据转换为模型对象的过程。 在开发REST API接口时,序列序列是非常重要的步骤。在视图中,我们需要将数据库中的数据序列为前端所需要的格式,并返回给前端;同时,我们也需要将前端发送的数据序列为模型类对象,并保存到数据库中。这样可以方便地处理数据的传输和存储。[1] 在Django REST framework中,我们可以使用序列器来定义数据的序列序列过程。序列器是一个类,可以定义需要序列序列的字段。例如,我们可以定义一个BookInfoSerializer序列器,其中包含需要序列序列的字段,如btitle、bpub_date和bread。[2] 在进行序列时,如果要序列的是包含多条数据的查询集QuerySet,可以通过添加many=True参数来说明。这样可以将查询集中的每个对象序列为特定格式的数据,并返回一个包含所有序列对象的列表。[3] 总结起来,序列序列是在开发REST API接口时非常重要的步骤。通过序列器,我们可以将数据库中的数据序列为前端所需要的格式,并返回给前端;同时,我们也可以将前端发送的数据序列为模型类对象,并保存到数据库中。这样可以方便地处理数据的传输和存储。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值