横去年底展望是一个且并未兑现。反正去年之展望是一个且没有兑现。

   以随后写Asp.Net
WebApi核心目标解析(下篇)之前,还是一如既往的扯扯淡,元旦刚刚过,整个人还是处于昏沉的状态,一大早尽管来处理体系BUG,简直是坑爹(好于没有叫自家元旦赶过来该BUG),队友挖的坑,还吃自己含在泪水去填。改BUG前看队友写的代码,这里就未评了,反正是止改边骂,我的嘴便无平息了,作为开发者,我那时的心情,就不再描述了,反正是摸索不至一个好词形容。

   在随后写Asp.Net
WebApi核心目标解析(下篇)之前,还是一如既往的扯扯淡,元旦刚好过,整个人或者处于昏沉的状态,一大早就来处理体系BUG,简直是坑爹(好以没有给自家元旦赶过来该BUG),队友挖的坑,还被自己含着泪水去填。改BUG前看队友写的代码,这里虽不评说了,反正是边改边骂,我的嘴巴便从来不停了,作为开发者,我那时候的心境,就不再描述了,反正是摸索不顶一个好词形容。

 
 新年展望,我感到自己是从来不啥好展望的,反正去年底展望是一个还未曾兑现,事情该怎么开要怎么开的,估计大多数人数以及自身差不多,任何事非可知强迫,事前极力去收拾,事后得不顶为尽管看淡一点,太苛求,迟早身心俱疲。

 
 新年展望,我感到自我是从未啥好展望的,反正去年之展望是一个且尚未实现,事情该怎么开要怎么开的,估计大多数总人口与我差不多,任何事不克迫使,事前大力去处置,事后得无至啊就看淡一点,太苛求,迟早身心俱疲。

   扯淡了,接着聊正事,上同首写的是Asp.Net
WebApi核心目标解析(上篇),本文是下篇,不管写的怎么,还向大家多多指正。

   扯淡了,接着聊正事,上同篇写的是Asp.Net
WebApi核心目标解析(上篇),本文是下篇,不管写的什么样,还往大家多多指正。

一.WebApi处理架构:

    我们在求学Asp.Net WebApi时,应该对Asp.Net
WebApi的内运行机制有一个大概的垂询,很多口说了解这些基本原理的意思不怪,实际付出中以不至并且还浪费时间,这样说发自然的道理,但是只要我们的看法放的一劳永逸有,就非会见如此想聊,我们询问基本原理后,可以以定之水准达到扶持我们处理局部序底层的bug,而且还有好被咱们从中学会思考,去深入的理解设计者的图,有利于我们越来越得心应手的动。

   
在谈WebApi处理架构之前,我们或来拘禁一下微软为WebApi提供的海报,这里就是非将图了,需要看之得点击下载:下载地址

    Asp.Net Web
Api处理架构可以分成三交汇,分别是托管层、消息处理程序管道、控制器处理。

       托管层:位于WebApi和底HTTP栈之间,是极其底部负责WebApi托管。

       信息处理程序管道层:用同贯彻信息之横切关注点,例如日志与缓存。

     
 控制器处理层:控制器和操作是以即时无异重合进行调用,参数还绑定和验证,HTTP响应消息啊当这边创办。

   
对于托管层测说明,会以下面进行讲解。消息处理程序是对准一个操作的抽象,它接受HTTP请求消息并回到HTTP响应消息。连接消息处理程序管道与控制器处理层的桥是控制器分发程序。控制器分发或一个音处理程序,主要是挑选、创建同调用正确的控制器来拍卖要。

一.WebApi处理架构:

    我们于求学Asp.Net WebApi时,应该对Asp.Net
WebApi的其中运行机制有一个大概的询问,很多口说了解这些基本原理的意思不坏,实际开支中使用不至并且还浪费时间,这样说生肯定的道理,但是倘若我们的看法放的遥远有,就非会见如此想聊,我们询问基本原理后,可以以定之档次达到扶持我们处理局部序底层的bug,而且还有好让咱们从中学会思考,去深入之理解设计者的图,有利于我们越来越得心应手的采取。

   
在谈WebApi处理架构之前,我们或来拘禁一下微软为WebApi提供的海报,这里就是非将图了,需要看的可点击下载:下载地址

    Asp.Net Web
Api处理架构可以分成三叠,分别是托管层、消息处理程序管道、控制器处理。

       托管层:位于WebApi和底HTTP栈之间,是极底部负责WebApi托管。

       信息处理程序管道层:用同贯彻信息的横切关注点,例如日志与缓存。

     
 控制器处理层:控制器和操作是以当下等同重叠进行调用,参数还绑定和验证,HTTP响应消息啊当这边创办。

   
对于托管层测说明,会以下面进行讲解。消息处理程序是对准一个操作的抽象,它接受HTTP请求消息并返HTTP响应消息。连接消息处理程序管道与控制器处理层的桥是控制器分发程序。控制器分发或一个消息处理程序,主要是挑选、创建同调用正确的控制器来拍卖要。

二.WebApi托管方式分析:

    在Asp.Net Web
Api的托管方发出三种植,接下我们来大概了解一下即三栽托管方。

       (1).在任何Windows进程被由托管。

     
 (2).Web托管,即于IIS之上使用ASP.NET管道进行托管。(如果需要了解IIS和ASPI.NET管道的知,可以友善找寻查看,笔者建议召开web开发的口了解一下夫运行机制,有利于我们本着asp.net
web程序来一个深切之摸底。)

       (3).OWIN托管。(在一个owin兼容的服务器上成立一个webapi层)

   
 在使用web托管时,所下的凡ASP.NET的管道与路由功能,将HTTP请求转发到一个初的ASP.NET处理程序,HttpControllerHandler中。这个次接收及HtppRequest实例转换成为HttpRequestMesssage实例,然后推送至WebApi管道,从而以人情的asp.net管道与初的asp.net
webapi架构间建立从链接。

     这里我们切实了解一下HttpControllerHandler这个看似:

   
 HttpControllerHandler类在 System.Web.Http.WebHost命名空间下,根据命名空间的称谓,我们虽得清晰的询问及拖欠命名空间要用来创造web托管的。

public class HttpControllerHandler : IHttpAsyncHandler, IHttpHandler

 该类继承自IHttpAsyncHandler,
IHttpHandler接口,我们是因为底层代码可知,该类实际具体继承自HttpTaskAsyncHandler类,用同Http任务异步处理程序。接下来我们实际看一下此类的部分艺术:

二.WebApi托管方式分析:

    在Asp.Net Web
Api的托管方产生三栽,接下去我们来大概了解一下及时三种托管方。

       (1).在另外Windows进程遭到由托管。

     
 (2).Web托管,即在IIS之上使用ASP.NET管道展开托管。(如果急需了解IIS和ASPI.NET管道的知识,可以友善找查看,笔者建议做web开发之口询问一下该运行机制,有利于我们对asp.net
web程序来一个刻骨铭心之垂询。)

       (3).OWIN托管。(在一个owin兼容的服务器上建一个webapi层)

   
 在运web托管时,所采用的凡ASP.NET的管道和路由功能,将HTTP请求转发到一个新的ASP.NET处理程序,HttpControllerHandler中。这个次接收至HtppRequest实例转换成HttpRequestMesssage实例,然后推送到WebApi管道,从而以风的asp.net管道和新的asp.net
webapi架构间建立于链接。

     这里我们现实了解一下HttpControllerHandler这个类似:

   
 HttpControllerHandler类在 System.Web.Http.WebHost命名空间下,根据命名空间的名目,我们尽管得清楚的问询及该命名空间要用来创造web托管的。

public class HttpControllerHandler : IHttpAsyncHandler, IHttpHandler

 该类继承自IHttpAsyncHandler,
IHttpHandler接口,我们是因为底层代码可知,该类实际具体继承自HttpTaskAsyncHandler类,用同Http任务异步处理程序。接下来我们实际看一下此类的局部措施:

  1.ProcessRequestAsync方式:提供处理异步任务的代码。

    /// <summary>
    /// 提供处理异步任务的代码
    /// </summary>
    /// <returns>
    /// 异步任务。
    /// </returns>
    /// <param name="context">HTTP 上下文。</param>
    public override Task ProcessRequestAsync(HttpContext context)
    {
      return this.ProcessRequestAsyncCore((HttpContextBase) new HttpContextWrapper(context));
    }

    internal async Task ProcessRequestAsyncCore(HttpContextBase contextBase)
    {
      HttpRequestMessage request = HttpContextBaseExtensions.GetHttpRequestMessage(contextBase) ?? HttpControllerHandler.ConvertRequest(contextBase);
      System.Net.Http.HttpRequestMessageExtensions.SetRouteData(request, this._routeData);
      CancellationToken cancellationToken = HttpResponseBaseExtensions.GetClientDisconnectedTokenWhenFixed(contextBase.Response);
      HttpResponseMessage response = (HttpResponseMessage) null;
      try
      {
        response = await this._server.SendAsync(request, cancellationToken);
        await HttpControllerHandler.CopyResponseAsync(contextBase, request, response, HttpControllerHandler._exceptionLogger.Value, HttpControllerHandler._exceptionHandler.Value, cancellationToken);
      }
      catch (OperationCanceledException ex)
      {
        contextBase.Request.Abort();
      }
      finally
      {
        System.Net.Http.HttpRequestMessageExtensions.DisposeRequestResources(request);
        request.Dispose();
        if (response != null)
          response.Dispose();
      }
    }

 
 该方式是一个异步方法,并且吸纳的参数是HttpContext,表示http上下文内容,调用GetHttpRequestMessage()获取HttpRequestMessage对象实例,调用SetRouteData()方法设置路由于信息,调用GetClientDisconnectedTokenWhenFixed()方法赢得客户端断开令牌时修复,并回取消令牌,该措施生成http请求后,对信息进行异步发送处理操作。

  1.ProcessRequestAsync法:提供处理异步任务之代码。

    /// <summary>
    /// 提供处理异步任务的代码
    /// </summary>
    /// <returns>
    /// 异步任务。
    /// </returns>
    /// <param name="context">HTTP 上下文。</param>
    public override Task ProcessRequestAsync(HttpContext context)
    {
      return this.ProcessRequestAsyncCore((HttpContextBase) new HttpContextWrapper(context));
    }

    internal async Task ProcessRequestAsyncCore(HttpContextBase contextBase)
    {
      HttpRequestMessage request = HttpContextBaseExtensions.GetHttpRequestMessage(contextBase) ?? HttpControllerHandler.ConvertRequest(contextBase);
      System.Net.Http.HttpRequestMessageExtensions.SetRouteData(request, this._routeData);
      CancellationToken cancellationToken = HttpResponseBaseExtensions.GetClientDisconnectedTokenWhenFixed(contextBase.Response);
      HttpResponseMessage response = (HttpResponseMessage) null;
      try
      {
        response = await this._server.SendAsync(request, cancellationToken);
        await HttpControllerHandler.CopyResponseAsync(contextBase, request, response, HttpControllerHandler._exceptionLogger.Value, HttpControllerHandler._exceptionHandler.Value, cancellationToken);
      }
      catch (OperationCanceledException ex)
      {
        contextBase.Request.Abort();
      }
      finally
      {
        System.Net.Http.HttpRequestMessageExtensions.DisposeRequestResources(request);
        request.Dispose();
        if (response != null)
          response.Dispose();
      }
    }

 
 该法是一个异步方法,并且吸纳的参数是HttpContext,表示http上下文内容,调用GetHttpRequestMessage()获取HttpRequestMessage对象实例,调用SetRouteData()方法设置路由于信息,调用GetClientDisconnectedTokenWhenFixed()方法得到客户端断开令牌时修复,并返回取消令牌,该办法生成http请求后,对信息进行异步发送处理操作。

   2.GetStreamContent方法:获取请求获取流内容。

 private static HttpContent GetStreamContent(HttpRequestBase requestBase, bool bufferInput)
    {
      if (bufferInput)
        return (HttpContent) new HttpControllerHandler.LazyStreamContent((Func<Stream>) (() =>
        {
          if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.None)
            return (Stream) new SeekableBufferedRequestStream(requestBase);
          if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Classic)
          {
            requestBase.InputStream.Position = 0L;
            return requestBase.InputStream;
          }
          if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Buffered)
          {
            if (requestBase.GetBufferedInputStream().Position <= 0L)
              return (Stream) new SeekableBufferedRequestStream(requestBase);
            requestBase.InputStream.Position = 0L;
            return requestBase.InputStream;
          }
          throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, SRResources.RequestBodyAlreadyReadInMode, new object[1]
          {
            (object) ReadEntityBodyMode.Bufferless
          }));
        }));
      return (HttpContent) new HttpControllerHandler.LazyStreamContent((Func<Stream>) (() =>
      {
        if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.None)
          return requestBase.GetBufferlessInputStream();
        if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Classic)
          throw new InvalidOperationException(SRResources.RequestStreamCannotBeReadBufferless);
        if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Bufferless)
        {
          Stream bufferlessInputStream = requestBase.GetBufferlessInputStream();
          if (bufferlessInputStream.Position > 0L)
            throw new InvalidOperationException(SRResources.RequestBodyAlreadyRead);
          return bufferlessInputStream;
        }
        throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, SRResources.RequestBodyAlreadyReadInMode, new object[1]
        {
          (object) ReadEntityBodyMode.Buffered
        }));
      }));
    }

 
 该方式用和收获HTTP请求的流动内容,根据参数HttpRequestBase可知,该办法接受到HTTP请求后,对信息进行拍卖,bufferInput参数判断传入的是否也流动对象,传入的流对象,进入LazyStreamContent类进行处理,LazyStreamContent类的构造函数接受一个暗含返回值的寄托。

public LazyStreamContent(Func<Stream> getStream)
      {
        this._getStream = getStream;
      }

   GetStreamContent方法的有关操作主要是本着HTTP请求内容的分析操作。

   2.GetStreamContent方法:获取请求获取流内容。

 private static HttpContent GetStreamContent(HttpRequestBase requestBase, bool bufferInput)
    {
      if (bufferInput)
        return (HttpContent) new HttpControllerHandler.LazyStreamContent((Func<Stream>) (() =>
        {
          if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.None)
            return (Stream) new SeekableBufferedRequestStream(requestBase);
          if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Classic)
          {
            requestBase.InputStream.Position = 0L;
            return requestBase.InputStream;
          }
          if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Buffered)
          {
            if (requestBase.GetBufferedInputStream().Position <= 0L)
              return (Stream) new SeekableBufferedRequestStream(requestBase);
            requestBase.InputStream.Position = 0L;
            return requestBase.InputStream;
          }
          throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, SRResources.RequestBodyAlreadyReadInMode, new object[1]
          {
            (object) ReadEntityBodyMode.Bufferless
          }));
        }));
      return (HttpContent) new HttpControllerHandler.LazyStreamContent((Func<Stream>) (() =>
      {
        if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.None)
          return requestBase.GetBufferlessInputStream();
        if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Classic)
          throw new InvalidOperationException(SRResources.RequestStreamCannotBeReadBufferless);
        if (requestBase.ReadEntityBodyMode == ReadEntityBodyMode.Bufferless)
        {
          Stream bufferlessInputStream = requestBase.GetBufferlessInputStream();
          if (bufferlessInputStream.Position > 0L)
            throw new InvalidOperationException(SRResources.RequestBodyAlreadyRead);
          return bufferlessInputStream;
        }
        throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, SRResources.RequestBodyAlreadyReadInMode, new object[1]
        {
          (object) ReadEntityBodyMode.Buffered
        }));
      }));
    }

 
 该措施用同取HTTP请求的流淌内容,根据参数HttpRequestBase可知,该办法接受到HTTP请求后,对信息进行处理,bufferInput参数判断传入的是不是为流动对象,传入的流对象,进入LazyStreamContent类进行拍卖,LazyStreamContent类的构造函数接受一个暗含返回值的寄托。

public LazyStreamContent(Func<Stream> getStream)
      {
        this._getStream = getStream;
      }

   GetStreamContent方法的连锁操作主要是指向HTTP请求内容的分析操作。

三.WebApi核心目标HttpRequestMessage和HttpResponseMessage:

三.WebApi核心目标HttpRequestMessage和HttpResponseMessage:

   1.HttpRequestMessageExtensions:HTTP消息请求实例的扩展类。

      (1).GetRequestContext方法:获取HTTP请求消息内容:

 public static HttpRequestContext GetRequestContext(this HttpRequestMessage request)
    {
      if (request == null)
        throw Error.ArgumentNull("request");
      return HttpRequestMessageExtensions.GetProperty<HttpRequestContext>(request, HttpPropertyKeys.RequestContextKey);
    }

 根据传入的HTTP请求,调用GetProperty()方法赢得属性,我们实际看一下GetProperty()方法:

 private static T GetProperty<T>(this HttpRequestMessage request, string key)
    {
      T obj;
      DictionaryExtensions.TryGetValue<T>(request.Properties, key, out obj);
      return obj;
    }

拖欠办法赢得请求对象,并因KEY值调用TryGetValue()方法得到属性。

   (2).CreateResponse():创建请求信息之应。

    /// <summary>
    /// 创建与关联的 HttpRequestMessage连接的HttpResponseMessage
    /// </summary>
    /// <returns>
    /// 与关联的 HttpRequestMessage连接的已初始化 HttpResponseMessage
    /// </returns>
    /// <param name="request">导致此响应消息的 HTTP 请求消息。</param>
        <param name="statusCode">HTTP 响应状态代码。</param>
        <param name="value">HTTP 响应消息的内容。</param>
        <param name="configuration">包含用于解析服务的依赖关系解析程序的 HTTP 配置。</param>
        <typeparam name="T">HTTP 响应消息的类型。</typeparam>
    public static HttpResponseMessage CreateResponse<T>(this HttpRequestMessage request, HttpStatusCode statusCode, T value, HttpConfiguration configuration)
    {
      if (request == null)
        throw Error.ArgumentNull("request");
      configuration = configuration ?? HttpRequestMessageExtensions.GetConfiguration(request);
      if (configuration == null)
        throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoConfiguration);
      IContentNegotiator contentNegotiator = ServicesExtensions.GetContentNegotiator(configuration.Services);
      if (contentNegotiator == null)
        throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoContentNegotiator, (object) typeof (IContentNegotiator).FullName);
      IEnumerable<MediaTypeFormatter> formatters = (IEnumerable<MediaTypeFormatter>) configuration.Formatters;
      return NegotiatedContentResult<T>.Execute(statusCode, value, contentNegotiator, request, formatters);
    }

 该措施根据请求消息提供的连锁信息,在处理完毕请求消息继,创建响应消息内容。

   1.HttpRequestMessageExtensions:HTTP消息请求实例的扩展类。

      (1).GetRequestContext方法:获取HTTP请求消息内容:

 public static HttpRequestContext GetRequestContext(this HttpRequestMessage request)
    {
      if (request == null)
        throw Error.ArgumentNull("request");
      return HttpRequestMessageExtensions.GetProperty<HttpRequestContext>(request, HttpPropertyKeys.RequestContextKey);
    }

 根据传入的HTTP请求,调用GetProperty()方法得到属性,我们现实看一下GetProperty()方法:

 private static T GetProperty<T>(this HttpRequestMessage request, string key)
    {
      T obj;
      DictionaryExtensions.TryGetValue<T>(request.Properties, key, out obj);
      return obj;
    }

欠措施取得请求对象,并冲KEY值调用TryGetValue()方法获得属性。

   (2).CreateResponse():创建请求信息之应。

    /// <summary>
    /// 创建与关联的 HttpRequestMessage连接的HttpResponseMessage
    /// </summary>
    /// <returns>
    /// 与关联的 HttpRequestMessage连接的已初始化 HttpResponseMessage
    /// </returns>
    /// <param name="request">导致此响应消息的 HTTP 请求消息。</param>
        <param name="statusCode">HTTP 响应状态代码。</param>
        <param name="value">HTTP 响应消息的内容。</param>
        <param name="configuration">包含用于解析服务的依赖关系解析程序的 HTTP 配置。</param>
        <typeparam name="T">HTTP 响应消息的类型。</typeparam>
    public static HttpResponseMessage CreateResponse<T>(this HttpRequestMessage request, HttpStatusCode statusCode, T value, HttpConfiguration configuration)
    {
      if (request == null)
        throw Error.ArgumentNull("request");
      configuration = configuration ?? HttpRequestMessageExtensions.GetConfiguration(request);
      if (configuration == null)
        throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoConfiguration);
      IContentNegotiator contentNegotiator = ServicesExtensions.GetContentNegotiator(configuration.Services);
      if (contentNegotiator == null)
        throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoContentNegotiator, (object) typeof (IContentNegotiator).FullName);
      IEnumerable<MediaTypeFormatter> formatters = (IEnumerable<MediaTypeFormatter>) configuration.Formatters;
      return NegotiatedContentResult<T>.Execute(statusCode, value, contentNegotiator, request, formatters);
    }

 该方式根据请求消息提供的有关消息,在处理完毕请求消息后,创建响应消息内容。

   2.HttpResponseMessageExtensions:HTTP应答消息实例的扩展类。

     TryGetContentValue():获取内容的值。

    /// <summary>
    /// 尝试检索HttpResponseMessageExtensions 的内容的值。
    /// </summary>
    /// <returns>
    /// 内容值的检索结果。
    /// </returns>
    /// <param name="response">操作的响应。</param>
         <param name="value">内容的值。</param>
         <typeparam name="T">要检索的值的类型。</typeparam>
    public static bool TryGetContentValue<T>(this HttpResponseMessage response, out T value)
    {
      if (response == null)
        throw Error.ArgumentNull("response");
      ObjectContent objectContent = response.Content as ObjectContent;
      if (objectContent != null && objectContent.Value is T)
      {
        value = (T) objectContent.Value;
        return true;
      }
      value = default (T);
      return false;
    }

   根据传入的响应消息对象获得响应消息之情节。

   2.HttpResponseMessageExtensions:HTTP应答消息实例的扩展类。

     TryGetContentValue():获取内容之价值。

    /// <summary>
    /// 尝试检索HttpResponseMessageExtensions 的内容的值。
    /// </summary>
    /// <returns>
    /// 内容值的检索结果。
    /// </returns>
    /// <param name="response">操作的响应。</param>
         <param name="value">内容的值。</param>
         <typeparam name="T">要检索的值的类型。</typeparam>
    public static bool TryGetContentValue<T>(this HttpResponseMessage response, out T value)
    {
      if (response == null)
        throw Error.ArgumentNull("response");
      ObjectContent objectContent = response.Content as ObjectContent;
      if (objectContent != null && objectContent.Value is T)
      {
        value = (T) objectContent.Value;
        return true;
      }
      value = default (T);
      return false;
    }

   根据传入的应消息对象获得响应消息的情节。

四.WebApi核心目标HttpClient:

 
 上面介绍了服务器端的收取和响应HTTP请求的操作方法,接下介绍一个客户端生成HTTP请求,用和请求与得到服务器返回的信,在初本子的.NET中,提供类HTTPClient类用来在客户端生成和得HTTP请求的接近。

四.WebApi核心目标HttpClient:

 
 上面介绍完服务器端的收纳及应HTTP请求的操作方法,接下去介绍一个客户端生成HTTP请求,用同请求和得服务器返回的音,在新本子的.NET中,提供类HTTPClient类用来以客户端生成和落HTTP请求的类似。

    1.属性概要:

   
  BaseAddress:获取或安装发送请求时所祭的互联网资源的联结资源标识符(URI)的基地址。

      DefaultRequestHeaders:获取应遵循每个请求发送的腔。

   
  MaxResponseContentBufferSize:获取或设置中之无比特别字节数读取响应内容时缓冲。

     Timeout:获取或设置的毫秒数请求过事先等待。

    1.属性概要:

   
  BaseAddress:获取或设置发送请求时所下的互联网资源的联资源标识符(URI)的基地址。

      DefaultRequestHeaders:获取应按照每个请求发送的腔。

   
  MaxResponseContentBufferSize:获取或安装中的无限可怜字节数读取响应内容常常缓冲。

     Timeout:获取或安装的毫秒数请求过之前等待。

   2.方法概要:

     CancelPendingRequests:取消这个实例上的有所未决请求。

     DeleteAsync(String):发送一个DELETE请求到指定的URI为异步操作。

     GetAsync(String):发送GET请求到指定的URI为异步操作。

   
 GetStreamAsync(String):发送GET请求到指定的URI并回响应中心作为一个异步操作流。

     PostAsync(String,
HttpContent):发送POST请求到指定的URI作为一个异步操作。

     SendAsync(HttpRequestMessage):发送一个HTTP请求作为一个异步操作。

   2.方法概要:

     CancelPendingRequests:取消以此实例上之享有未决请求。

     DeleteAsync(String):发送一个DELETE请求到指定的URI为异步操作。

     GetAsync(String):发送GET请求到指定的URI为异步操作。

   
 GetStreamAsync(String):发送GET请求到指定的URI并返回响应中心作为一个异步操作流。

     PostAsync(String,
HttpContent):发送POST请求到指定的URI作为一个异步操作。

     SendAsync(HttpRequestMessage):发送一个HTTP请求作为一个异步操作。

   3.方式和性质解析:

   
 (1).BaseAddress:获取或设置发送请求时所祭的互联网资源的联结资源标识符(URI)的基地址。

    /// <summary>
    /// 获取或设置发送请求时使用的 Internet 资源的统一资源标识符 (URI) 的基址。
    /// </summary>
    /// <returns>
    /// 返回 <see cref="T:System.Uri"/>。发送请求时使用的 Internet 资源的统一资源标识符 (URI) 的基址。
    /// </returns>
    [__DynamicallyInvokable]
    public Uri BaseAddress
    {
      [__DynamicallyInvokable] get
      {
        return this.baseAddress;
      }
      [__DynamicallyInvokable] set
      {
        HttpClient.CheckBaseAddress(value, "value");
        this.CheckDisposedOrStarted();
        if (Logging.On)
          Logging.PrintInfo(Logging.Http, (object) this, "BaseAddress: '" + (object) this.baseAddress + "'");
        this.baseAddress = value;
      }
    }

     (2).GetContentAsync:根据指定的uri异步的博内容。

private Task<T> GetContentAsync<T>(Uri requestUri, HttpCompletionOption completionOption, T defaultValue, Func<HttpContent, Task<T>> readAs)
    {
      TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
      HttpUtilities.ContinueWithStandard<HttpResponseMessage>(this.GetAsync(requestUri, completionOption), (Action<Task<HttpResponseMessage>>) (requestTask =>
      {
        if (HttpClient.HandleRequestFaultsAndCancelation<T>(requestTask, tcs))
          return;
        HttpResponseMessage result = requestTask.Result;
        if (result.Content == null)
        {
          tcs.TrySetResult(defaultValue);
        }
        else
        {
          try
          {
            HttpUtilities.ContinueWithStandard<T>(readAs(result.Content), (Action<Task<T>>) (contentTask =>
            {
              if (HttpUtilities.HandleFaultsAndCancelation<T>((Task) contentTask, tcs))
                return;
              tcs.TrySetResult(contentTask.Result);
            }));
          }
          catch (Exception ex)
          {
            tcs.TrySetException(ex);
          }
        }
      }));
      return tcs.Task;
    }

 
该办法呢异步的艺术,用和生成get、post请求后,获取相应的情。TrySetResult()方法将脚System.Threading.Tasks.Task`1转换为RanToCompletion状态。

     (3).SendAsync(): 以异步操作发送 HTTP 请求。

    /// <summary>
    /// 以异步操作发送 HTTP 请求。
    /// </summary>
    /// <returns>
    /// 返回 <see cref="T:System.Threading.Tasks.Task`1"/>。表示异步操作的任务对象。
    /// </returns>
    /// <param name="request">要发送的 HTTP 请求消息。</param>
        <param name="completionOption">操作应完成时(在响应可利用或在读取整个响应内容之后)。</param>
        <param name="cancellationToken">取消操作的取消标记。</param>
        <exception cref="T:System.ArgumentNullException">
        <paramref name="request"/> 为 null。</exception>
        <exception cref="T:System.InvalidOperationException">请求消息已由 <see cref="T:System.Net.Http.HttpClient"/> 实例发送。</exception>
    [__DynamicallyInvokable]
    public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
    {
      if (request == null)
        throw new ArgumentNullException("request");
      this.CheckDisposed();
      HttpClient.CheckRequestMessage(request);
      this.SetOperationStarted();
      this.PrepareRequestMessage(request);
      CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.pendingRequestsCts.Token);
      this.SetTimeout(linkedCts);
      TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
      HttpUtilities.ContinueWithStandard<HttpResponseMessage>(base.SendAsync(request, linkedCts.Token), (Action<Task<HttpResponseMessage>>) (task =>
      {
        try
        {
          this.DisposeRequestContent(request);
          if (task.IsFaulted)
            this.SetTaskFaulted(request, linkedCts, tcs, task.Exception.GetBaseException());
          else if (task.IsCanceled)
          {
            this.SetTaskCanceled(request, linkedCts, tcs);
          }
          else
          {
            HttpResponseMessage result = task.Result;
            if (result == null)
              this.SetTaskFaulted(request, linkedCts, tcs, (Exception) new InvalidOperationException(SR.net_http_handler_noresponse));
            else if (result.Content == null || completionOption == HttpCompletionOption.ResponseHeadersRead)
              this.SetTaskCompleted(request, linkedCts, tcs, result);
            else
              this.StartContentBuffering(request, linkedCts, tcs, result);
          }
        }
        catch (Exception ex)
        {
          if (Logging.On)
            Logging.Exception(Logging.Http, (object) this, "SendAsync", ex);
          tcs.TrySetException(ex);
        }
      }));
      return tcs.Task;
    }

 
 该法是坐异步发的道以HTTP请求发送出,该方法的老三独参数中,HttpRequestMessage表示http请求对象,HttpCompletionOption表示操作就项,CancellationToken表示取消令牌。在殡葬HTTP请求之前,调用CheckRequestMessage方法对信息进行检讨。在使用异步方法时,需要考虑操作的撤当标因素对章程的熏陶。

 
 介绍了HttpClient对象,对于HttpClient的实际操作就不做牵线,HttpClient对象的下十分的简要,但是该类的底部实现还是比的错综复杂。 
 

   3.艺术及性解析:

   
 (1).BaseAddress:获取或设置发送请求时所采取的互联网资源的汇合资源标识符(URI)的基地址。

    /// <summary>
    /// 获取或设置发送请求时使用的 Internet 资源的统一资源标识符 (URI) 的基址。
    /// </summary>
    /// <returns>
    /// 返回 <see cref="T:System.Uri"/>。发送请求时使用的 Internet 资源的统一资源标识符 (URI) 的基址。
    /// </returns>
    [__DynamicallyInvokable]
    public Uri BaseAddress
    {
      [__DynamicallyInvokable] get
      {
        return this.baseAddress;
      }
      [__DynamicallyInvokable] set
      {
        HttpClient.CheckBaseAddress(value, "value");
        this.CheckDisposedOrStarted();
        if (Logging.On)
          Logging.PrintInfo(Logging.Http, (object) this, "BaseAddress: '" + (object) this.baseAddress + "'");
        this.baseAddress = value;
      }
    }

     (2).GetContentAsync:根据指定的uri异步的获内容。

private Task<T> GetContentAsync<T>(Uri requestUri, HttpCompletionOption completionOption, T defaultValue, Func<HttpContent, Task<T>> readAs)
    {
      TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
      HttpUtilities.ContinueWithStandard<HttpResponseMessage>(this.GetAsync(requestUri, completionOption), (Action<Task<HttpResponseMessage>>) (requestTask =>
      {
        if (HttpClient.HandleRequestFaultsAndCancelation<T>(requestTask, tcs))
          return;
        HttpResponseMessage result = requestTask.Result;
        if (result.Content == null)
        {
          tcs.TrySetResult(defaultValue);
        }
        else
        {
          try
          {
            HttpUtilities.ContinueWithStandard<T>(readAs(result.Content), (Action<Task<T>>) (contentTask =>
            {
              if (HttpUtilities.HandleFaultsAndCancelation<T>((Task) contentTask, tcs))
                return;
              tcs.TrySetResult(contentTask.Result);
            }));
          }
          catch (Exception ex)
          {
            tcs.TrySetException(ex);
          }
        }
      }));
      return tcs.Task;
    }

 
该法为异步的不二法门,用以及生成get、post请求后,获取相应之情节。TrySetResult()方法以根System.Threading.Tasks.Task`1转换为RanToCompletion状态。

     (3).SendAsync(): 以异步操作发送 HTTP 请求。

    /// <summary>
    /// 以异步操作发送 HTTP 请求。
    /// </summary>
    /// <returns>
    /// 返回 <see cref="T:System.Threading.Tasks.Task`1"/>。表示异步操作的任务对象。
    /// </returns>
    /// <param name="request">要发送的 HTTP 请求消息。</param>
        <param name="completionOption">操作应完成时(在响应可利用或在读取整个响应内容之后)。</param>
        <param name="cancellationToken">取消操作的取消标记。</param>
        <exception cref="T:System.ArgumentNullException">
        <paramref name="request"/> 为 null。</exception>
        <exception cref="T:System.InvalidOperationException">请求消息已由 <see cref="T:System.Net.Http.HttpClient"/> 实例发送。</exception>
    [__DynamicallyInvokable]
    public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
    {
      if (request == null)
        throw new ArgumentNullException("request");
      this.CheckDisposed();
      HttpClient.CheckRequestMessage(request);
      this.SetOperationStarted();
      this.PrepareRequestMessage(request);
      CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.pendingRequestsCts.Token);
      this.SetTimeout(linkedCts);
      TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
      HttpUtilities.ContinueWithStandard<HttpResponseMessage>(base.SendAsync(request, linkedCts.Token), (Action<Task<HttpResponseMessage>>) (task =>
      {
        try
        {
          this.DisposeRequestContent(request);
          if (task.IsFaulted)
            this.SetTaskFaulted(request, linkedCts, tcs, task.Exception.GetBaseException());
          else if (task.IsCanceled)
          {
            this.SetTaskCanceled(request, linkedCts, tcs);
          }
          else
          {
            HttpResponseMessage result = task.Result;
            if (result == null)
              this.SetTaskFaulted(request, linkedCts, tcs, (Exception) new InvalidOperationException(SR.net_http_handler_noresponse));
            else if (result.Content == null || completionOption == HttpCompletionOption.ResponseHeadersRead)
              this.SetTaskCompleted(request, linkedCts, tcs, result);
            else
              this.StartContentBuffering(request, linkedCts, tcs, result);
          }
        }
        catch (Exception ex)
        {
          if (Logging.On)
            Logging.Exception(Logging.Http, (object) this, "SendAsync", ex);
          tcs.TrySetException(ex);
        }
      }));
      return tcs.Task;
    }

 
 该方式是因异步发的计将HTTP请求发送出,该法的老三只参数中,HttpRequestMessage表示http请求对象,HttpCompletionOption表示操作完成项,CancellationToken表示取消令牌。在发送HTTP请求之前,调用CheckRequestMessage方法对信息进行自我批评。在运异步方法时,需要考虑操作的取消当外部因素对艺术的震慑。

 
 介绍完HttpClient对象,对于HttpClient的实际操作就未开牵线,HttpClient对象的采用大之粗略,但是该类的脚实现还是于的纷繁。 
 

五.总结:

   本文分为上下两首,简单的介绍类一下Asp.Net
WebApi的局部主干目标,并简短介绍了Asp.Net
WebApi路由体制,处理架构,托管方等等,如有不足及左的处在还于多多指正。(对己的话总算是描写了了,写了上篇就得勾下篇,实在痛苦)

五.总结:

   本文分为前后两首,简单的介绍类一下Asp.Net
WebApi的一对为主目标,并简短介绍了Asp.Net
WebApi路由体制,处理架构,托管方等等,如产生欠缺及不当的处在还于多多指正。(对我的话总算是写了了,写了上篇就得勾下篇,实在痛苦)

相关文章