C#解析Json数据,常用的方法:
1、将双引号替换为单引号。
2、https://www.cnblogs.com/silverbullet11/p/DotNet_JSON_Serialization.html+http://www.bejson.com/convert/json2csharp/
一、简介
本文将介绍详细的REST请求/响应。比如请求的格式。
参考 https://www.cnblogs.com/xuliangxing/p/8735552.html (重点)C# 服务端篇之实现RestFul Service开发(简单实用)
/// <summary>
/// 请求类型:REST采用的是HTTP协议并通过HTTP中的GET、POST、PUT、DELETE等动词收发数据。
/// </summary>
public enum EnumHttpVerb
{
GET,
POST,
PUT,
DELETE
}
public RestClient(string endpoint, EnumHttpVerb method, string postData)
{
EndPoint = endpoint;
Method = method;
ContentType = "application/json";
PostData = postData;
}
你也可以参考别人的博客,看看别人是怎么Post请求的
http://www.cnblogs.com/jianyus/p/10101867.html
https://blog.csdn.net/sayesan/article/details/78476396
https://www.cnblogs.com/Andy-Blog/p/5666180.html
二、Post请求
2.1、REST服务器Post请求的格式
Post请求是REST服务器最常用的请求。它的请求格式一般为
public RestClient(string postData)
{
EndPoint = "192.168.1.1:80000";
Method = POST;
ContentType = "application/json";
PostData = postData;
}
其他三个参数,就是这样写。那么我们要弄明白postData的格式是怎么样的。
2.2.Json格式的数据(Post请求,postData一般是Json格式的数据)
2.1.1、样本1(C# 双引号)
Json数据:
"{\"Age\":25,\"ID\":3,\"Name\":\"王二麻子\",\"Score\":59}"
样本1可以看出以下问题:
A、名称是字符串,使用双引号表示。
\"Age\"
B、值用数字或字符串表示,在分号与逗号之间。如下所示
:25,
或者
:\"王二麻子\",
2.1.2、样本2(C# 双引号)
https://www.cnblogs.com/tech-bird/p/3588430.html
string testJson = "{\"Name\" : \"战神\",\"ByName\" : [\"男\",\"女\",\"人妖\"],\"Education\":{\"GradeSchool\" : \"第一小学\",\"MiddleSchool\" : [\"第一初中\" , \"第一高中\"], \"University\" :{ \"Name\" : \"清华\", \"Grand\" : [\"一年级\",\"二年级\"]}}}";
样本2可以看出以下问题:
A、数组表示用中括号。其他的功能与样本1一样。
2.1.3、样本3(C# 双引号)
2.3.Json格式数据的读写
https://blog.csdn.net/coolszy/article/details/8606803
https://www.cnblogs.com/cdz-sky/p/4528556.html
http://www.cnblogs.com/zhuxiaoge/p/7095960.html(重点)
2.3.1、读Json数据
(C#,单引号)
#region Josn数据的读写 http://www.cnblogs.com/zhuxiaoge/p/7095960.html
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using test;
namespace QueueSample
{
class Program
{
public class Info
{
public string phantom { get; set; }
public string id { get; set; }
public data data { get; set; }
}
public class data
{
public int MID { get; set; }
public string Name { get; set; }
public string Des { get; set; }
public string Disable { get; set; }
public string Remark { get; set; }
}
static void Main(string[] args)
{
string json = @"[{'phantom':true,'id':'20130717001','data':{'MID':1019,'Name':'aaccccc','Des':'cc','Disable':'启用','Remark':'cccc'}}]";
List<Info> jobInfoList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Info>>(json);//反序列化:将Json数据转成数组。
foreach (Info jobInfo in jobInfoList)
{
Console.WriteLine("UserName:" + jobInfo.id);
Console.WriteLine("UserName:" + jobInfo.data.MID);
}
Console.ReadLine();
}
}
}
#endregion
(C#,双引号+转义字符)
C#的Json数据,一定是带有字符的,比如https://jingyan.baidu.com/article/9faa7231fb8d8f473c28cbb0.html
那么我们常常需要解决转义字符等等特殊字符问题,比如http://www.cnblogs.com/wuyujie/p/7656488.html
2.3.2、写Json数据
JsonConvert.SerializeObject() 用该函数序列化即可。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace RestFulClient
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Restful客户端Demo测试";
RestClient client = new RestClient();
client.EndPoint = @"http://192.168.96.227:7788/";
//client.EndPoint = @"http://127.0.0.1:8000/";
client.Method = EnumHttpVerb.GET;
string resultGet = client.HttpRequest("PersonInfoQuery/王二麻子");
Console.WriteLine("GET方式获取结果:" + resultGet);
client.Method = EnumHttpVerb.POST;//POST请求。
Info info = new Info();//
info.ID = 1;
info.Name = "";
client.PostData = JsonConvert.SerializeObject(info);//JSon序列化我们用到第三方Newtonsoft.Json.dll//Json请求。
var resultPost = client.HttpRequest("PersonInfoQuery/Info");
Console.WriteLine("POST方式获取结果:" + resultPost);
//RestClient client = new RestClient();
//client.EndPoint = @"http://192.168.96.192:8000"; //请求IP和端口
//client.Method = EnumHttpVerb.GET;//请求类型:获取参数
//string RequestParameter = @"D:\TestImages\DRTestImages\z.dcm" + "http://localhost:/api/v1/ai_task";
//string resultGet = client.HttpRequest(RequestParameter);//本地图片路径 + 回调的URL
//Console.WriteLine("GET方式获取结果:" + resultGet);
Console.Read();
}
}
[Serializable]
public class Info
{
public int ID { get; set; }
public string Name { get; set; }
}
}
2.4、验证Json数据(至关重要)
C#里面,有人用单引号表示Json数据,有人用双引号表示Json数据。到底哪种格式才是正确的,可以确定的是,正确的Json格式数据,一定可以通过Json在线数据验证网址https://www.json.cn 来验证。
2.4.1、验证带双引号的Json数据
{"imagePath": "e:\\bin\\DiCom\\z.dcm", "data": {"is_negative": false, "is_normal": false, "disease_list": ["Infiltration", "Mass", "Nodule", "Pneumothorax", "Consolidation", "Emphysema", "Fibrosis", "Pleural_Thickening", "abnormal"], "detect_list": [{"prob": 1.0, "x1": 2138, "y1": 1236, "x2": 2193, "y2": 1297, "width": 55, "height": 61, "disease": "Nodule"}, {"prob": 0.99, "x1": 1016, "y1": 1333, "x2": 1096, "y2": 1451, "width": 80, "height": 118, "disease": "Nodule"}, {"prob": 0.99, "x1": 777, "y1": 747, "x2": 843, "y2": 824, "width": 66, "height": 77, "disease": "Nodule"}, {"prob": 0.98, "x1": 857, "y1": 1066, "x2": 943, "y2": 1150, "width": 86, "height": 84, "disease": "Nodule"}, {"prob": 0.96, "x1": 1803, "y1": 634, "x2": 2306, "y2": 1029, "width": 503, "height": 395, "disease": "Pneumonia"}, {"prob": 0.95, "x1": 1162, "y1": 1837, "x2": 1305, "y2": 1941, "width": 143, "height": 104, "disease": "Mass"}]}, "status_code": 1000}
2.4.2、验证单引号的Json数据(显然不行)
[{'phantom':true,'id':'20130717001','data':{'MID':1019,'Name':'aaccccc','Des':'cc','Disable':'启用','Remark':'cccc'}}]
2.4.3、那么C#里面用单引号还是双引号的格式,提取Json数据到数据结构中的呢?
其实在2.3.1、读Json数据(C#,单引号)小结中,已经可以成功地提取单引号的Json数据。下面来说说如何提取双引号的Json数据。
结论1:经过我多次尝试,发现了C#的Json数据,是带有转移字符的。
结论2:C#带双引号的Json数据的字符,必须带转义字符。输出到控制台后,才变成无转义字符的字符串。
结论3:C#中,只有带转义字符的Json数据的字符串,才能被正常解析。
结论4:C#中,路径字符串带有两个斜杠,把它转成四个斜杆才能正确输出。比如
string json82 = "[{\"imagePath\": \"e:\\\\bin\\\\DiCom\\\\z.dcm\", \"status_code\": 1000}]";
控制台输出:
json82被解析后:
imagePath:e:\bin\DiCom\z.dcm
status_code:1000
那么以后,在C#里面,我们就用带双引号+转义字符的形式来解析Json数据。见2.3.1小结。
那么以后,在C#里面,我们就用带双引号+转义字符的形式来解析Json数据。见2.3.1小结。
那么以后,在C#里面,我们就用带双引号+转义字符的形式来解析Json数据。见2.3.1小结。
那么以后,在C#里面,我们就用带双引号+转义字符的形式来解析Json数据。见2.3.1小结。
那么以后,在C#里面,我们就用带双引号+转义字符的形式来解析Json数据。见2.3.1小结。
三、HttpReques的Post请求
之前接收了请求格式,即请求的常用几个参数,包括了EndPoint、Method、ContentType、PostData。那么我们怎么把这几个参数放到了HttpRequest中。
3.1、样本
3.1.1、样本1
/// <summary>
/// http请求(带参数)
/// </summary>
/// <param name="parameters">parameters例如:?name=LiLei</param>
/// <returns></returns>
public string HttpRequest(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create(EndPoint + 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;
}
}
下面的代码,重点是 var request = (HttpWebRequest)WebRequest.Create(EndPoint + parameters);这行的参数。如若是只参考一个样本,还不知道它是什么意思。
接下来,我们参考多个样本。
3.1.2、样本2
https://blog.csdn.net/wangkailin9325/article/details/83010203
string _url = "http://192.168.0.135:888/sqjz/fxry/fxry/up";
string jsonParam = "{\"sqjzrybh\":\"A001\",\"sfzh\":\"130533196874589652\",\"xm\":\"王涛\"}";
var request = (HttpWebRequest)WebRequest.Create(_url);
request.Method = "POST";
request.ContentType = "application/json;charset=UTF-8";
var byteData = Encoding.UTF8.GetBytes(jsonParam);
var length = byteData.Length;
request.ContentLength = length;
var writer = request.GetRequestStream();
writer.Write(byteData, 0, length);
writer.Close();
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")).ReadToEnd();
MessageBox.Show(responseString.ToString());
可以看出,var request = (HttpWebRequest)WebRequest.Create(_url);传入参数就是你要访问的网址_url。
以上问题,已经全部阐明了http的Post请求的所有内容。在REST服务器请求中使用POST请求,够用了
以上问题,已经全部阐明了http的Post请求的重点内容。在REST服务器请求中使用POST请求,够用了
以上问题,已经全部阐明了http的Post请求的重点内容。在REST服务器请求中使用POST请求,够用了
3.2、在线Post/Json在线验证/Json转实体类
这几个工具一定要会用
http://coolaf.com验证Post数据的正确性
https://www.json.cn验证Json数据的正确性
http://www.bejson.com/convert/json2csharp/ Json转C#实体类
四、DEMO
4.1、Client(做客户端)
把工程的这个DEMO拿出来,给大家参考参考。我是在https://github.com/SunningPig/Restful-Service-And-Restful-Client/基础上进行修改的。
program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace RestFulClient
{
class Program
{
static void Main(string[] args)
{
/*访问算法无服务器*/
RestClient client = new RestClient();
//client.EndPoint = @"http://192.168.96.192:8000/";
client.EndPoint = @"http://92.168.96.192:8000/api/v1/ai_task";
client.Method = EnumHttpVerb.POST;//POST请求。
/* 1、Josn数据:JSon序列化我们用到第三方Newtonsoft.Json.dll
* 2、请求Josn数据:包括源图片地址、目标路径地址
*/
GetJsonData getJsonData = new GetJsonData();//
getJsonData.imagePath = @"D:\视见科技\DiCom\z.dcm";
getJsonData.callbackURL = @"http://92.168.96.192:8000/api/v1/ai_task";
client.PostData = JsonConvert.SerializeObject(getJsonData);
//请求连接的URL
var resultPost = client.HttpRequest(client.EndPoint);
Console.WriteLine("POST方式获取结果:" + resultPost);
Console.Read();
}
}
[Serializable]
public class GetJsonData
{
public string imagePath { get; set; }
public string callbackURL { get; set; }
}
}
RestClient.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
/************************************************************************************
* Autor:xuliangxing
* Email:907562392@qq.com
* WeChart:xuliangxing
* Version:V1.0.0.0
* CreateTime:2018/4/8 13:36:40
* Description:
* Company:
* Copyright © 2018 All Rights Reserved
************************************************************************************/
namespace RestFulClient
{
/// <summary>
/// 请求类型:REST采用的是HTTP协议并通过HTTP中的GET、POST、PUT、DELETE等动词收发数据。
/// </summary>
public enum EnumHttpVerb
{
GET,
POST,
PUT,
DELETE
}
public class RestClient
{
#region 属性
/// <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
#region 初始化
public RestClient()
{
EndPoint = "";
Method = EnumHttpVerb.GET;
ContentType = "application/json";
PostData = "";
}
public RestClient(string endpoint)
{
EndPoint = endpoint;
Method = EnumHttpVerb.GET;
ContentType = "application/json";
PostData = "";
}
public RestClient(string endpoint, EnumHttpVerb method)
{
EndPoint = endpoint;
Method = method;
ContentType = "application/json";
PostData = "";
}
public RestClient(string endpoint, EnumHttpVerb method, string postData)
{
EndPoint = endpoint;
Method = method;
ContentType = "application/json";
PostData = postData;
}
#endregion
#region 方法
/// <summary>
/// http请求(带参数)
/// </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 = 128 + 128;
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;
}
}
#endregion
}
}
4.2、做Service端
见我下一篇博客。此外,GitHub已经上传了Client、Service源码。