Closed
Description
Which Umbraco version are you using? (Please write the exact version, example: 10.1.0)
15.1.1
Bug summary
The Media Delivery API will not deliver your media item, if the media item is stored in a folder in your backoffice structure, and if you request it using the /umbraco/delivery/api/v2/media/item/{id}
-endpoint.
If you query your media item using it's ID and it's placed in a folder, one of two things will happen:
- The request will continue to run until you eventually run out of memory and get a
System.OutOfMemoryException
simmilar to the one highlighted below - The request will timeout depended on your hosting
Specifics
This happens specifically for the /umbraco/delivery/api/v2/media/item/{id}
-endpoint.
The System.OutOfMemoryException
:
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at Umbraco.Cms.Infrastructure.HybridCache.PublishedContent..ctor(ContentNode contentNode, Boolean preview, IElementsCache elementsCache, IVariationContextAccessor variationContextAccessor)
at Umbraco.Cms.Infrastructure.HybridCache.Services.MediaCacheService.GetNodeAsync(Guid key)
at Umbraco.Cms.Infrastructure.HybridCache.Services.MediaCacheService.GetByKeyAsync(Guid key)
at Umbraco.Cms.Infrastructure.HybridCache.MediaCache.GetByIdAsync(Guid key)
at Umbraco.Cms.Infrastructure.DeliveryApi.ApiMediaWithCropsResponseBuilder.GetParent(IPublishedContent media)
at Umbraco.Cms.Infrastructure.DeliveryApi.ApiMediaWithCropsResponseBuilder.PathSegments(IPublishedContent media)+MoveNext()
at System.Linq.Enumerable.<ToArray>g__EnumerableToArray|314_0[TSource](IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at System.Linq.Enumerable.ReverseIterator`1.MoveNext()
at System.String.Join(String separator, IEnumerable`1 values)
at Umbraco.Cms.Infrastructure.DeliveryApi.ApiMediaWithCropsResponseBuilder.Create(IPublishedContent media, IApiMedia inner, ImageFocalPoint focalPoint, IEnumerable`1 crops)
at Umbraco.Cms.Infrastructure.DeliveryApi.ApiMediaWithCropsBuilderBase`1.Build(MediaWithCrops media)
at Umbraco.Cms.Infrastructure.DeliveryApi.ApiMediaWithCropsBuilderBase`1.Build(IPublishedContent media)
at Umbraco.Cms.Api.Delivery.Controllers.Media.MediaApiControllerBase.BuildApiMediaWithCrops(IPublishedContent media)
at Umbraco.Cms.Api.Delivery.Controllers.Media.ByIdMediaApiController.HandleRequest(Guid id)
at Umbraco.Cms.Api.Delivery.Controllers.Media.ByIdMediaApiController.ByIdV20(Guid id)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Umbraco.Cms.Web.Common.Middleware.BasicAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Api.Management.Middleware.BackOfficeExternalLoginProviderErrorMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cloud.Cms.PublicAccess.Middleware.CloudPublicAccessMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Deploy.Infrastructure.Middleware.BearerTokenAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in C:\projects\dotnet\src\MiniProfiler.AspNetCore\MiniProfilerMiddleware.cs:line 112
at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Web.Common.Middleware.PreviewAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestLoggingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at SixLabors.ImageSharp.Web.Middleware.ImageSharpMiddleware.Invoke(HttpContext httpContext, Boolean retry)
at Umbraco.Forms.Web.HttpModules.ProtectFormUploadRequestsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Api.Management.Middleware.BackOfficeAuthorizationInitializationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
Steps to reproduce
- Set up a new Umbraco 15.1.1 project
- Enable Content and Media Delivery APIs
- Create a folder in the media section
- Upload an image to the folder and grab the idea
- Use Swagger UI or Postman to send a GET request to the
/umbraco/delivery/api/v2/media/item/{id}
-endpoint with the ID of your uploaded item. - You will see that it will keep on loading, until eventually running out of memory or simply timing out.
Expected result / actual result
The Media Delivery API should deliver the media item as it does when it's not placed in a folder.
This item has been added to our backlog AB#47486