// 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.Security.Claims;
using System.Security.Principal;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewComponents;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc
{
///
/// A base class for view components.
///
[ViewComponent]
public abstract class ViewComponent
{
private IUrlHelper _url;
private dynamic _viewBag;
private ViewComponentContext _viewComponentContext;
private ICompositeViewEngine _viewEngine;
///
/// Gets the .
///
public HttpContext HttpContext
{
get
{
return ViewContext?.HttpContext;
}
}
///
/// Gets the .
///
public HttpRequest Request
{
get
{
return ViewContext?.HttpContext?.Request;
}
}
///
/// Gets the for the current user.
///
public IPrincipal User
{
get
{
return ViewContext?.HttpContext?.User;
}
}
///
/// Gets the for the current user.
///
public ClaimsPrincipal UserClaimsPrincipal => ViewContext?.HttpContext?.User;
///
/// Gets the for the current request.
///
public RouteData RouteData
{
get
{
return ViewContext?.RouteData;
}
}
///
/// Gets the view bag.
///
public dynamic ViewBag
{
get
{
if (_viewBag == null)
{
_viewBag = new DynamicViewData(() => ViewData);
}
return _viewBag;
}
}
///
/// Gets the .
///
public ModelStateDictionary ModelState
{
get
{
return ViewData?.ModelState;
}
}
///
/// Gets or sets the .
///
public IUrlHelper Url
{
get
{
if (_url == null)
{
// May be null in unit-testing scenarios.
var services = ViewComponentContext.ViewContext?.HttpContext?.RequestServices;
var factory = services?.GetRequiredService();
_url = factory?.GetUrlHelper(ViewComponentContext.ViewContext);
}
return _url;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_url = value;
}
}
[ViewComponentContext]
public ViewComponentContext ViewComponentContext
{
get
{
// This should run only for the ViewComponent unit test scenarios.
if (_viewComponentContext == null)
{
_viewComponentContext = new ViewComponentContext();
}
return _viewComponentContext;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_viewComponentContext = value;
}
}
///
/// Gets the .
///
public ViewContext ViewContext
{
get
{
return ViewComponentContext.ViewContext;
}
}
///
/// Gets the .
///
public ViewDataDictionary ViewData
{
get
{
return ViewComponentContext.ViewData;
}
}
///
/// Gets the .
///
public ITempDataDictionary TempData
{
get
{
return ViewComponentContext.TempData;
}
}
///
/// Gets or sets the .
///
public ICompositeViewEngine ViewEngine
{
get
{
if (_viewEngine == null)
{
// May be null in unit-testing scenarios.
var services = ViewComponentContext.ViewContext?.HttpContext?.RequestServices;
_viewEngine = services?.GetRequiredService();
}
return _viewEngine;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_viewEngine = value;
}
}
///
/// Returns a result which will render HTML encoded text.
///
/// The content, will be HTML encoded before output.
/// A .
public ContentViewComponentResult Content(string content)
{
if (content == null)
{
throw new ArgumentNullException(nameof(content));
}
return new ContentViewComponentResult(content);
}
///
/// Returns a result which will render the partial view with name "Default".
///
/// A .
public ViewViewComponentResult View()
{
return View(viewName: null);
}
///
/// Returns a result which will render the partial view with name .
///
/// The name of the partial view to render.
/// A .
public ViewViewComponentResult View(string viewName)
{
return View(viewName, ViewData.Model);
}
///
/// Returns a result which will render the partial view with name "Default".
///
/// The model object for the view.
/// A .
public ViewViewComponentResult View(TModel model)
{
return View(viewName: null, model: model);
}
///
/// Returns a result which will render the partial view with name .
///
/// The name of the partial view to render.
/// The model object for the view.
/// A .
public ViewViewComponentResult View(string viewName, TModel model)
{
var viewData = new ViewDataDictionary(ViewData, model);
return new ViewViewComponentResult
{
ViewEngine = ViewEngine,
ViewName = viewName,
ViewData = viewData
};
}
}
}