using System; using System.Collections.Specialized; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.Services; using Umbraco.Web.Common.Controllers; using Umbraco.Web.Routing; using Umbraco.Web.Website.ActionResults; namespace Umbraco.Web.Website.Controllers { /// /// Provides a base class for front-end add-in controllers. /// // TODO: Migrate MergeModelStateToChildAction and MergeParentContextViewData action filters // [MergeModelStateToChildAction] // [MergeParentContextViewData] public abstract class SurfaceController : PluginController { private readonly IPublishedUrlProvider _publishedUrlProvider; /// /// Gets the current page. /// protected virtual IPublishedContent CurrentPage { get { var routeDefAttempt = TryGetRouteDefinitionFromAncestorViewContexts(); if (routeDefAttempt.Success == false) throw routeDefAttempt.Exception; var routeDef = routeDefAttempt.Result; return routeDef.PublishedRequest.PublishedContent; } } protected SurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, ILogger logger, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider) : base(umbracoContextAccessor, databaseFactory, services, appCaches, logger, profilingLogger) { _publishedUrlProvider = publishedUrlProvider; } /// /// Redirects to the Umbraco page with the given id /// /// /// protected RedirectToUmbracoPageResult RedirectToUmbracoPage(int pageId) { return new RedirectToUmbracoPageResult(pageId, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the Umbraco page with the given id and passes provided querystring /// /// /// /// protected RedirectToUmbracoPageResult RedirectToUmbracoPage(int pageId, NameValueCollection queryStringValues) { return new RedirectToUmbracoPageResult(pageId, queryStringValues, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the Umbraco page with the given id and passes provided querystring /// /// /// /// protected RedirectToUmbracoPageResult RedirectToUmbracoPage(int pageId, string queryString) { return new RedirectToUmbracoPageResult(pageId, queryString, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the Umbraco page with the given published content /// /// /// protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent) { return new RedirectToUmbracoPageResult(publishedContent, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the Umbraco page with the given published content and passes provided querystring /// /// /// /// protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent, NameValueCollection queryStringValues) { return new RedirectToUmbracoPageResult(publishedContent, queryStringValues, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the Umbraco page with the given published content and passes provided querystring /// /// /// /// protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent, string queryString) { return new RedirectToUmbracoPageResult(publishedContent, queryString, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the currently rendered Umbraco page /// /// protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage() { return new RedirectToUmbracoPageResult(CurrentPage, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the currently rendered Umbraco page and passes provided querystring /// /// /// protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage(NameValueCollection queryStringValues) { return new RedirectToUmbracoPageResult(CurrentPage, queryStringValues, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the currently rendered Umbraco page and passes provided querystring /// /// /// protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage(string queryString) { return new RedirectToUmbracoPageResult(CurrentPage, queryString, _publishedUrlProvider, UmbracoContextAccessor); } /// /// Redirects to the currently rendered Umbraco URL /// /// /// /// This is useful if you need to redirect /// to the current page but the current page is actually a rewritten URL normally done with something like /// Server.Transfer.* /// protected RedirectToUmbracoUrlResult RedirectToCurrentUmbracoUrl() { return new RedirectToUmbracoUrlResult(UmbracoContext); } /// /// Returns the currently rendered Umbraco page /// /// protected UmbracoPageResult CurrentUmbracoPage() { return new UmbracoPageResult(ProfilingLogger); } /// /// we need to recursively find the route definition based on the parent view context /// /// private Attempt TryGetRouteDefinitionFromAncestorViewContexts() { var currentContext = ControllerContext; while (!(currentContext is null)) { var currentRouteData = currentContext.RouteData; if (currentRouteData.DataTokens.ContainsKey(Core.Constants.Web.UmbracoRouteDefinitionDataToken)) return Attempt.Succeed((RouteDefinition)currentRouteData.DataTokens[Core.Constants.Web.UmbracoRouteDefinitionDataToken]); } return Attempt.Fail( new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request")); } } }