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 > )
- {
- 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介绍的更多相关文章
- ASP.NET Web API 框架研究 Controller创建 HttpController 类型解析 选择 创建
上一篇介绍了HttpController的一些细节,接下来说下HttpController 类型解析.选择和创建.生产HttpController实例的生产线如下图: 一.涉及的类及源码分析 涉及的类 ...
- ASP.NET Web API 框架研究 Controller创建过程与消息处理管道
现在我们从代码角度来看下,从消息处理管道末尾是怎么创建出Controller实例的.消息处理管道末端是一个叫HttpRoutingDispatcher的处理器,其内部完成路由后 ,会把消息派送给其内部 ...
- ASP.NET Web API 框架研究 Controller实例的销毁
我们知道项目中创建的Controller,如ProductController都继承自ApiController抽象类,其又实现了接口IDisposable,所以,框架中自动调用Dispose方法来释 ...
- ASP.NET Web API 框架研究 ASP.NET Web API 路由
ASP.NET Web API 核心框架是一个独立的.抽象的消息处理管道,ASP.NET Web API有自己独立的路由系统,是消息处理管道的组成部分,其与ASP.NET路由系统有类似的设计,都能找到 ...
- ASP.NET Web API 框架研究 Action方法介绍
在根据请求解析出匹配的Controller类型并创建实例后,要在该Controller类型中的众多Action方法中选择与请求匹配的那一个,并执行,然后返回响应. Action方法,其元数据,主要包括 ...
- ASP.NET Web API 框架研究 核心的消息处理管道
ASP.NET Web API 的核心框架是一个由一组HttpMessageHandler有序组成的双工消息处理管道:寄宿监听到请求接受后,把消息传入该管道经过所有HttpMessageHandler ...
- ASP.NET Web API 框架研究 IoC容器 DependencyResolver
一.概念 1.IoC(Inversion of Control),控制反转 即将依赖对象的创建和维护交给一个外部容器来负责,而不是应用本身.如,在类型A中需要使用类型B的实例,而B的实例的创建不是由A ...
- ASP.NET Web API 框架研究 服务容器 ServicesContainer
ServicesContainer是一个服务的容器,可以理解为—个轻量级的IoC容器,其维护着一个服务接口类型与服务实例之间的映射关系,可以根据服务接口类型获取对应的服务实例.构成ASP.NET We ...
- ASP.NET Web API 框架研究 Self Host模式下的消息处理管道
Self Host模式下的ASP.NET Web API与WCF非常相似,都可以寄宿在任意类型的托管应用程序中,宿主可以是Windows Form .WPF.控制台应用以及Windows Servic ...
随机推荐
- Win10传递优化设置技巧
什么是“传递优化缓存” “传递优化”是微软为了加快Windows更新和Microsoft Store应用更新的下载速度,而在Windows10中引入的一种“自组织分布式本地化缓存”设计,可以在用户电脑 ...
- 增加samba用户提示Failed to add entry for user
1.首先在Ubuntu安装好samba,具体步骤为:安装samba:sudo apt-get install samba安装smbclient:sudo apt-get install 安装smbfs ...
- Intellij idea 系列教程之破解方法
Intellij idea 系列教程之破解方法 Intellij idea 系列教程目录(https://www.cnblogs.com/binarylei/p/10347600.html) 到这个地 ...
- Python之线程与进程
今天我们来了解一下Python的线程和进程的管理机制 首先,我们要了解下线程跟进程的概念: 线程(Thread)是操作系统能够进行运算调度的最小的单位,是一堆cpu的指令.他被包含在进程中,是进程中的 ...
- 找不到类SimpleJdbcTemplate ParameterizedRowMapper cannot be resolved
找不到类SimpleJdbcTemplate 背景 想编译个web应用,原来spring-jdbc.jar用的是Spring 3.1,今天改成用Spring 4.3,报了这个错误. 现象 编译不通过, ...
- 【算法】DP解决旅行路径问题
问题描述 : After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice ...
- spring学习 五 依赖注入的方式
依赖注入有两种方式: 1 构造注入,如果<bean>标签下使用<contructor-arg>,则是构造注入 2 setter注入,就是调用setter方法注入,如果<b ...
- mybatis学习 九 代理开发
1.作用: 实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql. 2.实现步骤: 2.1 创建一个接口 (1) ...
- linux代码笔记
sudo passwd root更新root密码 软件包管理及shell命令_deb软件包管理一_笔记:dpkj -i 安装dpkj -r 移除dpkj -P 全部移除dpkj -L 列出安装清单dj ...
- 2018.12.22 spoj7258 Lexicographical Substring Search(后缀自动机)
传送门 samsamsam基础题. 题意简述:给出一个串,询问第kkk大的本质不同的串. 然而这就是弦论的简化版. 我们把samsamsam建出来然后贪心选择就行了. 代码: #include< ...