// 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 }; } } }