From 70f65583d79f595f423275e1ed43f66eba4937f3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 9 May 2014 15:50:07 +1000 Subject: [PATCH] Fixes: U4-4546 Error: Failed to retreive data for media ids --- .../EntityControllerConfigurationAttribute.cs | 7 +-- src/Umbraco.Web/Editors/MemberController.cs | 13 +--- src/Umbraco.Web/Umbraco.Web.csproj | 1 + .../WebApi/AngularJsonMediaTypeFormatter.cs | 40 +------------ .../OutgoingDateTimeFormatAttribute.cs | 28 ++++----- .../OutgoingNoHyphenGuidFormatAttribute.cs | 24 ++++++++ .../WebApi/HttpControllerContextExtensions.cs | 59 ++----------------- 7 files changed, 50 insertions(+), 122 deletions(-) create mode 100644 src/Umbraco.Web/WebApi/Filters/OutgoingNoHyphenGuidFormatAttribute.cs diff --git a/src/Umbraco.Web/Editors/EntityControllerConfigurationAttribute.cs b/src/Umbraco.Web/Editors/EntityControllerConfigurationAttribute.cs index 3f6fcc5c2c..7ef4ef206a 100644 --- a/src/Umbraco.Web/Editors/EntityControllerConfigurationAttribute.cs +++ b/src/Umbraco.Web/Editors/EntityControllerConfigurationAttribute.cs @@ -1,3 +1,4 @@ +using System; using System.Web.Http.Controllers; using Umbraco.Web.WebApi; @@ -10,12 +11,10 @@ namespace Umbraco.Web.Editors /// NOTE: It is SOOOO important to remember that you cannot just assign this in the 'initialize' method of a webapi /// controller as it will assign it GLOBALLY which is what you def do not want to do. /// - internal class EntityControllerConfigurationAttribute : AngularJsonOnlyConfigurationAttribute, IControllerConfiguration + internal class EntityControllerConfigurationAttribute : Attribute, IControllerConfiguration { - public override void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) + public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) { - base.Initialize(controllerSettings, controllerDescriptor); - controllerSettings.Services.Replace(typeof(IHttpActionSelector), new EntityControllerActionSelector()); } } diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index 383f78d28e..1c9486c67d 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -37,6 +37,7 @@ namespace Umbraco.Web.Editors /// [PluginController("UmbracoApi")] [UmbracoApplicationAuthorizeAttribute(Constants.Applications.Members)] + [OutgoingNoHyphenGuidFormat] public class MemberController : ContentControllerBase { /// @@ -58,17 +59,7 @@ namespace Umbraco.Web.Editors _provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); } - private MembershipProvider _provider; - - /// - /// Ensure all GUIDs are formatted without hyphens - /// - /// - protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext) - { - base.Initialize(controllerContext); - controllerContext.SetOutgoingNoHyphenGuidFormat(); - } + private readonly MembershipProvider _provider; /// /// Returns the currently configured membership scenario for members in umbraco diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index c17b9f1c56..03f5c397c9 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -510,6 +510,7 @@ + diff --git a/src/Umbraco.Web/WebApi/AngularJsonMediaTypeFormatter.cs b/src/Umbraco.Web/WebApi/AngularJsonMediaTypeFormatter.cs index 4f16c32c33..66a79376aa 100644 --- a/src/Umbraco.Web/WebApi/AngularJsonMediaTypeFormatter.cs +++ b/src/Umbraco.Web/WebApi/AngularJsonMediaTypeFormatter.cs @@ -36,54 +36,18 @@ namespace Umbraco.Web.WebApi if (type == null) throw new ArgumentNullException("type"); if (writeStream == null) throw new ArgumentNullException("writeStream"); - //Before we were calling the base method to do this however it was causing problems: - // http://issues.umbraco.org/issue/U4-4546 - // though I can't seem to figure out why the null ref exception was being thrown, it is very strange. - var effectiveEncoding = SelectCharacterEncoding(content == null ? null : content.Headers); - using (var streamWriter = new StreamWriter(writeStream, effectiveEncoding)) + using (var streamWriter = new StreamWriter(writeStream, effectiveEncoding)) { //write the special encoding for angular json to the start // (see: http://docs.angularjs.org/api/ng.$http) streamWriter.Write(")]}',\n"); streamWriter.Flush(); - return base.WriteToStreamAsync(type, value, writeStream, content, transportContext); } - //This is what the base method is doing for json, EXCEPT they have a handy TaskHelpers.RunSynchronously method - // that ensures that the code doesn't run async which avoids all sorts of thread sync issues like http context - // cultures, etc... but that is not public so we cannot use it. Instead I've modified our original version to be - // much simpler and we no longer create a separate memory stream so hopefully this solves the issue above, if it doesn't - // then we're kind of back to the drawing board. - - //var task = Task.Factory.StartNew(() => - //{ - // var effectiveEncoding = SelectCharacterEncoding(content == null ? null : content.Headers); - - // using (var streamWriter = new StreamWriter(writeStream, effectiveEncoding)) - // using (var jsonTextWriter = new JsonTextWriter(streamWriter) - // { - // CloseOutput = false - // }) - // { - // //write the special encoding for angular json to the start - // // (see: http://docs.angularjs.org/api/ng.$http) - // streamWriter.Write(")]}',\n"); - - // if (Indent) - // { - // jsonTextWriter.Formatting = Formatting.Indented; - // } - // var jsonSerializer = JsonSerializer.Create(SerializerSettings); - // jsonSerializer.Serialize(jsonTextWriter, value); - - // jsonTextWriter.Flush(); - // } - //}); - //return task; - + } } diff --git a/src/Umbraco.Web/WebApi/Filters/OutgoingDateTimeFormatAttribute.cs b/src/Umbraco.Web/WebApi/Filters/OutgoingDateTimeFormatAttribute.cs index a2f3373999..d8e185963a 100644 --- a/src/Umbraco.Web/WebApi/Filters/OutgoingDateTimeFormatAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/OutgoingDateTimeFormatAttribute.cs @@ -1,4 +1,8 @@ -using System.Web.Http.Filters; +using System; +using System.Linq; +using System.Net.Http.Formatting; +using System.Web.Http.Controllers; +using System.Web.Http.Filters; using Umbraco.Core; namespace Umbraco.Web.WebApi.Filters @@ -6,9 +10,9 @@ namespace Umbraco.Web.WebApi.Filters /// /// Sets the json outgoing/serialized datetime format /// - internal sealed class OutgoingDateTimeFormatAttribute : ActionFilterAttribute + internal sealed class OutgoingDateTimeFormatAttribute : Attribute, IControllerConfiguration { - private readonly string _format; + private readonly string _format = "yyyy-MM-dd HH:mm:ss"; /// /// Specify a custom format @@ -23,24 +27,18 @@ namespace Umbraco.Web.WebApi.Filters /// /// Will use the standard ISO format /// - public OutgoingDateTimeFormatAttribute() - { + public OutgoingDateTimeFormatAttribute(){ } - public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) + public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) { - base.OnActionExecuting(actionContext); - - if (_format.IsNullOrWhiteSpace()) + var jsonFormatter = controllerSettings.Formatters.OfType(); + foreach (var r in jsonFormatter) { - actionContext.ControllerContext.SetOutgoingDateTimeFormat(); + r.SerializerSettings.Converters.Add(new CustomDateTimeConvertor(_format)); } - else - { - actionContext.ControllerContext.SetOutgoingDateTimeFormat(_format); - } - } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/WebApi/Filters/OutgoingNoHyphenGuidFormatAttribute.cs b/src/Umbraco.Web/WebApi/Filters/OutgoingNoHyphenGuidFormatAttribute.cs new file mode 100644 index 0000000000..897213a142 --- /dev/null +++ b/src/Umbraco.Web/WebApi/Filters/OutgoingNoHyphenGuidFormatAttribute.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; +using System.Net.Http.Formatting; +using System.Web.Http.Controllers; + +namespace Umbraco.Web.WebApi.Filters +{ + internal sealed class OutgoingNoHyphenGuidFormatAttribute : Attribute, IControllerConfiguration + { + public OutgoingNoHyphenGuidFormatAttribute() + { + } + + public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) + { + var jsonFormatter = controllerSettings.Formatters.OfType(); + foreach (var r in jsonFormatter) + { + r.SerializerSettings.Converters.Add(new GuidNoHyphenConverter()); + } + } + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs b/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs index 8cd3384915..a3cb3b9d22 100644 --- a/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs +++ b/src/Umbraco.Web/WebApi/HttpControllerContextExtensions.cs @@ -55,61 +55,12 @@ namespace Umbraco.Web.WebApi /// private static async Task FilterContinuation(HttpActionContext actionContext, CancellationToken token, IList filters, int index) { - return await filters[index].ExecuteAuthorizationFilterAsync(actionContext, token, () => - { - Func nullResponse = () => null; - return (index + 1) == filters.Count - ? Task.Run(nullResponse, token) - : FilterContinuation(actionContext, token, filters, ++index); - }); + return await filters[index].ExecuteAuthorizationFilterAsync(actionContext, token, + () => (index + 1) == filters.Count + ? Task.FromResult(null) + : FilterContinuation(actionContext, token, filters, ++index)); } + - /// - /// Sets the JSON GUID format to not have hyphens - /// - /// - internal static void SetOutgoingNoHyphenGuidFormat(this HttpControllerContext controllerContext) - { - var jsonFormatter = controllerContext.Configuration.Formatters.JsonFormatter; - jsonFormatter.SerializerSettings.Converters.Add(new GuidNoHyphenConverter()); - } - - - /// - /// Sets the JSON datetime format to be a custom one - /// - /// - /// - internal static void SetOutgoingDateTimeFormat(this HttpControllerContext controllerContext, string format) - { - var jsonFormatter = controllerContext.Configuration.Formatters.JsonFormatter; - jsonFormatter.SerializerSettings.Converters.Add(new CustomDateTimeConvertor(format)); - } - - /// - /// Sets the JSON datetime format to be our regular iso standard - /// - internal static void SetOutgoingDateTimeFormat(this HttpControllerContext controllerContext) - { - var jsonFormatter = controllerContext.Configuration.Formatters.JsonFormatter; - jsonFormatter.SerializerSettings.Converters.Add(new CustomDateTimeConvertor("yyyy-MM-dd HH:mm:ss")); - } - - ///// - ///// Removes the xml formatter so it only outputs angularized json (with the json vulnerability prefix added) - ///// - ///// - //internal static void EnsureJsonOutputOnly(this HttpControllerContext controllerContext) - //{ - // controllerContext.Configuration.Formatters = new MediaTypeFormatterCollection(); - - // //remove all json/xml formatters then add our custom one - // var toRemove = controllerContext.Configuration.Formatters.Where(t => (t is JsonMediaTypeFormatter) || (t is XmlMediaTypeFormatter)).ToList(); - // foreach (var r in toRemove) - // { - // controllerContext.Configuration.Formatters.Remove(r); - // } - // controllerContext.Configuration.Formatters.Add(new AngularJsonMediaTypeFormatter()); - //} } } \ No newline at end of file