using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.Common.Filters;
using Umbraco.Web.Models;
using Umbraco.Web.Routing;
namespace Umbraco.Web.Mvc
{
///
/// Represents the default front-end rendering controller.
///
[PreRenderViewActionFilter]
[TypeFilter(typeof(ModelBindingExceptionFilter))]
public class RenderMvcController : UmbracoController, IRenderMvcController
{
private IPublishedRequest _publishedRequest;
private readonly ILogger _logger;
private readonly ICompositeViewEngine _compositeViewEngine;
public RenderMvcController(ILogger logger, ICompositeViewEngine compositeViewEngine)
{
_logger = logger;
_compositeViewEngine = compositeViewEngine;
}
///
/// Gets the current content item.
///
protected IPublishedContent CurrentPage => PublishedRequest.PublishedContent;
///
/// Gets the current published content request.
///
protected internal virtual IPublishedRequest PublishedRequest
{
get
{
if (_publishedRequest != null)
return _publishedRequest;
if (RouteData.DataTokens.ContainsKey(Core.Constants.Web.PublishedDocumentRequestDataToken) == false)
{
throw new InvalidOperationException("DataTokens must contain an 'umbraco-doc-request' key with a PublishedRequest object");
}
_publishedRequest = (IPublishedRequest)RouteData.DataTokens[Core.Constants.Web.PublishedDocumentRequestDataToken];
return _publishedRequest;
}
}
///
/// Ensures that a physical view file exists on disk.
///
/// The view name.
protected bool EnsurePhsyicalViewExists(string template)
{
var result = _compositeViewEngine.FindView(ControllerContext, template, false);
if (result.View != null) return true;
_logger.LogWarning("No physical template file was found for template {Template}", template);
return false;
}
///
/// Gets an action result based on the template name found in the route values and a model.
///
/// The type of the model.
/// The model.
/// The action result.
/// If the template found in the route values doesn't physically exist, then an empty ContentResult will be returned.
protected IActionResult CurrentTemplate(T model)
{
var template = ControllerContext.RouteData.Values["action"].ToString();
if (EnsurePhsyicalViewExists(template) == false)
throw new InvalidOperationException("No physical template file was found for template " + template);
return View(template, model);
}
///
/// The default action to render the front-end view.
///
///
///
[RenderIndexActionSelector]
public virtual IActionResult Index(ContentModel model)
{
return CurrentTemplate(model);
}
}
}