// 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.IO;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.Internal;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
namespace Microsoft.AspNet.Mvc
{
///
/// Base class for an MVC controller.
///
public abstract class Controller : IActionFilter, IAsyncActionFilter, IDisposable
{
private DynamicViewData _viewBag;
private ViewDataDictionary _viewData;
private ActionContext _actionContext;
///
/// Gets the request-specific .
///
public IServiceProvider Resolver
{
get
{
return ActionContext?.HttpContext?.RequestServices;
}
}
///
/// Gets the for the executing action.
///
public HttpContext Context
{
get
{
return ActionContext?.HttpContext;
}
}
///
/// Gets the for the executing action.
///
public HttpRequest Request
{
get
{
return ActionContext?.HttpContext?.Request;
}
}
///
/// Gets the for the executing action.
///
public HttpResponse Response
{
get
{
return ActionContext?.HttpContext?.Response;
}
}
///
/// Gets the for the executing action.
///
public RouteData RouteData
{
get
{
return ActionContext?.RouteData;
}
}
///
/// Gets the that contains the state of the model and of model-binding validation.
///
public ModelStateDictionary ModelState
{
get
{
return ViewData?.ModelState;
}
}
///
/// Gets or sets the object.
///
///
/// activates this property while activating controllers. If user codes
/// directly instantiate controllers, the getter returns an empty .
///
[ActionContext]
public ActionContext ActionContext
{
get
{
// This should run only for the controller unit test scenarios
_actionContext = _actionContext ?? new ActionContext();
return _actionContext;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_actionContext = value;
}
}
///
/// Gets or sets the .
///
[ActionBindingContext]
public ActionBindingContext BindingContext { get; set; }
///
/// Gets or sets the .
///
[FromServices]
public IModelMetadataProvider MetadataProvider { get; set; }
///
/// Gets or sets the .
///
[FromServices]
public IUrlHelper Url { get; set; }
[FromServices]
public IObjectModelValidator ObjectValidator { get; set; }
///
/// Gets or sets the for user associated with the executing action.
///
public ClaimsPrincipal User
{
get
{
return Context?.User;
}
}
///
/// Gets or sets used by and .
///
///
/// By default, this property is activated when activates controllers.
/// However, when controllers are directly instantiated in user codes, this property is initialized with
/// .
///
[ViewDataDictionary]
public ViewDataDictionary ViewData
{
get
{
if (_viewData == null)
{
// This should run only for the controller unit test scenarios
_viewData =
new ViewDataDictionary(new EmptyModelMetadataProvider(),
ActionContext?.ModelState ?? new ModelStateDictionary());
}
return _viewData;
}
set
{
if (value == null)
{
throw
new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(ViewData));
}
_viewData = value;
}
}
///
/// Gets or sets used by .
///
[FromServices]
public ITempDataDictionary TempData { get; set; }
///
/// Gets the dynamic view bag.
///
public dynamic ViewBag
{
get
{
if (_viewBag == null)
{
_viewBag = new DynamicViewData(() => ViewData);
}
return _viewBag;
}
}
///
/// Creates a object that renders a view to the response.
///
/// The created object for the response.
[NonAction]
public virtual ViewResult View()
{
return View(viewName: null);
}
///
/// Creates a object by specifying a .
///
/// The name of the view that is rendered to the response.
/// The created object for the response.
[NonAction]
public virtual ViewResult View(string viewName)
{
return View(viewName, model: null);
}
///
/// Creates a object by specifying a
/// to be rendered by the view.
///
/// The model that is rendered by the view.
/// The created object for the response.
[NonAction]
public virtual ViewResult View(object model)
{
return View(viewName: null, model: model);
}
///
/// Creates a object by specifying a
/// and the to be rendered by the view.
///
/// The name of the view that is rendered to the response.
/// The model that is rendered by the view.
/// The created object for the response.
[NonAction]
public virtual ViewResult View(string viewName, object model)
{
// Do not override ViewData.Model unless passed a non-null value.
if (model != null)
{
ViewData.Model = model;
}
return new ViewResult()
{
ViewName = viewName,
ViewData = ViewData,
TempData = TempData
};
}
///
/// Creates a object that renders a partial view to the response.
///
/// The created object for the response.
[NonAction]
public virtual PartialViewResult PartialView()
{
return PartialView(viewName: null);
}
///
/// Creates a object by specifying a .
///
/// The name of the view that is rendered to the response.
/// The created object for the response.
[NonAction]
public virtual PartialViewResult PartialView(string viewName)
{
return PartialView(viewName, model: null);
}
///
/// Creates a object by specifying a
/// to be rendered by the partial view.
///
/// The model that is rendered by the partial view.
/// The created object for the response.
[NonAction]
public virtual PartialViewResult PartialView(object model)
{
return PartialView(viewName: null, model: model);
}
///
/// Creates a object by specifying a
/// and the to be rendered by the partial view.
///
/// The name of the partial view that is rendered to the response.
/// The model that is rendered by the partial view.
/// The created object for the response.
[NonAction]
public virtual PartialViewResult PartialView(string viewName, object model)
{
// Do not override ViewData.Model unless passed a non-null value.
if (model != null)
{
ViewData.Model = model;
}
return new PartialViewResult()
{
ViewName = viewName,
ViewData = ViewData,
TempData = TempData
};
}
///
/// 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, contentType, contentEncoding: null);
}
///
/// 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.
[NonAction]
public virtual ContentResult Content(string content, string contentType, Encoding contentEncoding)
{
return Content(content, new MediaTypeHeaderValue(contentType) { Encoding = contentEncoding });
}
///
/// 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
};
return result;
}
///
/// Creates a object that serializes the specified object
/// to JSON.
///
/// The object to serialize.
/// The created that serializes the specified
/// to JSON format for the response.
[NonAction]
public virtual JsonResult Json(object data)
{
var disposableValue = data as IDisposable;
if (disposableValue != null)
{
Response.RegisterForDispose(disposableValue);
}
return new JsonResult(data);
}
///
/// Creates a object that serializes the specified object
/// to JSON.
///
/// The object to serialize.
/// The to be used by
/// the formatter.
/// The created that serializes the specified
/// as JSON format for the response.
/// Callers should cache an instance of to avoid
/// recreating cached data with each call.
[NonAction]
public virtual JsonResult Json(object data, [NotNull] JsonSerializerSettings serializerSettings)
{
var disposableValue = data as IDisposable;
if (disposableValue != null)
{
Response.RegisterForDispose(disposableValue);
}
return new JsonResult(data, serializerSettings);
}
///
/// 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);
}
///
/// 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, PropertyHelper.ObjectToDictionary(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,
PropertyHelper.ObjectToDictionary(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 with the contents of the file.
/// The Content-Type of the file.
/// The created for the response.
[NonAction]
public virtual FilePathResult File(string fileName, string contentType)
{
return File(fileName, contentType, fileDownloadName: null);
}
///
/// Returns the file specified by 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 FilePathResult File(string fileName, string contentType, string fileDownloadName)
{
return new FilePathResult(fileName, contentType) { FileDownloadName = fileDownloadName };
}
///
/// Creates an that produces an Unauthorized (401) response.
///
/// The created for the response.
[NonAction]
public virtual HttpUnauthorizedResult HttpUnauthorized()
{
return new HttpUnauthorizedResult();
}
///
/// Creates an that produces a Not Found (404) response.
///
/// The created for the response.
[NonAction]
public virtual HttpNotFoundResult HttpNotFound()
{
return new HttpNotFoundResult();
}
///
/// Creates an that produces a Not Found (404) response.
///
/// The created for the response.
[NonAction]
public virtual HttpNotFoundObjectResult HttpNotFound(object value)
{
var disposableValue = value as IDisposable;
if (disposableValue != null)
{
Response.RegisterForDispose(disposableValue);
}
return new HttpNotFoundObjectResult(value);
}
///
/// Creates an that produces a Bad Request (400) response.
///
/// The created for the response.
[NonAction]
public virtual BadRequestResult HttpBadRequest()
{
return new BadRequestResult();
}
///
/// Creates an that produces a Bad Request (400) response.
///
/// The created for the response.
[NonAction]
public virtual BadRequestObjectResult HttpBadRequest(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 HttpBadRequest([NotNull] ModelStateDictionary 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([NotNull] string uri, object value)
{
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([NotNull] Uri uri, object value)
{
string location;
if (uri.IsAbsoluteUri)
{
location = uri.AbsoluteUri;
}
else
{
location = uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
}
return Created(location, 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);
}
///
/// Called before the action method is invoked.
///
/// The action executing context.
[NonAction]
public virtual void OnActionExecuting([NotNull] ActionExecutingContext context)
{
}
///
/// Called after the action method is invoked.
///
/// The action executed context.
[NonAction]
public virtual void OnActionExecuted([NotNull] ActionExecutedContext context)
{
}
///
/// Called before the action method is invoked.
///
/// The action executing context.
/// The to execute. Invoke this delegate in the body
/// of to continue execution of the action.
/// A instance.
[NonAction]
public virtual async Task OnActionExecutionAsync(
[NotNull] ActionExecutingContext context,
[NotNull] ActionExecutionDelegate next)
{
OnActionExecuting(context);
if (context.Result == null)
{
OnActionExecuted(await next());
}
}
///
/// 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([NotNull] TModel model)
where TModel : class
{
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 async Task TryUpdateModelAsync([NotNull] TModel model,
[NotNull] string prefix)
where TModel : class
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await TryUpdateModelAsync(model, prefix, BindingContext.ValueProvider);
}
///
/// 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 async Task TryUpdateModelAsync([NotNull] TModel model,
[NotNull] string prefix,
[NotNull] IValueProvider valueProvider)
where TModel : class
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider);
}
///
/// 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 async Task TryUpdateModelAsync(
[NotNull] TModel model,
string prefix,
[NotNull] params Expression>[] includeExpressions)
where TModel : class
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
BindingContext.ValueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
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 async Task TryUpdateModelAsync(
[NotNull] TModel model,
string prefix,
[NotNull] Func predicate)
where TModel : class
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
BindingContext.ValueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
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 async Task TryUpdateModelAsync(
[NotNull] TModel model,
string prefix,
[NotNull] IValueProvider valueProvider,
[NotNull] params Expression>[] includeExpressions)
where TModel : class
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
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 async Task TryUpdateModelAsync(
[NotNull] TModel model,
string prefix,
[NotNull] IValueProvider valueProvider,
[NotNull] Func predicate)
where TModel : class
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
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 async Task TryUpdateModelAsync([NotNull] object model,
[NotNull] Type modelType,
string prefix)
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
modelType,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
BindingContext.ValueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider);
}
///
/// 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 async Task TryUpdateModelAsync(
[NotNull] object model,
[NotNull] Type modelType,
string prefix,
[NotNull] IValueProvider valueProvider,
[NotNull] Func predicate)
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
return await ModelBindingHelper.TryUpdateModelAsync(
model,
modelType,
prefix,
ActionContext.HttpContext,
ModelState,
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
predicate);
}
///
/// Validates the specified instance.
///
/// The model to validate.
/// true if the is valid; false otherwise.
[NonAction]
public virtual bool TryValidateModel([NotNull] object 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([NotNull] object model, string prefix)
{
if (BindingContext == null)
{
var message = Resources.FormatPropertyOfTypeCannotBeNull(
nameof(BindingContext),
typeof(Controller).FullName);
throw new InvalidOperationException(message);
}
var modelExplorer = MetadataProvider.GetModelExplorerForType(model.GetType(), model);
var modelName = prefix ?? string.Empty;
// Clear ModelStateDictionary entries for the model so that it will be re-validated.
ModelBindingHelper.ClearValidationStateForModel(
model.GetType(),
ModelState,
MetadataProvider,
modelName);
var validationContext = new ModelValidationContext(
bindingSource: null,
validatorProvider: BindingContext.ValidatorProvider,
modelState: ModelState,
modelExplorer: modelExplorer);
ObjectValidator.Validate(
validationContext,
new ModelValidationNode(modelName, modelExplorer.Metadata, model)
{
ValidateAllProperties = true
});
return ModelState.IsValid;
}
///
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
///
/// Releases all resources currently used by this instance.
///
/// true if this method is being invoked by the method,
/// otherwise false.
protected virtual void Dispose(bool disposing)
{
}
}
}