// 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.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc
{
///
/// A base class for an MVC controller with view support.
///
public abstract class Controller : ControllerBase, IActionFilter, IAsyncActionFilter, IDisposable
{
private ITempDataDictionary _tempData;
private DynamicViewData _viewBag;
private ViewDataDictionary _viewData;
///
/// Gets or sets used by and .
///
///
/// By default, this property is activated when activates
/// controllers. However, when controllers are directly instantiated in user code, 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(), ControllerContext.ModelState);
}
return _viewData;
}
set
{
if (value == null)
{
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(ViewData));
}
_viewData = value;
}
}
///
/// Gets or sets used by .
///
public ITempDataDictionary TempData
{
get
{
if (_tempData == null)
{
var factory = HttpContext?.RequestServices?.GetRequiredService();
_tempData = factory?.GetTempData(HttpContext);
}
return _tempData;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_tempData = value;
}
}
///
/// 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: ViewData.Model);
}
///
/// 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)
{
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: ViewData.Model);
}
///
/// 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)
{
ViewData.Model = model;
return new PartialViewResult()
{
ViewName = viewName,
ViewData = ViewData,
TempData = TempData
};
}
///
/// Creates a by specifying the name of a view component to render.
///
///
/// The view component name. Can be a view component
/// or
/// .
/// The created object for the response.
[NonAction]
public virtual ViewComponentResult ViewComponent(string componentName)
{
return ViewComponent(componentName, arguments: null);
}
///
/// Creates a by specifying the of a view component to
/// render.
///
/// The view component .
/// The created object for the response.
[NonAction]
public virtual ViewComponentResult ViewComponent(Type componentType)
{
return ViewComponent(componentType, arguments: null);
}
///
/// Creates a by specifying the name of a view component to render.
///
///
/// The view component name. Can be a view component
/// or
/// .
///
/// An with properties representing arguments to be passed to the invoked view component
/// method. Alternatively, an instance
/// containing the invocation arguments.
///
/// The created object for the response.
[NonAction]
public virtual ViewComponentResult ViewComponent(string componentName, object arguments)
{
return new ViewComponentResult
{
ViewComponentName = componentName,
Arguments = arguments,
ViewData = ViewData,
TempData = TempData
};
}
///
/// Creates a by specifying the of a view component to
/// render.
///
/// The view component .
///
/// An with properties representing arguments to be passed to the invoked view component
/// method. Alternatively, an instance
/// containing the invocation arguments.
///
/// The created object for the response.
[NonAction]
public virtual ViewComponentResult ViewComponent(Type componentType, object arguments)
{
return new ViewComponentResult
{
ViewComponentType = componentType,
Arguments = arguments,
ViewData = ViewData,
TempData = TempData
};
}
///
/// 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)
{
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, JsonSerializerSettings serializerSettings)
{
if (serializerSettings == null)
{
throw new ArgumentNullException(nameof(serializerSettings));
}
return new JsonResult(data, serializerSettings);
}
///
/// Called before the action method is invoked.
///
/// The action executing context.
[NonAction]
public virtual void OnActionExecuting(ActionExecutingContext context)
{
}
///
/// Called after the action method is invoked.
///
/// The action executed context.
[NonAction]
public virtual void OnActionExecuted(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(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (next == null)
{
throw new ArgumentNullException(nameof(next));
}
OnActionExecuting(context);
if (context.Result == null)
{
OnActionExecuted(await next());
}
}
///
public void Dispose() => Dispose(disposing: true);
///
/// 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)
{
}
}
}