ASP.NET Web API 框架研究 Controller創建 HttpController介紹


  對請求進行路由解析以及消息處理管道進行處理后,最后可以從HttpRequestMessage對象的屬性字典中獲取解析的路由數據,后邊我們就可以根據其進行HttpController的創建,從前邊幾篇可知道,消息處理管道的末端即最后一個處理器HttpRoutingDispatcher會把消息派送給其一個內部處理器HttpControllerDispatcher進行HttpController的創建。這篇先介紹下HttpController,先熟悉下相關類,后邊都會用到,后邊會把這些類聯系起來。

  關注點:

  • 熟悉下各類成員及關系,基本都有注釋
  • 主要看ApiController抽象類的方法,項目中創建的控制器都繼承它,很多方法都可以直接使用,核心邏輯方法是ExecuteAsync,創建控制器對象后,會調用ExecuteAsync方法,進行后續操作,由於還沒講控制器的創建,里邊的邏輯以后再細說

一、涉及的類及源碼分析

 

 

1、IHttpController

  我們創建的Web API項目中的所有的Controller最后都要繼承該接口,如ProductController先繼承ApiController,ApiController再繼承IHttpController,接口定義如下,就一個方法ExecuteAsync方法,主要是一個參數HttpControllerContext,其具體見下一個類。

       

  

  

2、HttpControllerContext

  表示執行HttpController的上下文,作為IHttpController接口的ExecuteAsync方法的參數,主要包含以下五個屬性,前三個可以在構造函數里指定,也可以直接賦值

  HttpConfiguration  全局配置

  IHttpRouteData  解析的路由數據

  HttpRequestMessage  表示當前請求

  HttpControIlerDesciptor  描述HttpController

  HttpControIler 控制器對象

  這個類沒什么邏輯,只是在構造函數可以創建一個RequestContext

  _requestContext = new HttpRequestContext
  {
       Configuration = configuration, RouteData = routeData };
 public class HttpControllerContext
    {
        private HttpRequestContext _requestContext;
        private HttpRequestMessage _request;
        private HttpControllerDescriptor _controllerDescriptor;
        private IHttpController _controller;

        
        public HttpControllerContext(HttpRequestContext requestContext, HttpRequestMessage request,
            HttpControllerDescriptor controllerDescriptor, IHttpController controller)
        {
            if (requestContext == null)
            {
                throw Error.ArgumentNull("requestContext");
            }

            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            if (controllerDescriptor == null)
            {
                throw Error.ArgumentNull("controllerDescriptor");
            }

            if (controller == null)
            {
                throw Error.ArgumentNull("controller");
            }

            _requestContext = requestContext;
            _request = request;
            _controllerDescriptor = controllerDescriptor;
            _controller = controller;
        }

        public HttpControllerContext(HttpConfiguration configuration, IHttpRouteData routeData,
            HttpRequestMessage request)
        {
            if (configuration == null)
            {
                throw Error.ArgumentNull("configuration");
            }

            if (routeData == null)
            {
                throw Error.ArgumentNull("routeData");
            }

            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            //requestContext包含了Configuration和RouteData
            _requestContext = new HttpRequestContext
            {
                Configuration = configuration,
                RouteData = routeData
            };
            _request = request;
        }

        public HttpControllerContext()
        {
           
            _requestContext = new HttpRequestContext();
        }

        public HttpConfiguration Configuration
        {
            get
            {
                return _requestContext.Configuration;
            }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }

                _requestContext.Configuration = value;
            }
        }
public HttpControllerDescriptor ControllerDescriptor { get { return _controllerDescriptor; } set { if (value == null) { throw Error.PropertyNull(); } _controllerDescriptor = value; } }
public IHttpController Controller { get { return _controller; } set { if (value == null) { throw Error.PropertyNull(); } _controller = value; } } public HttpRequestMessage Request { get { return _request; } set { if (value == null) { throw Error.PropertyNull(); } _request = value; } } public HttpRequestContext RequestContext { get { return _requestContext; } set { if (value == null) { throw Error.PropertyNull(); } _requestContext = value; } } public IHttpRouteData RouteData { get { return _requestContext.RouteData; } set { if (value == null) { throw Error.PropertyNull(); } _requestContext.RouteData = value; } } }

3、HttpControllerDescriptor

  描述HttpController對象,封裝了HttpController元數據,系統就是根據HttpControllerDescriptor創建Controller的;主要有以下三個屬性,可以在構造函數指定,也可以直接賦值。

  HttpConfiguration 全局配置

  ControllerName  描述HttpCoutroller的控制器名稱

  ControllerType 描述HttpCoutroller的Type

  還有個特殊的屬性,類似HttpRequestMessage和HttpConfiguration類似的設計,可以添加任何對象到該屬性

  Properties 類型為ConcurrentDictionary(object, object)

  另外,有以下主要方法:

     IHttpController CreateController(HttpRequestMessage request)   創建Controller核心方法,主要邏輯都在這

  Collection<T> GetCustomAttributes<T>() where T: class  獲取定義在控制器上的自定義屬性

  Collection<T> GetCustomAttributes(bool inherit)where T: class  同上

  virtual Collection<IFilter> GetFilters() 獲取定在在控制器上的過濾器

 public class HttpControllerDescriptor
    {
        //附加任何對象到該字典屬性
        private readonly ConcurrentDictionary<object, object> _properties = new ConcurrentDictionary<object, object>();

        private HttpConfiguration _configuration;

        private string _controllerName;
        private Type _controllerType;

        //緩存用
        private object[] _attributeCache;
        private object[] _declaredOnlyAttributeCache;

        //后邊文章介紹,解析出ControllerType時候會調用該構造函數創建HttpControllerDescriptor
        public HttpControllerDescriptor(HttpConfiguration configuration, string controllerName, Type controllerType)
        {
            if (configuration == null)
            {
                throw Error.ArgumentNull("configuration");
            }

            if (controllerName == null)
            {
                throw Error.ArgumentNull("controllerName");
            }

            if (controllerType == null)
            {
                throw Error.ArgumentNull("controllerType");
            }

            _configuration = configuration;
            _controllerName = controllerName;
            _controllerType = controllerType;
            //構造函數里直接調用Initialize

            Initialize();
        }

        //默認構造函數,單元測試用
        public HttpControllerDescriptor()
        {
        }

        //默認構造函數,單元測試用
        internal HttpControllerDescriptor(HttpConfiguration configuration)
        {
            Initialize(configuration);
        }

        /// <summary>
        /// 附加任何對象到該字典屬性
        /// </summary>
        public virtual ConcurrentDictionary<object, object> Properties
        {
            get { return _properties; }
        }

        public HttpConfiguration Configuration
        {
            get { return _configuration; }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }
                _configuration = value;
            }
        }

        //控制器名稱
        public string ControllerName
        {
            get { return _controllerName; }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }
                _controllerName = value;
            }
        }

        //控制器類型
        public Type ControllerType
        {
            get { return _controllerType; }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }
                _controllerType = value;
            }
        }

        
        //主要方法 根據HttpRequestMessage創建一個IHttpController
        public virtual IHttpController CreateController(HttpRequestMessage request)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            //先從ServicesContainer獲取默認的IHttpControllerActivator
            IHttpControllerActivator activator = Configuration.Services.GetHttpControllerActivator();
            //調用IHttpControllerActivator的Create方法,創建,這個后一篇會說到
            IHttpController instance = activator.Create(request, this, ControllerType);
            return instance;
        }

     
        //描述符對應的控制器定義的過濾器列表
        public virtual Collection<IFilter> GetFilters()
        {
            return GetCustomAttributes<IFilter>();
        }

        //獲取泛型的自定義特性的集合,對應控制器上定義的
        public virtual Collection<T> GetCustomAttributes<T>() where T : class
        {
            return GetCustomAttributes<T>(inherit: true);
        }


        //獲取泛型的自定義特性的集合,對應控制器上定義的
       
        public virtual Collection<T> GetCustomAttributes<T>(bool inherit) where T : class
        {
            object[] attributes;
            //反射獲取自定義特性很慢,所以使用緩存_attributeCache,第二次開始,就直接從其獲取
            //inherit決定是否要去控制器類型繼承結構中去找所有特性
            if (inherit)
            {

                if (_attributeCache == null)
                {
                    _attributeCache = ControllerType.GetCustomAttributes(inherit: true);
                }
                attributes = _attributeCache;
            }
            else
            {
                if (_declaredOnlyAttributeCache == null)
                {
                    //是從ControllerType屬性上去尋找特性的
                    _declaredOnlyAttributeCache = ControllerType.GetCustomAttributes(inherit: false);
                }
                attributes = _declaredOnlyAttributeCache;
            }

            return new Collection<T>(TypeHelper.OfType<T>(attributes));
        }


        private void Initialize()
        {
            InvokeAttributesOnControllerType(this, ControllerType);
        }

        //先略過
        private static void InvokeAttributesOnControllerType(HttpControllerDescriptor controllerDescriptor, Type type)
        {
            Contract.Assert(controllerDescriptor != null);

            if (type == null)
            {
                return;
            }
          
            InvokeAttributesOnControllerType(controllerDescriptor, type.BaseType);

            object[] attrs = type.GetCustomAttributes(inherit: false);
            foreach (object attr in attrs)
            {
                var controllerConfig = attr as IControllerConfiguration;
                if (controllerConfig != null)
                {
                    var originalConfig = controllerDescriptor.Configuration;
                    var controllerSettings = new HttpControllerSettings(originalConfig);
                    controllerConfig.Initialize(controllerSettings, controllerDescriptor);
                    controllerDescriptor.Configuration = HttpConfiguration.ApplyControllerSettings(controllerSettings, originalConfig);
                }
            }
        }
    }

4、ApiController

  WebAPI項目創建的HttpController類型默認繼承ApiController,ApiController又繼承自IHttpController和IDisposable

    HttpControllerContext ControllerContext 表示執行當前ApiController上下文
  HttpConfiguration Configration 全局配置 同 HttpControllerContext
  HttpRequestMessage Request 請求消息 同 HttpControllerContext
  HttpRouteData  RouteData  路由解析數據 同 HttpControllerContext
  ModelstateDictionary Modelstate  包含其中的數據會被以Model綁定的形式綁定到目標Aotion方法的對應的參數

  UrlHelper Url  可以根據注冊的HttpRoute和提供的路由變量生成—個完整的URL   
  IPrincipal User 返回當前線程的Principal ,前幾篇中HttpServer在SendAsync方法執行過程中,如果當前線程中的當前線程的Principal為Null,創建一個空的GenericPrincipaI對象作為當前線程的匿名Principal。

  主要方法有以下幾個:

  virtual Task<HttpRequsetMessage> ExecuteAsync(HttpControllerContext controllerContext,...)  實現IHttpController接口

  virtual void Initialize(HttpControllerContext  controllerContext) 受保護方法

  //資源回收

  void Dispose()
  virtual void Dispose(bool disposing)

  另外,特別注意,ApiController不能重復使用,每次請求都會使用一個新的HttpController來處理請求,ExecuteAsync方法的時候發現當前的ApiController已經處於“初始化”的狀態,系統會直接拋出一個InvaIidationException異常。

 public abstract class ApiController : IHttpController, IDisposable
    {
        private HttpActionContext _actionContext = new HttpActionContext();
        private bool _initialized;

        //獲取HttpConfiguration
        //setter 單元測試用
        public HttpConfiguration Configuration
        {
            get { return ControllerContext.Configuration; }
            set { ControllerContext.Configuration = value; }
        }

        //獲取HttpControllerContext
        //setter 單元測試用
        public HttpControllerContext ControllerContext
        {
            get
            {
                // unit test only
                if (ActionContext.ControllerContext == null)
                {
                    ActionContext.ControllerContext = new HttpControllerContext
                    {
                        RequestContext = new RequestBackedHttpRequestContext()
                    };
                }
                return ActionContext.ControllerContext;
            }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }

                ActionContext.ControllerContext = value;
            }
        }

        //獲取HttpRequestMessage
        //setter 單元測試用
        public HttpActionContext ActionContext
        {
            get { return _actionContext; }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }
                _actionContext = value;
            }
        }

        
        //在模型綁定之后獲取ModelState,綁定之前是空的,模型綁定以后再說
        public ModelStateDictionary ModelState
        {
            get
            {
                return ActionContext.ModelState;
            }
        }

        //獲取HttpRequestMessage
        //setter 單元測試用
        public HttpRequestMessage Request
        {
            get
            {
                return ControllerContext.Request;
            }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }

                HttpRequestContext contextOnRequest = value.GetRequestContext();
                HttpRequestContext contextOnController = RequestContext;

                if (contextOnRequest != null && contextOnRequest != contextOnController)
                {
                    // Prevent unit testers from setting conflicting requests contexts.
                    throw new InvalidOperationException(SRResources.RequestContextConflict);
                }

                ControllerContext.Request = value;
                value.SetRequestContext(contextOnController);

                RequestBackedHttpRequestContext requestBackedContext =
                    contextOnController as RequestBackedHttpRequestContext;

                if (requestBackedContext != null)
                {
                    requestBackedContext.Request = value;
                }
            }
        }

        //獲取HttpRequestContext
        //setter 單元測試用
        public HttpRequestContext RequestContext
        {
            get
            {
                return ControllerContext.RequestContext;
            }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }

                HttpRequestContext oldContext = ControllerContext.RequestContext;
                HttpRequestMessage request = Request;

                if (request != null)
                {
                    HttpRequestContext contextOnRequest = request.GetRequestContext();

                    if (contextOnRequest != null && contextOnRequest != oldContext && contextOnRequest != value)
                    {
                        // Prevent unit testers from setting conflicting requests contexts.
                        throw new InvalidOperationException(SRResources.RequestContextConflict);
                    }

                    request.SetRequestContext(value);
                }

                ControllerContext.RequestContext = value;
            }
        }

       
        //獲取UrlHelper用來對其他APIS生成URLS
        //setter 單元測試用
        public UrlHelper Url
        {
            get { return RequestContext.Url; }
            set { RequestContext.Url = value; }
        }

        //獲取或設置當前請求的Principal 
        //setter 單元測試用
        public IPrincipal User
        {
            get { return RequestContext.Principal; }
            set { RequestContext.Principal = value; }
        }

        //主要方法,創建控制器對象后,會調用ExecuteAsync方法,進行后續操作,由於還沒講控制器的創建,里邊的邏輯以后再細說
        public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            if (_initialized)
            {
                // 如果已經創建過該實例,就拋出異常,一個控制器實例,多次請求不能重復使用
                throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name);
            }

            Initialize(controllerContext);

           
            if (Request != null)
            {
                //先注冊到待銷毀集合,待請求完成后一起銷毀改控制器實例
                Request.RegisterForDispose(this);
            }

            HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
            ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;
            //選擇Action
            HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);
            ActionContext.ActionDescriptor = actionDescriptor;
            if (Request != null)
            {
                Request.SetActionDescriptor(actionDescriptor);
            }

            FilterGrouping filterGrouping = actionDescriptor.GetFilterGrouping();

            //ActionFilters
            IActionFilter[] actionFilters = filterGrouping.ActionFilters;
            //身份認證過濾器
            IAuthenticationFilter[] authenticationFilters = filterGrouping.AuthenticationFilters;
            //授權過濾器
            IAuthorizationFilter[] authorizationFilters = filterGrouping.AuthorizationFilters;
            //ExceptionFilters
            IExceptionFilter[] exceptionFilters = filterGrouping.ExceptionFilters;

            IHttpActionResult result = new ActionFilterResult(actionDescriptor.ActionBinding, ActionContext,
                controllerServices, actionFilters);
            if (authorizationFilters.Length > 0)
            {
                result = new AuthorizationFilterResult(ActionContext, authorizationFilters, result);
            }
            if (authenticationFilters.Length > 0)
            {
                result = new AuthenticationFilterResult(ActionContext, this, authenticationFilters, result);
            }
            if (exceptionFilters.Length > 0)
            {
                IExceptionLogger exceptionLogger = ExceptionServices.GetLogger(controllerServices);
                IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(controllerServices);
                result = new ExceptionFilterResult(ActionContext, exceptionFilters, exceptionLogger, exceptionHandler,
                    result);
            }
            //執行IHttpActionResult的ExecuteAsync
            return result.ExecuteAsync(cancellationToken);
        }

        //驗證entity,並把驗證錯誤添加到ModelState
        public void Validate<TEntity>(TEntity entity)
        {
            Validate(entity, keyPrefix: String.Empty);
        }

        //驗證entity,並把驗證錯誤添加到ModelState
        public void Validate<TEntity>(TEntity entity, string keyPrefix)
        {
            if (Configuration == null)
            {
                throw Error.InvalidOperation(SRResources.TypePropertyMustNotBeNull, typeof(ApiController).Name, "Configuration");
            }

            IBodyModelValidator validator = Configuration.Services.GetBodyModelValidator();
            if (validator != null)
            {
                ModelMetadataProvider metadataProvider = Configuration.Services.GetModelMetadataProvider();
                Contract.Assert(metadataProvider != null, "GetModelMetadataProvider throws on null.");

                validator.Validate(entity, typeof(TEntity), metadataProvider, ActionContext, keyPrefix);
            }
        }

        //創建一個400 Bad Request,項目中的Controller里可以直接使用
        protected internal virtual BadRequestResult BadRequest()
        {
            return new BadRequestResult(this);
        }

        //根據message 創建一個400 Bad Request,項目中的Controller里可以直接使用
        protected internal virtual BadRequestErrorMessageResult BadRequest(string message)
        {
            return new BadRequestErrorMessageResult(message, this);
        }

       
        //根據指定的modelState創建一個 400 Bad Request.
        protected internal virtual InvalidModelStateResult BadRequest(ModelStateDictionary modelState)
        {
            return new InvalidModelStateResult(modelState, this);
        }

        //創建一個 409 Conflict
        protected internal virtual ConflictResult Conflict()
        {
            return new ConflictResult(this);
        }

        /// <summary>創建一個內容協商結果響應</summary>
        /// <typeparam name="T">主體內容中的數據類型</typeparam>
        /// <param name="statusCode">響應狀態碼</param>
        /// <param name="value">在主體中要協商和格式化的數據</param>
        /// <returns>A <see cref="NegotiatedContentResult{T}"/> with the specified values.</returns>
        protected internal virtual NegotiatedContentResult<T> Content<T>(HttpStatusCode statusCode, T value)
        {
            return new NegotiatedContentResult<T>(statusCode, value, this);
        }

        /// <summary>創建一個指定格式化的內容響應</summary>
        /// <typeparam name="T">主體內容中的數據類型</typeparam>
        /// <param name="statusCode">響應狀態碼</param>
        /// <param name="value">在主體中要協商和格式化的數據</param>
        /// <param name="formatter">格式化器</param>
        /// <returns>A <see cref="FormattedContentResult{T}"/> with the specified values.</returns>
        protected internal FormattedContentResult<T> Content<T>(HttpStatusCode statusCode, T value,
            MediaTypeFormatter formatter)
        {
            return Content(statusCode, value, formatter, (MediaTypeHeaderValue)null);
        }

        /// <summary>創建一個指定媒體類型的格式化的內容響應</summary>
        /// <typeparam name="T">主體內容中的數據類型</typeparam>
        /// <param name="statusCode">響應狀態碼</param>
        /// <param name="value">在主體中要協商和格式化的數據</param>
        /// <param name="formatter">格式化器</param>
        /// <param name="mediaType">媒體類型</param>
        /// <returns>A <see cref="FormattedContentResult{T}"/> with the specified values.</returns>
        protected internal FormattedContentResult<T> Content<T>(HttpStatusCode statusCode, T value,
            MediaTypeFormatter formatter, string mediaType)
        {
            return Content(statusCode, value, formatter, new MediaTypeHeaderValue(mediaType));
        }

        /// <summary>創建一個指定媒體類型的格式化的內容響應</summary>
        /// <typeparam name="T">主體內容中的數據類型</typeparam>
        /// <param name="statusCode">響應狀態碼</param>
        /// <param name="value">在主體中要協商和格式化的數據</param>
        /// <param name="formatter">格式化器</param>
        /// <param name="mediaType">媒體類型</param>
        /// <returns>A <see cref="FormattedContentResult{T}"/> with the specified values.</returns>
        protected internal virtual FormattedContentResult<T> Content<T>(HttpStatusCode statusCode, T value,
            MediaTypeFormatter formatter, MediaTypeHeaderValue mediaType)
        {
            return new FormattedContentResult<T>(statusCode, value, formatter, mediaType, this);
        }

        /// <summary>
        /// 創建一個201 Created 響應Created
        /// </summary>
        /// <typeparam name="T">The type of content in the entity body.</typeparam>
        /// <param name="location">
        /// The location at which the content has been created. Must be a relative or absolute URL.
        /// </param>
        /// <param name="content">The content value to negotiate and format in the entity body.</param>
        /// <returns>A <see cref="CreatedNegotiatedContentResult{T}"/> with the specified values.</returns>
        protected internal CreatedNegotiatedContentResult<T> Created<T>(string location, T content)
        {
            if (location == null)
            {
                throw new ArgumentNullException("location");
            }

            return Created<T>(new Uri(location, UriKind.RelativeOrAbsolute), content);
        }

        /// <summary>
        /// 創建一個201 Created 響應Created
        /// </summary>
        /// <typeparam name="T">The type of content in the entity body.</typeparam>
        /// <param name="location">The location at which the content has been created.</param>
        /// <param name="content">The content value to negotiate and format in the entity body.</param>
        /// <returns>A <see cref="CreatedNegotiatedContentResult{T}"/> with the specified values.</returns>
        protected internal virtual CreatedNegotiatedContentResult<T> Created<T>(Uri location, T content)
        {
            return new CreatedNegotiatedContentResult<T>(location, content, this);
        }

        /// <summary>
        /// 創建一個201 Created 響應Created
        /// </summary>
        /// <typeparam name="T">The type of content in the entity body.</typeparam>
        /// <param name="routeName">The name of the route to use for generating the URL.</param>
        /// <param name="routeValues">The route data to use for generating the URL.</param>
        /// <param name="content">The content value to negotiate and format in the entity body.</param>
        /// <returns>A <see cref="CreatedAtRouteNegotiatedContentResult{T}"/> with the specified values.</returns>
        protected internal CreatedAtRouteNegotiatedContentResult<T> CreatedAtRoute<T>(string routeName,
            object routeValues, T content)
        {
            return CreatedAtRoute<T>(routeName, new HttpRouteValueDictionary(routeValues), content);
        }

        /// <summary>
        /// 創建一個201 Created 響應Created
        /// </summary>
        /// <typeparam name="T">The type of content in the entity body.</typeparam>
        /// <param name="routeName">The name of the route to use for generating the URL.</param>
        /// <param name="routeValues">The route data to use for generating the URL.</param>
        /// <param name="content">The content value to negotiate and format in the entity body.</param>
        /// <returns>A <see cref="CreatedAtRouteNegotiatedContentResult{T}"/> with the specified values.</returns>
        protected internal virtual CreatedAtRouteNegotiatedContentResult<T> CreatedAtRoute<T>(string routeName,
            IDictionary<string, object> routeValues, T content)
        {
            return new CreatedAtRouteNegotiatedContentResult<T>(routeName, routeValues, content, this);
        }

        //創建一個 500 Internal Server Error 
        protected internal virtual InternalServerErrorResult InternalServerError()
        {
            return new InternalServerErrorResult(this);
        }

       
        //根據異常創建一個 500 Internal Server Error 
        protected internal virtual ExceptionResult InternalServerError(Exception exception)
        {
            return new ExceptionResult(exception, this);
        }

        /// <summary>創建一個 200 OK 響應,主體內容有JSON格式的數據,JsonSerializerSettings 序列化器</summary>
        /// <typeparam name="T">主體內容的數據類型</typeparam>
        /// <param name="content">序列化到主體部分的內容</param>
        /// <returns>A <see cref="JsonResult{T}"/> with the specified value.</returns>
        protected internal JsonResult<T> Json<T>(T content)
        {
            return Json<T>(content, new JsonSerializerSettings());
        }

        /// <summary>創建一個 200 OK 響應,主體內容有JSON格式的數據, UTF8Encoding編碼</summary>
        /// <typeparam name="T">主體內容的數據類型</typeparam>
        /// <param name="content">序列化到主體部分的內容</param>
        /// <param name="serializerSettings">序列化器</param>
        /// <returns>A <see cref="JsonResult{T}"/> with the specified values.</returns>
        protected internal JsonResult<T> Json<T>(T content, JsonSerializerSettings serializerSettings)
        {
            return Json<T>(content, serializerSettings, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false,
                throwOnInvalidBytes: true));
        }

        /// 創建一個 200 OK 響應,主體內容有JSON格式的數據
        /// <typeparam name="T">主體內容的數據類型.</typeparam>
        /// <param name="content">序列化到主體部分的內容.</param>
        /// <param name="serializerSettings">序列化器</param>
        /// <param name="encoding">內容編碼</param>
        /// <returns>A <see cref="JsonResult{T}"/> with the specified values.</returns>
        protected internal virtual JsonResult<T> Json<T>(T content, JsonSerializerSettings serializerSettings,
            Encoding encoding)
        {
            return new JsonResult<T>(content, serializerSettings, encoding, this);
        }

        //創建一個 404 Not Found 響應
        protected internal virtual NotFoundResult NotFound()
        {
            return new NotFoundResult(this);
        }

        //創建一個 200 OK 響應 
        protected internal virtual OkResult Ok()
        {
            return new OkResult(this);
        }

      
        //根據指定主體內容創建  OkNegotiatedContentResult(200 OK) 
        protected internal virtual OkNegotiatedContentResult<T> Ok<T>(T content)
        {
            return new OkNegotiatedContentResult<T>(content, this);
        }

        //根據指定值創建一個Redirect 302 Found,參數用來生成URL
        protected internal virtual RedirectResult Redirect(string location)
        {
            if (location == null)
            {
                throw new ArgumentNullException("location");
            }

            return Redirect(new Uri(location));
        }

        //根據指定值創建一個RedirectResult 302 Found,參數用來生成URL
        protected internal virtual RedirectResult Redirect(Uri location)
        {
            return new RedirectResult(location, this);
        }

        //根據指定值創建一個RedirectToRouteResult 302 Found,參數用來生成URL
        protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues)
        {
            return RedirectToRoute(routeName, new HttpRouteValueDictionary(routeValues));
        }

        //根據指定值創建一個RedirectToRouteResult 302 Found,參數用來生成URL
        protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName,
            IDictionary<string, object> routeValues)
        {
            return new RedirectToRouteResult(routeName, routeValues, this);
        }

        //根據HttpResponseMessage創建一個ResponseMessageResult
        protected internal virtual ResponseMessageResult ResponseMessage(HttpResponseMessage response)
        {
            return new ResponseMessageResult(response);
        }

        /// 根據指定的HttpStatusCode創建StatusCodeResult
        protected internal virtual StatusCodeResult StatusCode(HttpStatusCode status)
        {
            return new StatusCodeResult(status, this);
        }

        // 根據指定值 創建401 未授權 響應
        //challenges 為 The WWW-Authenticate challenges.
        protected internal UnauthorizedResult Unauthorized(params AuthenticationHeaderValue[] challenges)
        {
            return Unauthorized((IEnumerable<AuthenticationHeaderValue>)challenges);
        }


        // 根據指定值 創建401 未授權 響應
        //challenges 為 The WWW-Authenticate challenges.
        protected internal virtual UnauthorizedResult Unauthorized(IEnumerable<AuthenticationHeaderValue> challenges)
        {
            return new UnauthorizedResult(challenges, this);
        }

        //標記_initialized = true說明已經被使用,不能重復使用,即同一個控制器實例只能被使用於一次請求
        protected virtual void Initialize(HttpControllerContext controllerContext)
        {
            if (controllerContext == null)
            {
                throw Error.ArgumentNull("controllerContext");
            }

            _initialized = true;
            ControllerContext = controllerContext;
        }

        #region IDisposable

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
        }

        #endregion IDisposable
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM