Gets all list views working correctly with content apps, fixes various issues, cleans up a bunch of code and reduces amount of service locator.
This commit is contained in:
@@ -43,7 +43,20 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
where TPersisted : class, IContentBase
|
||||
where TModelSave : ContentBaseItemSave<TPersisted>
|
||||
{
|
||||
protected ServiceContext Services => Current.Services; // fixme - inject
|
||||
protected Core.Logging.ILogger Logger { get; }
|
||||
protected ServiceContext Services { get; }
|
||||
protected IUmbracoContextAccessor UmbracoContextAccessor { get; }
|
||||
|
||||
public ContentItemBaseBinder() : this(Current.Logger, Current.Services, Current.UmbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
public ContentItemBaseBinder(Core.Logging.ILogger logger, ServiceContext services, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
Logger = logger;
|
||||
Services = services;
|
||||
UmbracoContextAccessor = umbracoContextAccessor;
|
||||
}
|
||||
|
||||
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
|
||||
{
|
||||
@@ -58,29 +71,18 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
Directory.CreateDirectory(root);
|
||||
var provider = new MultipartFormDataStreamProvider(root);
|
||||
|
||||
var task = Task.Run(() => GetModelAsync(actionContext, bindingContext, provider))
|
||||
.ContinueWith(x =>
|
||||
{
|
||||
if (x.IsFaulted && x.Exception != null)
|
||||
{
|
||||
throw x.Exception;
|
||||
}
|
||||
|
||||
//now that everything is binded, validate the properties
|
||||
var contentItemValidator = GetValidationHelper();
|
||||
contentItemValidator.ValidateItem(actionContext, x.Result);
|
||||
|
||||
bindingContext.Model = x.Result;
|
||||
});
|
||||
|
||||
task.Wait();
|
||||
var model = GetModel(actionContext, bindingContext, provider);
|
||||
//now that everything is binded, validate the properties
|
||||
var contentItemValidator = GetValidationHelper();
|
||||
contentItemValidator.ValidateItem(actionContext, model);
|
||||
bindingContext.Model = model;
|
||||
|
||||
return bindingContext.Model != null;
|
||||
}
|
||||
|
||||
protected virtual ContentItemValidationHelper<TPersisted, TModelSave> GetValidationHelper()
|
||||
{
|
||||
return new ContentItemValidationHelper<TPersisted, TModelSave>();
|
||||
return new ContentItemValidationHelper<TPersisted, TModelSave>(Logger, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,29 +92,13 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
/// <param name="bindingContext"></param>
|
||||
/// <param name="provider"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<TModelSave> GetModelAsync(HttpActionContext actionContext, ModelBindingContext bindingContext, MultipartFormDataStreamProvider provider)
|
||||
private TModelSave GetModel(HttpActionContext actionContext, ModelBindingContext bindingContext, MultipartFormDataStreamProvider provider)
|
||||
{
|
||||
// note
|
||||
//
|
||||
// for some reason, due to the way we do async, HttpContext.Current is null
|
||||
// which means that the 'current' UmbracoContext is null too since we are using HttpContextUmbracoContextAccessor
|
||||
// trying to 'EnsureContext' fails because that accessor cannot access the HttpContext either to register the current UmbracoContext
|
||||
//
|
||||
// so either we go with an HybridUmbracoContextAccessor that relies on a ThreadStatic variable when HttpContext.Current is null
|
||||
// and I don't like it
|
||||
// or
|
||||
// we try to force-set the current http context, because, hey... it's there.
|
||||
// and then there is no need to event 'Ensure' anything
|
||||
// read http://stackoverflow.com/questions/1992141/how-do-i-get-an-httpcontext-object-from-httpcontextbase-in-asp-net-mvc-1
|
||||
|
||||
// what's below works but I cannot say I am proud of it
|
||||
var request = actionContext.Request;
|
||||
var httpContext = (HttpContextBase) request.Properties["MS_HttpContext"];
|
||||
HttpContext.Current = httpContext.ApplicationInstance.Context;
|
||||
|
||||
var content = request.Content;
|
||||
|
||||
var result = await content.ReadAsMultipartAsync(provider);
|
||||
var result = content.ReadAsMultipartAsync(provider).Result;
|
||||
|
||||
if (result.FormData["contentItem"] == null)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,10 @@ using System.Net.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Mapping;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
@@ -14,9 +17,18 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
{
|
||||
internal class ContentItemBinder : ContentItemBaseBinder<IContent, ContentItemSave>
|
||||
{
|
||||
public ContentItemBinder() : this(Current.Logger, Current.Services, Current.UmbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
public ContentItemBinder(Core.Logging.ILogger logger, ServiceContext services, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
: base(logger, services, umbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ContentItemValidationHelper<IContent, ContentItemSave> GetValidationHelper()
|
||||
{
|
||||
return new ContentValidationHelper();
|
||||
return new ContentValidationHelper(Logger, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
protected override IContent GetExisting(ContentItemSave model)
|
||||
@@ -49,6 +61,10 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
|
||||
internal class ContentValidationHelper : ContentItemValidationHelper<IContent, ContentItemSave>
|
||||
{
|
||||
public ContentValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, umbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the correct information is in the request for saving a culture variant
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Mapping;
|
||||
|
||||
@@ -9,6 +11,15 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
{
|
||||
internal class MediaItemBinder : ContentItemBaseBinder<IMedia, MediaItemSave>
|
||||
{
|
||||
public MediaItemBinder() : this(Current.Logger, Current.Services, Current.UmbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
public MediaItemBinder(Core.Logging.ILogger logger, ServiceContext services, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
: base(logger, services, umbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IMedia GetExisting(MediaItemSave model)
|
||||
{
|
||||
return Services.MediaService.GetById(Convert.ToInt32(model.Id));
|
||||
|
||||
@@ -19,14 +19,25 @@ using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Web.WebApi.Binders
|
||||
{
|
||||
internal class MemberBinder : ContentItemBaseBinder<IMember, MemberSave>
|
||||
{
|
||||
|
||||
public MemberBinder() : this(Current.Logger, Current.Services, Current.UmbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberBinder(ILogger logger, ServiceContext services, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
: base(logger, services, umbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ContentItemValidationHelper<IMember, MemberSave> GetValidationHelper()
|
||||
{
|
||||
return new MemberValidationHelper();
|
||||
return new MemberValidationHelper(Logger, UmbracoContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -179,6 +190,10 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
/// </summary>
|
||||
internal class MemberValidationHelper : ContentItemValidationHelper<IMember, MemberSave>
|
||||
{
|
||||
public MemberValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, umbracoContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We need to manually validate a few things here like email and login to make sure they are valid and aren't duplicates
|
||||
/// </summary>
|
||||
@@ -244,12 +259,9 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
propertiesToValidate.RemoveAll(property => property.Alias == remove);
|
||||
}
|
||||
|
||||
|
||||
var umbCtx = Current.UmbracoContext; // fixme inject?
|
||||
|
||||
//if the user doesn't have access to sensitive values, then we need to validate the incoming properties to check
|
||||
//if a sensitive value is being submitted.
|
||||
if (umbCtx.Security.CurrentUser.HasAccessToSensitiveData() == false)
|
||||
if (UmbracoContextAccessor.UmbracoContext.Security.CurrentUser.HasAccessToSensitiveData() == false)
|
||||
{
|
||||
var sensitiveProperties = postedItem.PersistedContent.ContentType
|
||||
.PropertyTypes.Where(x => postedItem.PersistedContent.ContentType.IsSensitiveProperty(x.Alias))
|
||||
|
||||
@@ -26,6 +26,14 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
where TPersisted : class, IContentBase
|
||||
where TModelSave : ContentBaseItemSave<TPersisted>
|
||||
{
|
||||
protected IUmbracoContextAccessor UmbracoContextAccessor { get; }
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
public ContentItemValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
UmbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the content item and updates the Response and ModelState accordingly
|
||||
@@ -94,7 +102,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
/// <param name="persistedProperties"></param>
|
||||
/// <param name="actionContext"></param>
|
||||
/// <returns></returns>
|
||||
protected bool ValidateProperties(List<ContentPropertyBasic> postedProperties , List<Property> persistedProperties, HttpActionContext actionContext)
|
||||
protected bool ValidateProperties(List<ContentPropertyBasic> postedProperties, List<Property> persistedProperties, HttpActionContext actionContext)
|
||||
{
|
||||
foreach (var p in postedProperties)
|
||||
{
|
||||
@@ -131,7 +139,8 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
if (editor == null)
|
||||
{
|
||||
var message = $"Could not find property editor \"{p.DataType.EditorAlias}\" for property with id {p.Id}.";
|
||||
Current.Logger.Warn<ContentItemValidationHelper<TPersisted, TModelSave>>(message);
|
||||
|
||||
Logger.Warn<ContentItemValidationHelper<TPersisted, TModelSave>>(message);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user