// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.IO; using System.Linq.Expressions; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Mvc { /// /// A base class for an MVC controller without view support. /// public abstract class ControllerBase { private ControllerContext _controllerContext; private IModelMetadataProvider _metadataProvider; private IObjectModelValidator _objectValidator; private IUrlHelper _url; /// /// Gets the request-specific . /// public IServiceProvider Resolver { get { return HttpContext?.RequestServices; } } /// /// Gets the for the executing action. /// public HttpContext HttpContext { get { return ControllerContext.HttpContext; } } /// /// Gets the for the executing action. /// public HttpRequest Request { get { return HttpContext?.Request; } } /// /// Gets the for the executing action. /// public HttpResponse Response { get { return HttpContext?.Response; } } /// /// Gets the for the executing action. /// public RouteData RouteData { get { return ControllerContext.RouteData; } } /// /// Gets the that contains the state of the model and of model-binding validation. /// public ModelStateDictionary ModelState { get { return ControllerContext?.ModelState; } } /// /// Gets or sets the . /// /// /// activates this property while activating controllers. /// If user code directly instantiates a controller, the getter returns an empty /// . /// [ControllerContext] public ControllerContext ControllerContext { get { if (_controllerContext == null) { _controllerContext = new ControllerContext(); } return _controllerContext; } set { if (value == null) { throw new ArgumentNullException(nameof(value)); } _controllerContext = value; } } /// /// Gets or sets the . /// public IModelMetadataProvider MetadataProvider { get { if (_metadataProvider == null) { _metadataProvider = Resolver?.GetRequiredService(); } return _metadataProvider; } set { if (value == null) { throw new ArgumentNullException(nameof(value)); } _metadataProvider = value; } } /// /// Gets or sets the . /// public IUrlHelper Url { get { if (_url == null) { var factory = Resolver?.GetRequiredService(); _url = factory?.GetUrlHelper(ControllerContext); } return _url; } set { if (value == null) { throw new ArgumentNullException(nameof(value)); } _url = value; } } /// /// Gets or sets the . /// public IObjectModelValidator ObjectValidator { get { if (_objectValidator == null) { _objectValidator = Resolver?.GetRequiredService(); } return _objectValidator; } set { if (value == null) { throw new ArgumentNullException(nameof(value)); } _objectValidator = value; } } /// /// Gets or sets the for user associated with the executing action. /// public ClaimsPrincipal User { get { return HttpContext?.User; } } /// /// Creates a object by specifying a string. /// /// The content to write to the response. /// The created object for the response. [NonAction] public virtual ContentResult Content(string content) { return Content(content, (MediaTypeHeaderValue)null); } /// /// Creates a object by specifying a string /// and a content type. /// /// The content to write to the response. /// The content type (MIME type). /// The created object for the response. [NonAction] public virtual ContentResult Content(string content, string contentType) { return Content(content, MediaTypeHeaderValue.Parse(contentType)); } /// /// Creates a object by specifying a string, /// a , and . /// /// The content to write to the response. /// The content type (MIME type). /// The content encoding. /// The created object for the response. /// /// If encoding is provided by both the 'charset' and the parameters, then /// the parameter is chosen as the final encoding. /// [NonAction] public virtual ContentResult Content(string content, string contentType, Encoding contentEncoding) { var mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); mediaTypeHeaderValue.Encoding = contentEncoding ?? mediaTypeHeaderValue.Encoding; return Content(content, mediaTypeHeaderValue); } /// /// Creates a object by specifying a /// string and a . /// /// The content to write to the response. /// The content type (MIME type). /// The created object for the response. [NonAction] public virtual ContentResult Content(string content, MediaTypeHeaderValue contentType) { var result = new ContentResult { Content = content, ContentType = contentType?.ToString() }; return result; } /// /// Creates a object that produces an empty No Content (204) response. /// /// The created object for the response. [NonAction] public virtual NoContentResult NoContent() { return new NoContentResult(); } /// /// Creates a object that produces an empty OK (200) response. /// /// The created for the response. [NonAction] public virtual OkResult Ok() { return new OkResult(); } /// /// Creates an object that produces an OK (200) response. /// /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual OkObjectResult Ok(object value) { var disposableValue = value as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new OkObjectResult(value); } /// /// Creates a object that redirects to the specified . /// /// The URL to redirect to. /// The created for the response. [NonAction] public virtual RedirectResult Redirect(string url) { if (string.IsNullOrEmpty(url)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(url)); } return new RedirectResult(url); } /// /// Creates a object with set to true /// using the specified . /// /// The URL to redirect to. /// The created for the response. [NonAction] public virtual RedirectResult RedirectPermanent(string url) { if (string.IsNullOrEmpty(url)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(url)); } return new RedirectResult(url, permanent: true); } /// /// Creates a object that redirects to /// the specified local . /// /// The local URL to redirect to. /// The created for the response. [NonAction] public virtual LocalRedirectResult LocalRedirect(string localUrl) { if (string.IsNullOrEmpty(localUrl)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(localUrl)); } return new LocalRedirectResult(localUrl); } /// /// Creates a object with /// set to true using the specified . /// /// The local URL to redirect to. /// The created for the response. [NonAction] public virtual LocalRedirectResult LocalRedirectPermanent(string localUrl) { if (string.IsNullOrEmpty(localUrl)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(localUrl)); } return new LocalRedirectResult(localUrl, permanent: true); } /// /// Redirects to the specified action using the . /// /// The name of the action. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToAction(string actionName) { return RedirectToAction(actionName, routeValues: null); } /// /// Redirects to the specified action using the /// and . /// /// The name of the action. /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToAction(string actionName, object routeValues) { return RedirectToAction(actionName, controllerName: null, routeValues: routeValues); } /// /// Redirects to the specified action using the /// and the . /// /// The name of the action. /// The name of the controller. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToAction(string actionName, string controllerName) { return RedirectToAction(actionName, controllerName, routeValues: null); } /// /// Redirects to the specified action using the specified , /// , and . /// /// The name of the action. /// The name of the controller. /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToAction( string actionName, string controllerName, object routeValues) { return new RedirectToActionResult(actionName, controllerName, routeValues) { UrlHelper = Url, }; } /// /// Redirects to the specified action with set to true /// using the specified . /// /// The name of the action. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToActionPermanent(string actionName) { return RedirectToActionPermanent(actionName, routeValues: null); } /// /// Redirects to the specified action with set to true /// using the specified and . /// /// The name of the action. /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToActionPermanent(string actionName, object routeValues) { return RedirectToActionPermanent(actionName, controllerName: null, routeValues: routeValues); } /// /// Redirects to the specified action with set to true /// using the specified and . /// /// The name of the action. /// The name of the controller. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToActionPermanent(string actionName, string controllerName) { return RedirectToActionPermanent(actionName, controllerName, routeValues: null); } /// /// Redirects to the specified action with set to true /// using the specified , , /// and . /// /// The name of the action. /// The name of the controller. /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToActionResult RedirectToActionPermanent( string actionName, string controllerName, object routeValues) { return new RedirectToActionResult( actionName, controllerName, routeValues, permanent: true) { UrlHelper = Url, }; } /// /// Redirects to the specified route using the specified . /// /// The name of the route. /// The created for the response. [NonAction] public virtual RedirectToRouteResult RedirectToRoute(string routeName) { return RedirectToRoute(routeName, routeValues: null); } /// /// Redirects to the specified route using the specified . /// /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToRouteResult RedirectToRoute(object routeValues) { return RedirectToRoute(routeName: null, routeValues: routeValues); } /// /// Redirects to the specified route using the specified /// and . /// /// The name of the route. /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToRouteResult RedirectToRoute(string routeName, object routeValues) { return new RedirectToRouteResult(routeName, routeValues) { UrlHelper = Url, }; } /// /// Redirects to the specified route with set to true /// using the specified . /// /// The name of the route. /// The created for the response. [NonAction] public virtual RedirectToRouteResult RedirectToRoutePermanent(string routeName) { return RedirectToRoutePermanent(routeName, routeValues: null); } /// /// Redirects to the specified route with set to true /// using the specified . /// /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToRouteResult RedirectToRoutePermanent(object routeValues) { return RedirectToRoutePermanent(routeName: null, routeValues: routeValues); } /// /// Redirects to the specified route with set to true /// using the specified and . /// /// The name of the route. /// The parameters for a route. /// The created for the response. [NonAction] public virtual RedirectToRouteResult RedirectToRoutePermanent(string routeName, object routeValues) { return new RedirectToRouteResult(routeName, routeValues, permanent: true) { UrlHelper = Url, }; } /// /// Returns a file with the specified as content and the /// specified as the Content-Type. /// /// The file contents. /// The Content-Type of the file. /// The created for the response. [NonAction] public virtual FileContentResult File(byte[] fileContents, string contentType) { return File(fileContents, contentType, fileDownloadName: null); } /// /// Returns a file with the specified as content, the /// specified as the Content-Type and the /// specified as the suggested file name. /// /// The file contents. /// The Content-Type of the file. /// The suggested file name. /// The created for the response. [NonAction] public virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName) { return new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName }; } /// /// Returns a file in the specified with the /// specified as the Content-Type. /// /// The with the contents of the file. /// The Content-Type of the file. /// The created for the response. [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType) { return File(fileStream, contentType, fileDownloadName: null); } /// /// Returns a file in the specified with the /// specified as the Content-Type and the /// specified as the suggested file name. /// /// The with the contents of the file. /// The Content-Type of the file. /// The suggested file name. /// The created for the response. [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) { if (fileStream != null) { Response.RegisterForDispose(fileStream); } return new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName }; } /// /// Returns the file specified by with the /// specified as the Content-Type. /// /// The virtual path of the file to be returned. /// The Content-Type of the file. /// The created for the response. [NonAction] public virtual VirtualFileResult File(string virtualPath, string contentType) { return File(virtualPath, contentType, fileDownloadName: null); } /// /// Returns the file specified by with the /// specified as the Content-Type and the /// specified as the suggested file name. /// /// The virtual path of the file to be returned. /// The Content-Type of the file. /// The suggested file name. /// The created for the response. [NonAction] public virtual VirtualFileResult File(string virtualPath, string contentType, string fileDownloadName) { return new VirtualFileResult(virtualPath, contentType) { FileDownloadName = fileDownloadName }; } /// /// Returns the file specified by with the /// specified as the Content-Type. /// /// The physical path of the file to be returned. /// The Content-Type of the file. /// The created for the response. [NonAction] public virtual PhysicalFileResult PhysicalFile(string physicalPath, string contentType) { return PhysicalFile(physicalPath, contentType, fileDownloadName: null); } /// /// Returns the file specified by with the /// specified as the Content-Type and the /// specified as the suggested file name. /// /// The physical path of the file to be returned. /// The Content-Type of the file. /// The suggested file name. /// The created for the response. [NonAction] public virtual PhysicalFileResult PhysicalFile( string physicalPath, string contentType, string fileDownloadName) { return new PhysicalFileResult(physicalPath, contentType) { FileDownloadName = fileDownloadName }; } /// /// Creates an that produces an Unauthorized (401) response. /// /// The created for the response. [NonAction] public virtual UnauthorizedResult Unauthorized() { return new UnauthorizedResult(); } /// /// Creates an that produces a Not Found (404) response. /// /// The created for the response. [NonAction] public virtual NotFoundResult NotFound() { return new NotFoundResult(); } /// /// Creates an that produces a Not Found (404) response. /// /// The created for the response. [NonAction] public virtual NotFoundObjectResult NotFound(object value) { var disposableValue = value as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new NotFoundObjectResult(value); } /// /// Creates an that produces a Bad Request (400) response. /// /// The created for the response. [NonAction] public virtual BadRequestResult BadRequest() { return new BadRequestResult(); } /// /// Creates an that produces a Bad Request (400) response. /// /// The created for the response. [NonAction] public virtual BadRequestObjectResult BadRequest(object error) { var disposableValue = error as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new BadRequestObjectResult(error); } /// /// Creates an that produces a Bad Request (400) response. /// /// The created for the response. [NonAction] public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState) { if (modelState == null) { throw new ArgumentNullException(nameof(modelState)); } return new BadRequestObjectResult(modelState); } /// /// Creates a object that produces a Created (201) response. /// /// The URI at which the content has been created. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedResult Created(string uri, object value) { if (uri == null) { throw new ArgumentNullException(nameof(uri)); } var disposableValue = value as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new CreatedResult(uri, value); } /// /// Creates a object that produces a Created (201) response. /// /// The URI at which the content has been created. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedResult Created(Uri uri, object value) { if (uri == null) { throw new ArgumentNullException(nameof(uri)); } var disposableValue = value as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new CreatedResult(uri, value); } /// /// Creates a object that produces a Created (201) response. /// /// The name of the action to use for generating the URL. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedAtActionResult CreatedAtAction(string actionName, object value) { return CreatedAtAction(actionName, routeValues: null, value: value); } /// /// Creates a object that produces a Created (201) response. /// /// The name of the action to use for generating the URL. /// The route data to use for generating the URL. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedAtActionResult CreatedAtAction(string actionName, object routeValues, object value) { return CreatedAtAction(actionName, controllerName: null, routeValues: routeValues, value: value); } /// /// Creates a object that produces a Created (201) response. /// /// The name of the action to use for generating the URL. /// The name of the controller to use for generating the URL. /// The route data to use for generating the URL. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedAtActionResult CreatedAtAction( string actionName, string controllerName, object routeValues, object value) { var disposableValue = value as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new CreatedAtActionResult(actionName, controllerName, routeValues, value); } /// /// Creates a object that produces a Created (201) response. /// /// The name of the route to use for generating the URL. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedAtRouteResult CreatedAtRoute(string routeName, object value) { return CreatedAtRoute(routeName, routeValues: null, value: value); } /// /// Creates a object that produces a Created (201) response. /// /// The route data to use for generating the URL. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedAtRouteResult CreatedAtRoute(object routeValues, object value) { return CreatedAtRoute(routeName: null, routeValues: routeValues, value: value); } /// /// Creates a object that produces a Created (201) response. /// /// The name of the route to use for generating the URL. /// The route data to use for generating the URL. /// The content value to format in the entity body. /// The created for the response. [NonAction] public virtual CreatedAtRouteResult CreatedAtRoute(string routeName, object routeValues, object value) { var disposableValue = value as IDisposable; if (disposableValue != null) { Response.RegisterForDispose(disposableValue); } return new CreatedAtRouteResult(routeName, routeValues, value); } /// /// Creates a . /// /// The created for the response. [NonAction] public virtual ChallengeResult Challenge() => new ChallengeResult(); /// /// Creates a with the specified authentication scheme. /// /// The authentication scheme to challenge. /// The created for the response. [NonAction] public virtual ChallengeResult Challenge(string authenticationScheme) => new ChallengeResult(authenticationScheme); /// /// Creates a with the specified authentication schemes. /// /// The authentication schemes to challenge. /// The created for the response. [NonAction] public virtual ChallengeResult Challenge(IList authenticationSchemes) => new ChallengeResult(authenticationSchemes); /// /// Creates a with the specified . /// /// used to perform the authentication /// challenge. /// The created for the response. [NonAction] public virtual ChallengeResult Challenge(AuthenticationProperties properties) => new ChallengeResult(properties); /// /// Creates a with the specified specified authentication scheme and /// . /// /// The authentication scheme to challenge. /// used to perform the authentication /// challenge. /// The created for the response. [NonAction] public virtual ChallengeResult Challenge(string authenticationScheme, AuthenticationProperties properties) => new ChallengeResult(authenticationScheme, properties); /// /// Creates a with the specified specified authentication schemes and /// . /// /// The authentication schemes to challenge. /// used to perform the authentication /// challenge. /// The created for the response. [NonAction] public virtual ChallengeResult Challenge( IList authenticationSchemes, AuthenticationProperties properties) => new ChallengeResult(authenticationSchemes, properties); /// /// Creates a . /// /// The created for the response. [NonAction] public virtual ForbidResult Forbid() => new ForbidResult(); /// /// Creates a with the specified authentication scheme. /// /// The authentication scheme to challenge. /// The created for the response. [NonAction] public virtual ForbidResult Forbid(string authenticationScheme) => new ForbidResult(authenticationScheme); /// /// Creates a with the specified authentication schemes. /// /// The authentication schemes to challenge. /// The created for the response. [NonAction] public virtual ForbidResult Forbid(IList authenticationSchemes) => new ForbidResult(authenticationSchemes); /// /// Creates a with the specified . /// /// used to perform the authentication /// challenge. /// The created for the response. [NonAction] public virtual ForbidResult Forbid(AuthenticationProperties properties) => new ForbidResult(properties); /// /// Creates a with the specified specified authentication scheme and /// . /// /// The authentication scheme to challenge. /// used to perform the authentication /// challenge. /// The created for the response. [NonAction] public virtual ForbidResult Forbid(string authenticationScheme, AuthenticationProperties properties) => new ForbidResult(authenticationScheme, properties); /// /// Creates a with the specified specified authentication schemes and /// . /// /// The authentication schemes to challenge. /// used to perform the authentication /// challenge. /// The created for the response. [NonAction] public virtual ForbidResult Forbid(IList authenticationSchemes, AuthenticationProperties properties) => new ForbidResult(authenticationSchemes, properties); /// /// Updates the specified instance using values from the controller's current /// . /// /// The type of the model object. /// The model instance to update. /// A that on completion returns true if the update is successful. [NonAction] public virtual Task TryUpdateModelAsync( TModel model) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } return TryUpdateModelAsync(model, prefix: string.Empty); } /// /// Updates the specified instance using values from the controller's current /// and a . /// /// The type of the model object. /// The model instance to update. /// The prefix to use when looking up values in the current . /// /// A that on completion returns true if the update is successful. [NonAction] public virtual Task TryUpdateModelAsync( TModel model, string prefix) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (prefix == null) { throw new ArgumentNullException(nameof(prefix)); } return TryUpdateModelAsync(model, prefix, new CompositeValueProvider(ControllerContext.ValueProviders)); } /// /// Updates the specified instance using the and a /// . /// /// The type of the model object. /// The model instance to update. /// The prefix to use when looking up values in the . /// /// The used for looking up values. /// A that on completion returns true if the update is successful. [NonAction] public virtual Task TryUpdateModelAsync( TModel model, string prefix, IValueProvider valueProvider) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (prefix == null) { throw new ArgumentNullException(nameof(prefix)); } if (valueProvider == null) { throw new ArgumentNullException(nameof(valueProvider)); } return ModelBindingHelper.TryUpdateModelAsync( model, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), valueProvider, ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders)); } /// /// Updates the specified instance using values from the controller's current /// and a . /// /// The type of the model object. /// The model instance to update. /// The prefix to use when looking up values in the current . /// /// (s) which represent top-level properties /// which need to be included for the current model. /// A that on completion returns true if the update is successful. [NonAction] public Task TryUpdateModelAsync( TModel model, string prefix, params Expression>[] includeExpressions) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (includeExpressions == null) { throw new ArgumentNullException(nameof(includeExpressions)); } return ModelBindingHelper.TryUpdateModelAsync( model, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), new CompositeValueProvider(ControllerContext.ValueProviders), ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders), includeExpressions); } /// /// Updates the specified instance using values from the controller's current /// and a . /// /// The type of the model object. /// The model instance to update. /// The prefix to use when looking up values in the current . /// /// A predicate which can be used to filter properties at runtime. /// A that on completion returns true if the update is successful. [NonAction] public Task TryUpdateModelAsync( TModel model, string prefix, Func predicate) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } return ModelBindingHelper.TryUpdateModelAsync( model, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), new CompositeValueProvider(ControllerContext.ValueProviders), ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders), predicate); } /// /// Updates the specified instance using the and a /// . /// /// The type of the model object. /// The model instance to update. /// The prefix to use when looking up values in the . /// /// The used for looking up values. /// (s) which represent top-level properties /// which need to be included for the current model. /// A that on completion returns true if the update is successful. [NonAction] public Task TryUpdateModelAsync( TModel model, string prefix, IValueProvider valueProvider, params Expression>[] includeExpressions) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (valueProvider == null) { throw new ArgumentNullException(nameof(valueProvider)); } if (includeExpressions == null) { throw new ArgumentNullException(nameof(includeExpressions)); } return ModelBindingHelper.TryUpdateModelAsync( model, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), valueProvider, ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders), includeExpressions); } /// /// Updates the specified instance using the and a /// . /// /// The type of the model object. /// The model instance to update. /// The prefix to use when looking up values in the . /// /// The used for looking up values. /// A predicate which can be used to filter properties at runtime. /// A that on completion returns true if the update is successful. [NonAction] public Task TryUpdateModelAsync( TModel model, string prefix, IValueProvider valueProvider, Func predicate) where TModel : class { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (valueProvider == null) { throw new ArgumentNullException(nameof(valueProvider)); } if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } return ModelBindingHelper.TryUpdateModelAsync( model, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), valueProvider, ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders), predicate); } /// /// Updates the specified instance using values from the controller's current /// and a . /// /// The model instance to update. /// The type of model instance to update. /// The prefix to use when looking up values in the current . /// /// A that on completion returns true if the update is successful. [NonAction] public virtual Task TryUpdateModelAsync( object model, Type modelType, string prefix) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (modelType == null) { throw new ArgumentNullException(nameof(modelType)); } return ModelBindingHelper.TryUpdateModelAsync( model, modelType, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), new CompositeValueProvider(ControllerContext.ValueProviders), ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders)); } /// /// Updates the specified instance using the and a /// . /// /// The model instance to update. /// The type of model instance to update. /// The prefix to use when looking up values in the . /// /// The used for looking up values. /// A predicate which can be used to filter properties at runtime. /// A that on completion returns true if the update is successful. [NonAction] public Task TryUpdateModelAsync( object model, Type modelType, string prefix, IValueProvider valueProvider, Func predicate) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (modelType == null) { throw new ArgumentNullException(nameof(modelType)); } if (valueProvider == null) { throw new ArgumentNullException(nameof(valueProvider)); } if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } return ModelBindingHelper.TryUpdateModelAsync( model, modelType, prefix, ControllerContext, MetadataProvider, new CompositeModelBinder(ControllerContext.ModelBinders), valueProvider, ControllerContext.InputFormatters, ObjectValidator, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders), predicate); } /// /// Validates the specified instance. /// /// The model to validate. /// true if the is valid; false otherwise. [NonAction] public virtual bool TryValidateModel( object model) { if (model == null) { throw new ArgumentNullException(nameof(model)); } return TryValidateModel(model, prefix: null); } /// /// Validates the specified instance. /// /// The model to validate. /// The key to use when looking up information in . /// /// true if the is valid;false otherwise. [NonAction] public virtual bool TryValidateModel( object model, string prefix) { if (model == null) { throw new ArgumentNullException(nameof(model)); } ObjectValidator.Validate( ControllerContext, new CompositeModelValidatorProvider(ControllerContext.ValidatorProviders), validationState: null, prefix: prefix ?? string.Empty, model: model); return ModelState.IsValid; } } }