Merge remote-tracking branch 'origin/netcore/netcore' into netcore/feature/remove-httpresponseexception

This commit is contained in:
Elitsa Marinovska
2020-12-29 14:40:03 +01:00
449 changed files with 10108 additions and 9853 deletions

View File

@@ -30,10 +30,10 @@ using Umbraco.Web.BackOffice.Security;
using Umbraco.Web.Common.ActionsResults;
using Umbraco.Web.Common.Attributes;
using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Common.Controllers;
using Umbraco.Web.Common.Filters;
using Umbraco.Web.Common.Security;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebAssets;
using Constants = Umbraco.Core.Constants;

View File

@@ -621,19 +621,20 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Saves content
/// </summary>
/// <returns></returns>
[FileUploadCleanupFilter]
[ContentSaveValidation]
public async Task<ContentItemDisplay> PostSaveBlueprint([ModelBinder(typeof(BlueprintItemBinder))] ContentItemSave contentItem)
{
var contentItemDisplay = await PostSaveInternal(contentItem,
var contentItemDisplay = await PostSaveInternal(
contentItem,
content =>
{
EnsureUniqueName(content.Name, content, "Name");
_contentService.SaveBlueprint(contentItem.PersistedContent, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
//we need to reuse the underlying logic so return the result that it wants
return OperationResult.Succeed(new EventMessages());
// we need to reuse the underlying logic so return the result that it wants
return OperationResult.Succeed(new EventMessages());
},
content =>
{
@@ -648,7 +649,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Saves content
/// </summary>
/// <returns></returns>
[FileUploadCleanupFilter]
[ContentSaveValidation]
[OutgoingEditorModelEvent]
@@ -664,9 +664,9 @@ namespace Umbraco.Web.BackOffice.Controllers
private async Task<ActionResult<ContentItemDisplay>> PostSaveInternal(ContentItemSave contentItem, Func<IContent, OperationResult> saveMethod, Func<IContent, ContentItemDisplay> mapToDisplay)
{
//Recent versions of IE/Edge may send in the full client side file path instead of just the file name.
//To ensure similar behavior across all browsers no matter what they do - we strip the FileName property of all
//uploaded files to being *only* the actual file name (as it should be).
// Recent versions of IE/Edge may send in the full client side file path instead of just the file name.
// To ensure similar behavior across all browsers no matter what they do - we strip the FileName property of all
// uploaded files to being *only* the actual file name (as it should be).
if (contentItem.UploadedFiles != null && contentItem.UploadedFiles.Any())
{
foreach (var file in contentItem.UploadedFiles)
@@ -675,7 +675,7 @@ namespace Umbraco.Web.BackOffice.Controllers
}
}
//If we've reached here it means:
// If we've reached here it means:
// * Our model has been bound
// * and validated
// * any file attachments have been saved to their temporary location for us to use
@@ -685,20 +685,20 @@ namespace Umbraco.Web.BackOffice.Controllers
var passesCriticalValidationRules = ValidateCriticalData(contentItem, out var variantCount);
//we will continue to save if model state is invalid, however we cannot save if critical data is missing.
// we will continue to save if model state is invalid, however we cannot save if critical data is missing.
if (!ModelState.IsValid)
{
//check for critical data validation issues, we can't continue saving if this data is invalid
// check for critical data validation issues, we can't continue saving if this data is invalid
if (!passesCriticalValidationRules)
{
//ok, so the absolute mandatory data is invalid and it's new, we cannot actually continue!
// ok, so the absolute mandatory data is invalid and it's new, we cannot actually continue!
// add the model state to the outgoing object and throw a validation message
var forDisplay = mapToDisplay(contentItem.PersistedContent);
forDisplay.Errors = ModelState.ToErrorDictionary();
return new ValidationErrorResult(forDisplay);
}
//if there's only one variant and the model state is not valid we cannot publish so change it to save
// if there's only one variant and the model state is not valid we cannot publish so change it to save
if (variantCount == 1)
{
switch (contentItem.Action)

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -29,14 +29,12 @@ namespace Umbraco.Web.BackOffice.Controllers
[JsonDateTimeFormat]
public abstract class ContentControllerBase : BackOfficeNotificationsController
{
protected ICultureDictionary CultureDictionary { get; }
protected ILoggerFactory LoggerFactory { get; }
protected IShortStringHelper ShortStringHelper { get; }
protected IEventMessagesFactory EventMessages { get; }
protected ILocalizedTextService LocalizedTextService { get; }
private readonly ILogger<ContentControllerBase> _logger;
private readonly IJsonSerializer _serializer;
/// <summary>
/// Initializes a new instance of the <see cref="ContentControllerBase"/> class.
/// </summary>
protected ContentControllerBase(
ICultureDictionary cultureDictionary,
ILoggerFactory loggerFactory,
@@ -54,6 +52,31 @@ namespace Umbraco.Web.BackOffice.Controllers
_serializer = serializer;
}
/// <summary>
/// Gets the <see cref="ICultureDictionary"/>
/// </summary>
protected ICultureDictionary CultureDictionary { get; }
/// <summary>
/// Gets the <see cref="ILoggerFactory"/>
/// </summary>
protected ILoggerFactory LoggerFactory { get; }
/// <summary>
/// Gets the <see cref="IShortStringHelper"/>
/// </summary>
protected IShortStringHelper ShortStringHelper { get; }
/// <summary>
/// Gets the <see cref="IEventMessagesFactory"/>
/// </summary>
protected IEventMessagesFactory EventMessages { get; }
/// <summary>
/// Gets the <see cref="ILocalizedTextService"/>
/// </summary>
protected ILocalizedTextService LocalizedTextService { get; }
protected NotFoundObjectResult HandleContentNotFound(object id, bool throwException = true)
{
ModelState.AddModelError("id", $"content with id: {id} was not found");

View File

@@ -114,8 +114,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Gets the document type a given id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[DetermineAmbiguousActionByPassingParameters]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public ActionResult<DocumentTypeDisplay> GetById(int id)
@@ -133,8 +131,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Gets the document type a given guid
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[DetermineAmbiguousActionByPassingParameters]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public ActionResult<DocumentTypeDisplay> GetById(Guid id)
@@ -152,8 +148,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Gets the document type a given udi
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[DetermineAmbiguousActionByPassingParameters]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public ActionResult<DocumentTypeDisplay> GetById(Udi id)
@@ -175,8 +169,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Deletes a document type with a given ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete]
[HttpPost]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
@@ -195,7 +187,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Gets all user defined properties.
/// </summary>
/// <returns></returns>
[Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)]
public IEnumerable<string> GetAllPropertyTypeAliases()
{
@@ -205,7 +196,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Gets all the standard fields.
/// </summary>
/// <returns></returns>
[Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)]
public IEnumerable<string> GetAllStandardFields()
{
@@ -217,8 +207,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Returns the available compositions for this content type
/// This has been wrapped in a dto instead of simple parameters to support having multiple parameters in post request body
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
[HttpPost]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public IActionResult GetAvailableCompositeContentTypes(GetAvailableCompositionsFilter filter)
@@ -235,7 +223,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Returns true if any content types have culture variation enabled
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
public bool AllowsCultureVariation()
@@ -248,8 +235,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Returns where a particular composition has been used
/// This has been wrapped in a dto instead of simple parameters to support having multiple parameters in post request body
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
[HttpPost]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public IActionResult GetWhereCompositionIsUsedInContentTypes(GetAvailableCompositionsFilter filter)
@@ -287,8 +272,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// Deletes a document type container with a given ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete]
[HttpPost]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]

View File

@@ -1,4 +1,4 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Options;
@@ -108,7 +108,6 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <summary>
/// The endpoint that is loaded within the preview iframe
/// </summary>
/// <returns></returns>
[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
public ActionResult Frame(int id, string culture)
{
@@ -119,22 +118,17 @@ namespace Umbraco.Web.BackOffice.Controllers
return RedirectPermanent($"../../{id}.aspx{query}");
}
public ActionResult EnterPreview(int id)
{
var user = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
var previewToken = _publishedSnapshotService.EnterPreview(user, id);
_cookieManager.SetCookieValue(Constants.Web.PreviewCookieName, previewToken);
_cookieManager.SetCookieValue(Constants.Web.PreviewCookieName, "preview");
return null;
}
public ActionResult End(string redir = null)
{
var previewToken = _cookieManager.GetPreviewCookieValue();
_publishedSnapshotService.ExitPreview(previewToken);
_cookieManager.ExpireCookie(Constants.Web.PreviewCookieName);
// Expire Client-side cookie that determines whether the user has accepted to be in Preview Mode when visiting the website.

View File

@@ -1,5 +1,6 @@
using System;
using System;
using System.Reflection.Metadata;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Core;
using Umbraco.Web.Cache;
@@ -8,43 +9,54 @@ using Umbraco.Web.PublishedCache;
namespace Umbraco.Web.BackOffice.Controllers
{
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
public class PublishedSnapshotCacheStatusController : UmbracoAuthorizedApiController
{
private readonly IPublishedSnapshotService _publishedSnapshotService;
private readonly IPublishedSnapshotStatus _publishedSnapshotStatus;
private readonly DistributedCache _distributedCache;
public PublishedSnapshotCacheStatusController(IPublishedSnapshotService publishedSnapshotService, DistributedCache distributedCache)
/// <summary>
/// Initializes a new instance of the <see cref="PublishedSnapshotCacheStatusController"/> class.
/// </summary>
public PublishedSnapshotCacheStatusController(
IPublishedSnapshotService publishedSnapshotService,
IPublishedSnapshotStatus publishedSnapshotStatus,
DistributedCache distributedCache)
{
_publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService));
_publishedSnapshotStatus = publishedSnapshotStatus;
_distributedCache = distributedCache;
}
/// <summary>
/// Rebuilds the Database cache
/// </summary>
[HttpPost]
public string RebuildDbCache()
{
_publishedSnapshotService.Rebuild();
return _publishedSnapshotService.GetStatus();
return _publishedSnapshotStatus.GetStatus();
}
/// <summary>
/// Gets a status report
/// </summary>
[HttpGet]
public string GetStatus()
{
return _publishedSnapshotService.GetStatus();
}
public string GetStatus() => _publishedSnapshotStatus.GetStatus();
/// <summary>
/// Cleans up unused snapshots
/// </summary>
[HttpGet]
public string Collect()
public async Task<string> Collect()
{
GC.Collect();
_publishedSnapshotService.Collect();
return _publishedSnapshotService.GetStatus();
await _publishedSnapshotService.CollectAsync();
return _publishedSnapshotStatus.GetStatus();
}
[HttpPost]
public void ReloadCache()
{
_distributedCache.RefreshAllPublishedSnapshot();
}
public void ReloadCache() => _distributedCache.RefreshAllPublishedSnapshot();
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Web.PublishedCache;
@@ -6,22 +6,22 @@ namespace Umbraco.Web.BackOffice.Controllers
{
public class PublishedStatusController : UmbracoAuthorizedApiController
{
private readonly IPublishedSnapshotService _publishedSnapshotService;
private readonly IPublishedSnapshotStatus _publishedSnapshotStatus;
public PublishedStatusController(IPublishedSnapshotService publishedSnapshotService)
public PublishedStatusController(IPublishedSnapshotStatus publishedSnapshotStatus)
{
_publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService));
_publishedSnapshotStatus = publishedSnapshotStatus ?? throw new ArgumentNullException(nameof(publishedSnapshotStatus));
}
[HttpGet]
public string GetPublishedStatusUrl()
{
if (!string.IsNullOrWhiteSpace(_publishedSnapshotService.StatusUrl))
if (!string.IsNullOrWhiteSpace(_publishedSnapshotStatus.StatusUrl))
{
return _publishedSnapshotService.StatusUrl;
return _publishedSnapshotStatus.StatusUrl;
}
throw new NotSupportedException("Not supported: " + _publishedSnapshotService.GetType().FullName);
throw new NotSupportedException("Not supported: " + _publishedSnapshotStatus.GetType().FullName);
}
}
}