对请求进行路由解析以及消息处理管道进行处理后,最后可以从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 }