api post 请求纪要

不用抓包工具,返回错误信息不够全面,在此次测试中也就返回了status的415 和error错误  ,而没有类似下边wireshark抓包返回的信息 还隐藏着message这个信息

{"timestamp":"2020-08-27T03:51:50.524+0000","status":415,"error":"Unsupported Media Type","message":"Invalid mime type "Content-Type: application/json": Invalid token character ':' in token "Content-Type: application"","path":"/app/user/login"}HTTP/1.1 100 Continue

尽管上边你的415提示的是媒体格式问题,因为还有json格式,以及对post 的使用不够深刻,也没进一步锁定问题,最终通过上边出现的 Content-Type,发现方法里边的 配置出现问题

正确: request.ContentType = "application/json";

错误: request.ContentType = "Content-Type: application/json";  //重复的写了content-type

出现报错

粘来粘去的代码,一不留神就出了问题

fiddler 抓web 包 抓不着软件里边的请求,所以改用wireshark

 

 正确的返回

 request.ContentType = "application/json"; 类型的post请求方法

  /// <summary>
            /// 向指定 URL 发送POST方法的请求
            /// </summary>
            /// <param name="url">发送请求的 URL</param>
            /// <param name="jsonData">请求参数,请求参数应该是Json格式字符串的形式。</param>
            /// <returns>所代表远程资源的响应结果</returns>
            public static string SendPost(string url, string jsonData)

            {
                string result = String.Empty;
                try
                {
                    CookieContainer cookie = new CookieContainer();

                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = "POST";
                    //request.Headers.Add("x-requested-with", "XMLHttpRequest");
                    //request.ServicePoint.Expect100Continue = false;
                    request.ContentType = "application/json";
                    request.Accept = "application/json";
                    //request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)";
                    request.ContentLength = Encoding.UTF8.GetByteCount(jsonData);
                    request.CookieContainer = cookie;
                    using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                    {
                        writer.Write(jsonData);
                    }

                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    response.Cookies = cookie.GetCookies(response.ResponseUri);
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            result = reader.ReadToEnd();

                            reader.Close();
                        }
                        responseStream.Close();
                    }
                    response.Close();
                    response = null;
                    request = null;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("发送GET请求出现异常:" + ex.Message);
                }
                return result;
            }

参数 jsonData 可以先定义一个实体类 通过 JsonConvert.SerializeObject(lg);  转换成json 格式

string jslg= JsonConvert.SerializeObject(lg); 
string result= SendPost(url, jslg);

有些api  对于时间来说有的直接甩过来一个时间戳,鉴于每个人存数据库的时间格式不同习惯, 对于时间戳的格式, jsonconvert 经过一些搜索,没有找到在转换过程中的强制格式,只有在序列化时有,在deserrializeobject 没有

所以需要实体对象之间的转换,大大降低了效率,复制黏贴,头大

如果反射用的熟练可以反射两个实体类, 进行类型相同, 属性名相同进行赋值, 时间格式那块可以在反射方法内 循环时碰到相关属性名给转换成格式

用反射的方式, 必须两个实体类的 字段定义必须相同, 因为反射中是通过字段的名字字符串判断两个字段是否相同. 

1.适用于创建实体的时候从一个实体作为数据源赋值
 /// <summary>
        /// 反射实现两个类的对象之间相同属性的值的复制
        /// 适用于初始化新实体
        /// </summary>
        /// <typeparam name="D">返回的实体</typeparam>
        /// <typeparam name="S">数据源实体</typeparam>
        /// <param name="s">数据源实体</param>
        /// <returns>返回的新实体</returns>
        public static D Mapper<D, S>(S s)
        {
            D d = Activator.CreateInstance<D>(); //构造新实例
            try
            {
                var Types = s.GetType();//获得类型  
                var Typed = typeof(D);
                foreach (PropertyInfo sp in Types.GetProperties())//获得类型的属性字段  
                {
                    foreach (PropertyInfo dp in Typed.GetProperties())
                    {
                        if (dp.Name == sp.Name && dp.PropertyType == sp.PropertyType && dp.Name!= "Error" && dp.Name != "Item")//判断属性名是否相同  
                        {
                            dp.SetValue(d, sp.GetValue(s, null), null);//获得s对象属性的值复制给d对象的属性  
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return d;
        }

2.适用于没有创建实体,两个实体之间数据的转换

  /// <summary>
        /// 反射实现两个类的对象之间相同属性的值的复制
        /// 适用于没有新建实体之间
        /// </summary>
        /// <typeparam name="D">返回的实体</typeparam>
        /// <typeparam name="S">数据源实体</typeparam>
        /// <param name="d">返回的实体</param>
        /// <param name="s">数据源实体</param>
        /// <returns></returns>
        public static D MapperToModel<D, S>(D d,S s)
        {
            try
            {
                var Types = s.GetType();//获得类型  
                var Typed = typeof(D);
                foreach (PropertyInfo sp in Types.GetProperties())//获得类型的属性字段  
                {
                    foreach (PropertyInfo dp in Typed.GetProperties())
                    {
                        if (dp.Name == sp.Name && dp.PropertyType == sp.PropertyType && dp.Name != "Error" && dp.Name != "Item")//判断属性名是否相同  
                        {
                            dp.SetValue(d, sp.GetValue(s, null), null);//获得s对象属性的值复制给d对象的属性  
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return d;
        }
原文地址:https://www.cnblogs.com/zuochanzi/p/13570731.html