对请求进行路由解析以及消息处理管道进行处理后,最后可以从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 > )
{
result = new AuthorizationFilterResult(ActionContext, authorizationFilters, result);
}
if (authenticationFilters.Length > )
{
result = new AuthenticationFilterResult(ActionContext, this, authenticationFilters, result);
}
if (exceptionFilters.Length > )
{
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
}

ASP.NET Web API 框架研究 Controller创建 HttpController介绍的更多相关文章

  1. ASP.NET Web API 框架研究 Controller创建 HttpController 类型解析 选择 创建

    上一篇介绍了HttpController的一些细节,接下来说下HttpController 类型解析.选择和创建.生产HttpController实例的生产线如下图: 一.涉及的类及源码分析 涉及的类 ...

  2. ASP.NET Web API 框架研究 Controller创建过程与消息处理管道

    现在我们从代码角度来看下,从消息处理管道末尾是怎么创建出Controller实例的.消息处理管道末端是一个叫HttpRoutingDispatcher的处理器,其内部完成路由后 ,会把消息派送给其内部 ...

  3. ASP.NET Web API 框架研究 Controller实例的销毁

    我们知道项目中创建的Controller,如ProductController都继承自ApiController抽象类,其又实现了接口IDisposable,所以,框架中自动调用Dispose方法来释 ...

  4. ASP.NET Web API 框架研究 ASP.NET Web API 路由

    ASP.NET Web API 核心框架是一个独立的.抽象的消息处理管道,ASP.NET Web API有自己独立的路由系统,是消息处理管道的组成部分,其与ASP.NET路由系统有类似的设计,都能找到 ...

  5. ASP.NET Web API 框架研究 Action方法介绍

    在根据请求解析出匹配的Controller类型并创建实例后,要在该Controller类型中的众多Action方法中选择与请求匹配的那一个,并执行,然后返回响应. Action方法,其元数据,主要包括 ...

  6. ASP.NET Web API 框架研究 核心的消息处理管道

    ASP.NET Web API 的核心框架是一个由一组HttpMessageHandler有序组成的双工消息处理管道:寄宿监听到请求接受后,把消息传入该管道经过所有HttpMessageHandler ...

  7. ASP.NET Web API 框架研究 IoC容器 DependencyResolver

    一.概念 1.IoC(Inversion of Control),控制反转 即将依赖对象的创建和维护交给一个外部容器来负责,而不是应用本身.如,在类型A中需要使用类型B的实例,而B的实例的创建不是由A ...

  8. ASP.NET Web API 框架研究 服务容器 ServicesContainer

    ServicesContainer是一个服务的容器,可以理解为—个轻量级的IoC容器,其维护着一个服务接口类型与服务实例之间的映射关系,可以根据服务接口类型获取对应的服务实例.构成ASP.NET We ...

  9. ASP.NET Web API 框架研究 Self Host模式下的消息处理管道

    Self Host模式下的ASP.NET Web API与WCF非常相似,都可以寄宿在任意类型的托管应用程序中,宿主可以是Windows Form .WPF.控制台应用以及Windows Servic ...

随机推荐

  1. linux中的设备类型

    loop设备 loop设备 一.参考命令[root@localhost a]# losetup usage:  losetup loop_device                          ...

  2. LibreOJ 2003. 「SDOI2017」新生舞会 基础01分数规划 最大权匹配

    #2003. 「SDOI2017」新生舞会 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  3. mysql5.6改进子查询实测试

    表t1,t2 各自生成100万条记录. 表引擎  myiasm  ,查询语句 select * from t1 where id2 in (select id2 from t2 ) 查询速度 2.x秒 ...

  4. tiny cc 编译器,tinycc,变种

    去掉了 -run 参数 下载代码和编译好的程序

  5. Spring 属性注入(三)AbstractNestablePropertyAccessor

    Spring 属性注入(三)AbstractNestablePropertyAccessor Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117 ...

  6. Spring 属性注入(四)属性键值对 - PropertyValue

    Spring 属性注入(四)属性键值对 - PropertyValue Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) P ...

  7. service fabric重装电脑后集群失败

    前提.下载service fabric sdk工具 1.Remote Procedure Call (RPC)服务打开 自动 2.Remote Procedure Call (RPC) Locator ...

  8. redis集群中的主从复制架构(3主3从)

    架构图如下 首先开启6个实例,这里为了演示方便,只是在一个linux上开启了6个redis实例 6380 (主)   6480 (从) 6381(主)   6481(从) 6382(主)   6482 ...

  9. html5 data-*自定义属性取值

    demo: <!DOCTYPE HTML> <html> <head> <title></title> <meta http-equi ...

  10. 2017/2/8 hibernate + oracle 实现id的自增 同时 hibernate项目跑起来 会自己增加字段的原因 oracle触发器的使用

    hibernate + oracle 实现id的自增 1.在oracle中先创建一个序列 : 序列语法 如下 create  sequence   (序列名称)seq_student_id minva ...