客户端和Web Api服务的交互

客户端(windows应用程序和Web)和Web Api交互的核心代码提炼

//★HTTP请求对象。

HttpRequestMessage requestMsg = new HttpRequestMessage();

//设置HTTP接收请求的数据类型为JSON

requestMsg.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

//请求数据的链接(Uri)例如:"http://10.186.3.xx/zl_server/api/[Controller]/[id]?XXX=XXX&..."

requestMsg.RequestUri = new Uri(strToRequest);



//★HTTP的内容对象

HttpContent content = null;

if(objToSend!=null)

//StringContent():转换成基于字符串的HTTP内容。

//JsonConvert.SerializeObject(objToSend):将实体对象序列化成JSON

content = new StringContent(JsonConvert.SerializeObject(objToSend), Encoding.UTF8, "application/json");





requestMsg.Method = HttpMethod.Get;//用于获取数据

requestMsg.Content = content;



//★HTTP客户端对象(用于发送HTTP请求和接收HTTP响应)

static readonly HttpClient s_httpClient = new HttpClient();

//s_httpClient是HttpClient的对象:用于发送HTTP请求和接收HTTP响应

//s_httpClient.SendAsync:发送一个HTTP请求一个异步操作,并返回响应结果。 

Task<HttpResponseMessage> rtnAll = s_httpClient.SendAsync(requestMsg);//这一步是核心,正式发出请求并获取响应的结果。



//★HTTP的响应对象(这一步是核心,正式发出请求并获取响应的结果)

HttpResponseMessage resultMessage =rtnAll.Result;





/*  ★这一步非常关键,是将服务器端响应的数据赋值给本地的过程。

 * resultMessage.Content.ReadAsAsync<NjtHttpInfo>(s_formatters)如何理解?

 * 解释:从响应的内容里异步读取,并赋值给指定的Model对象

 * new MediaTypeFormatter[] { new JsonMediaTypeFormatter() } 指定数据以Json格式化

*/

Task<T> rtnFinal = resultMessage.Content.ReadAsAsync<T>(new MediaTypeFormatter[] { new JsonMediaTypeFormatter() });



//如果HttpMethod.Get时 rtnFinal.Result这个就是Get获取的数据

return rtnFinal.Result;



//如果是HttpMethod.Post\HttpMethod.Put\HttpMethod.Delete的时候是不需要返回值的

return default(T);//default(T):返回 NULL

 客户端(windows应用程序和Web)和Web Api交互的完成的代码

//Get调用方法(集合列表)获取单条数据只需要后面加上“/id”

WebApiClientHelper.DoJsonRequest<SimUser_API_Get>("http://10.186.3.21/zl_server/api/entrance", EnuHttpMethod.Get);



//Post调用方法(新增)

WebApiClientHelper.DoJsonRequest<UsbDisk_API_Post>("http://10.186.3.21/zl_server/api/entrance", EnuHttpMethod.Post, objToSend: objToPost);



//Put调用方法(变更)

WebApiClientHelper.DoJsonRequest<User_API_Put>("http://10.186.3.21/zl_server/api/entrance/2", EnuHttpMethod.Put, objToSend: userPut, tick: userVm.UpdateTicks);

 

        /// <summary>

        /// 客户端与API服务的交互函数

        /// </summary>

        /// <typeparam name="T">T DoJsonRequest<T>中“T”是代表可变的参数,是根据传入的类型而定的可以是model类或是IEnumerable<T></typeparam>

        /// <param name="strUri">请求地址</param>

        /// <param name="method">请求类型(Get,Put,Post,Delete)</param>

        /// <param name="queryCondition">分页参数</param>

        /// <param name="objToSend">对象参数(一般用于Update的时候)</param>

        /// <param name="tick">变更时间</param>

        /// <returns></returns>

        public static T DoJsonRequest<T>(string strUri, EnuHttpMethod method, IUriConvertable queryCondition = null, Object objToSend = null, long tick = 0)

        {

            string strToRequest = strUri;



            if (tick != 0 && (method == EnuHttpMethod.Put || method == EnuHttpMethod.Delete))

                strToRequest += "?UpdateTicks=" + tick.ToString(CultureInfo.InvariantCulture);//CultureInfo.InvariantCulture的作用是为了固定格式



            if (queryCondition != null && method == EnuHttpMethod.Get)

                strToRequest += queryCondition.QueryString;



            //表示一个HTTP请求消息。

            HttpRequestMessage requestMsg = new HttpRequestMessage();

            //这一步是非对称的加密

            MakePrincipleHeader(requestMsg, strToRequest);

            //设置HTTP接收请求的数据类型为JSON

            requestMsg.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //请求数据的链接(Uri)

            requestMsg.RequestUri = new Uri(strToRequest);



            HttpContent content = null;

            

            if(objToSend!=null)

                //StringContent():转换成基于字符串的HTTP内容。

                //JsonConvert.SerializeObject(objToSend):将实体对象序列化成JSON

                content = new StringContent(JsonConvert.SerializeObject(objToSend), Encoding.UTF8, "application/json");



            switch (method)

            {

                case EnuHttpMethod.Post:

                    requestMsg.Method = HttpMethod.Post;//Post用于新增

                    requestMsg.Content = content;

                    break;

                case EnuHttpMethod.Put:

                    requestMsg.Method = HttpMethod.Put;//Put用于修改

                    requestMsg.Content = content;

                    break;

                case EnuHttpMethod.Delete:

                    requestMsg.Method = HttpMethod.Delete;

                    break;

                default: //EnuHttpMethod.Get:

                    requestMsg.Method = HttpMethod.Get;//Get用于获取

                    break;

            }

            //s_httpClient是HttpClient的对象:用于发送HTTP请求和接收HTTP响应

            //s_httpClient.SendAsync:发送一个HTTP请求一个异步操作,并返回响应结果。 

            Task<HttpResponseMessage> rtnAll = s_httpClient.SendAsync(requestMsg);



            #region 执行

            HttpResponseMessage resultMessage = null;

            Task<T> rtnFinal;



            try

            {

                try

                {
           //这一步是关键提交请求的过程,rtnAll.Result这里其实是一个多线程的处理,是.Net Framework 4.0的新特性之一 resultMessage
= rtnAll.Result; } catch (AggregateException ae) { foreach (var ex in ae.InnerExceptions) { if (ex is HttpRequestException) { throw new NjtCsException("发送网络请求失败", ex); } } } if (!resultMessage.IsSuccessStatusCode)//判断响应是否成功? { Task<NjtHttpInfo> error; try { /* * resultMessage.Content.ReadAsAsync<NjtHttpInfo>(s_formatters)如何理解? * 解释:从响应的内容里异步读取,并赋值给指定的Model对象 * s_formatters:就是new MediaTypeFormatter[] { new JsonMediaTypeFormatter() } 指定数据以Json格式化 */ error = resultMessage.Content.ReadAsAsync<NjtHttpInfo>(s_formatters); } catch (Exception ex) { throw new NjtCsException("服务器意外错误", ex); } throw new NjtCsException(error.Result.Message); } if (method!=EnuHttpMethod.Get) { return default(T);//default(T):返回 NULL(除了Get方式是需要获取值的,其他方式都不需要返回响应结果) } try { /* ★这一步非常关键,是将服务器端响应的数据赋值给本地的过程。 * resultMessage.Content.ReadAsAsync<NjtHttpInfo>(s_formatters)如何理解? * 解释:从响应的内容里异步读取,并赋值给指定的Model对象 * s_formatters:就是new MediaTypeFormatter[] { new JsonMediaTypeFormatter() } 指定数据以Json格式化 */ rtnFinal = resultMessage.Content.ReadAsAsync<T>(s_formatters); } catch (Exception ex) { throw new NjtCsException("服务器返回与请求不匹配", ex); } } catch (NjtCsException njtex) { njtex.ParameterObject = new { Uri = strUri, Method = method, Data = objToSend, Tick = tick }; throw; } #endregion return rtnFinal.Result; }

 

你可能感兴趣的:(Web)