using System
.Collections
.Generic
;
using System
.Diagnostics
.CodeAnalysis
;
using System
.Diagnostics
.Contracts
;
using System
.Net
;
using System
.Net
.Http
;
using System
.Net
.Http
.Formatting
;
using System
.Net
.Http
.Headers
;
using System
.Security
.Principal
;
using System
.Text
;
using System
.Threading
;
using System
.Threading
.Tasks
;
using System
.Web
.Http
.Controllers
;
using System
.Web
.Http
.Dispatcher
;
using System
.Web
.Http
.ExceptionHandling
;
using System
.Web
.Http
.Filters
;
using System
.Web
.Http
.Metadata
;
using System
.Web
.Http
.ModelBinding
;
using System
.Web
.Http
.Properties
;
using System
.Web
.Http
.Results
;
using System
.Web
.Http
.Routing
;
using System
.Web
.Http
.Validation
;
using Newtonsoft
.Json
;
namespace System
.Web
.Http
{
public abstract class ApiController : IHttpController, IDisposable
{
private HttpActionContext _actionContext
= new HttpActionContext();
private bool _initialized
;
public HttpConfiguration Configuration
{
get { return ControllerContext
.Configuration
; }
set { ControllerContext
.Configuration
= value; }
}
public HttpControllerContext ControllerContext
{
get
{
if (ActionContext
.ControllerContext
== null)
{
ActionContext
.ControllerContext
= new HttpControllerContext
{
RequestContext
= new RequestBackedHttpRequestContext()
};
}
return ActionContext
.ControllerContext
;
}
set
{
if (value == null)
{
throw Error
.PropertyNull();
}
ActionContext
.ControllerContext
= value;
}
}
public HttpActionContext ActionContext
{
get { return _actionContext
; }
set
{
if (value == null)
{
throw Error
.PropertyNull();
}
_actionContext
= value;
}
}
public ModelStateDictionary ModelState
{
get
{
return ActionContext
.ModelState
;
}
}
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
)
{
throw new InvalidOperationException(SRResources
.RequestContextConflict
);
}
ControllerContext
.Request
= value;
value.SetRequestContext(contextOnController
);
RequestBackedHttpRequestContext requestBackedContext
=
contextOnController
as RequestBackedHttpRequestContext
;
if (requestBackedContext
!= null)
{
requestBackedContext
.Request
= value;
}
}
}
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)
{
throw new InvalidOperationException(SRResources
.RequestContextConflict
);
}
request
.SetRequestContext(value);
}
ControllerContext
.RequestContext
= value;
}
}
public UrlHelper Url
{
get { return RequestContext
.Url
; }
set { RequestContext
.Url
= value; }
}
public IPrincipal User
{
get { return RequestContext
.Principal
; }
set { RequestContext
.Principal
= value; }
}
[SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification
= "This method is a coordinator, so this coupling is expected.")]
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
;
HttpActionDescriptor actionDescriptor
= controllerServices
.GetActionSelector().SelectAction(controllerContext
);
ActionContext
.ActionDescriptor
= actionDescriptor
;
if (Request
!= null)
{
Request
.SetActionDescriptor(actionDescriptor
);
}
FilterGrouping filterGrouping
= actionDescriptor
.GetFilterGrouping();
IActionFilter
[] actionFilters
= filterGrouping
.ActionFilters
;
IAuthenticationFilter
[] authenticationFilters
= filterGrouping
.AuthenticationFilters
;
IAuthorizationFilter
[] authorizationFilters
= filterGrouping
.AuthorizationFilters
;
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
);
}
return result
.ExecuteAsync(cancellationToken
);
}
public void Validate<TEntity>(TEntity entity
)
{
Validate(entity
, keyPrefix
: String
.Empty
);
}
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
);
}
}
protected internal virtual BadRequestResult BadRequest()
{
return new BadRequestResult(this);
}
protected internal virtual BadRequestErrorMessageResult BadRequest(string message
)
{
return new BadRequestErrorMessageResult(message
, this);
}
protected internal virtual InvalidModelStateResult BadRequest(ModelStateDictionary modelState
)
{
return new InvalidModelStateResult(modelState
, this);
}
protected internal virtual ConflictResult Conflict()
{
return new ConflictResult(this);
}
protected internal virtual NegotiatedContentResult
<T
> Content<T>(HttpStatusCode statusCode
, T value)
{
return new NegotiatedContentResult<T>(statusCode
, value, this);
}
protected internal FormattedContentResult
<T
> Content<T>(HttpStatusCode statusCode
, T value,
MediaTypeFormatter formatter
)
{
return Content(statusCode
, value, formatter
, (MediaTypeHeaderValue
)null);
}
protected internal FormattedContentResult
<T
> Content<T>(HttpStatusCode statusCode
, T value,
MediaTypeFormatter formatter
, string mediaType
)
{
return Content(statusCode
, value, formatter
, new MediaTypeHeaderValue(mediaType
));
}
protected internal virtual FormattedContentResult
<T
> Content<T>(HttpStatusCode statusCode
, T value,
MediaTypeFormatter formatter
, MediaTypeHeaderValue mediaType
)
{
return new FormattedContentResult<T>(statusCode
, value, formatter
, mediaType
, this);
}
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
);
}
protected internal virtual CreatedNegotiatedContentResult
<T
> Created<T>(Uri location
, T content
)
{
return new CreatedNegotiatedContentResult<T>(location
, content
, this);
}
protected internal CreatedAtRouteNegotiatedContentResult
<T
> CreatedAtRoute<T>(string routeName
,
object routeValues
, T content
)
{
return CreatedAtRoute<T>(routeName
, new HttpRouteValueDictionary(routeValues
), content
);
}
protected internal virtual CreatedAtRouteNegotiatedContentResult
<T
> CreatedAtRoute<T>(string routeName
,
IDictionary
<string, object> routeValues
, T content
)
{
return new CreatedAtRouteNegotiatedContentResult<T>(routeName
, routeValues
, content
, this);
}
protected internal virtual InternalServerErrorResult InternalServerError()
{
return new InternalServerErrorResult(this);
}
protected internal virtual ExceptionResult InternalServerError(Exception exception
)
{
return new ExceptionResult(exception
, this);
}
protected internal JsonResult
<T
> Json<T>(T content
)
{
return Json<T>(content
, new JsonSerializerSettings());
}
protected internal JsonResult
<T
> Json<T>(T content
, JsonSerializerSettings serializerSettings
)
{
return Json<T>(content
, serializerSettings
, new UTF8Encoding(encoderShouldEmitUTF8Identifier
: false,
throwOnInvalidBytes
: true));
}
protected internal virtual JsonResult
<T
> Json<T>(T content
, JsonSerializerSettings serializerSettings
,
Encoding encoding
)
{
return new JsonResult<T>(content
, serializerSettings
, encoding
, this);
}
protected internal virtual NotFoundResult NotFound()
{
return new NotFoundResult(this);
}
protected internal virtual OkResult Ok()
{
return new OkResult(this);
}
protected internal virtual OkNegotiatedContentResult
<T
> Ok<T>(T content
)
{
return new OkNegotiatedContentResult<T>(content
, this);
}
protected internal virtual RedirectResult Redirect(string location
)
{
if (location
== null)
{
throw new ArgumentNullException("location");
}
return Redirect(new Uri(location
));
}
protected internal virtual RedirectResult Redirect(Uri location
)
{
return new RedirectResult(location
, this);
}
protected internal RedirectToRouteResult RedirectToRoute(string routeName
, object routeValues
)
{
return RedirectToRoute(routeName
, new HttpRouteValueDictionary(routeValues
));
}
protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName
,
IDictionary
<string, object> routeValues
)
{
return new RedirectToRouteResult(routeName
, routeValues
, this);
}
protected internal virtual ResponseMessageResult ResponseMessage(HttpResponseMessage response
)
{
return new ResponseMessageResult(response
);
}
protected internal virtual StatusCodeResult StatusCode(HttpStatusCode status
)
{
return new StatusCodeResult(status
, this);
}
protected internal UnauthorizedResult Unauthorized(params AuthenticationHeaderValue
[] challenges
)
{
return Unauthorized((IEnumerable
<AuthenticationHeaderValue
>)challenges
);
}
protected internal virtual UnauthorizedResult Unauthorized(IEnumerable
<AuthenticationHeaderValue
> challenges
)
{
return new UnauthorizedResult(challenges
, this);
}
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
}
}