Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Derek 4 posts 95 karma points
    Aug 19, 2023 @ 15:00
    Derek
    0

    Large file upload ends in System.IO.IOException: Unexpected end of Stream (Umbraco 11.4.2)

    Hello together,

    I am trying to implement the uploading of large files for the frontend user in my Umbraco 11 site. Unfortunately, this ends in an exception: System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component.

    In a simple MVC .net core application my code works, but with Umbraco 11 I can't get it to work. What am I missing here so that the stream is not preloaded?

    [DisableFormValueModelBinding] doesn't seem to work, but the code there is executed.

    Here is my code (I left out everything irrelevant, like error handling etc.)

    The form element used to upload the file(s)

    <form id="uploadForm"
      action="/fileupload/UploadToFilesystem"
      method="POST"
      enctype="multipart/form-data"
      >
    <dl>
        <dt>
            <label for="file">Files to upload</label>
        </dt>
        <dd>
            <input data-id="file" type="file" name="file" />
        </dd>
    </dl>
    
    <input class="btn" type="submit" value="upload" />
    
    <div>
        <output form="uploadForm" name="result"></output>
    </div></form>
    

    My controller:

    public class FileUploadController : ControllerBase // Controller  - have tried both
    {
        [HttpPost]
        [MultipartFormData]
        [DisableFormValueModelBinding]
        public async Task<IActionResult> UploadToFilesystem()
        {
            string strTargetFilePath = Path.Combine(objFiles.dgGetRootPath(), dgFilesConfig.cstrDataFilesTmp);
            // is something like D:\...\umbracosite\data\tmp at the moment
    
        boundary = HeaderUtilities.RemoveQuotes(Request.ContentType).Value;
    
        var reader = new MultipartReader(boundary, HttpContext.Request.Body);
        var section = await reader.ReadNextSectionAsync();
        // this is the point where the server error 500 occurs
        // System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component.
    
        // the rest of the code comes here, but it doesn't matter for now.
    

    Herewith I try to prevent model binding (checked during debugging, the code is executed):

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            var factories = context.ValueProviderFactories;
    
            var formValueProviderFactory = context.ValueProviderFactories.OfType<FormValueProviderFactory>().FirstOrDefault();
            if (formValueProviderFactory != null)
            {
                factories.RemoveType<FormValueProviderFactory>();
                //checked during debugging, the code is executed
            }
    
            var formFileValueProviderFactory = context.ValueProviderFactories.OfType<FormFileValueProviderFactory>().FirstOrDefault();
            if (formFileValueProviderFactory != null)
            {
                factories.RemoveType<FormFileValueProviderFactory>();
                //checked during debugging, the code is executed
            }
    
            var jQueryformValueProviderFactory = context.ValueProviderFactories.OfType<JQueryFormValueProviderFactory>().FirstOrDefault();
            if (jQueryformValueProviderFactory != null)
            {
                factories.RemoveType<JQueryFormValueProviderFactory>();
                //checked during debugging, the code is executed
            }
        }
    
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
        }
    }
    

    In startup.cs i have adapted the Configure function for routing to my controller.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
        app.UseDeveloperExceptionPage();
        }
    
        app.UseHttpsRedirection();
    
        app.UseUmbraco()
            .WithMiddleware(u =>
            {
            u.UseBackOffice();
            u.UseWebsite();
            })
            .WithEndpoints(u =>
            {
                // my routing start
                u.EndpointRouteBuilder.MapControllerRoute(
                    "FileUpload",
                    "/fileupload/{action}",
                    new { Controller = "FileUpload", Action = "UploadToFilesystem" });
                // my routing end
    
    
                u.UseInstallerEndpoints();
                u.UseBackOfficeEndpoints();
                u.UseWebsiteEndpoints();
            });
    }
    

    does anyone have a tip for me?

    Thanks Derek

  • Derek 4 posts 95 karma points
    Aug 20, 2023 @ 07:11
    Derek
    100

    Hi,

    i'll answer myself. in appsettings.json I added an exception under ReservedPaths.

      "Umbraco": {
        "CMS": {
          "Global": {
            "ReservedUrls": "~/.well-known",
            "ReservedPaths": "~/fileupload",
            ...
      }
    

    Derek

Please Sign in or register to post replies

Write your reply to:

Draft