Search code examples
c#asp.net-mvcformsrequest.form

File uploaded through Form with other form values is located in Request.Form.Keys instead of Request.Form.Files


I am trying to take a file input from an HTML form.

@model ViewModel
@using (Html.BeginForm("UploadForm", "Upload", FormMethod.Post, new { enctype = "multipart / form - data" }))
            {
                <div class="row m-3">
                    <div class="col m-3 justify-content-start">
                        <label ID="region" runat="server">Selection:</label>
                        <select class="custom-select form-select" ID="selection" asp-for="@Model!.Selection">
                            <option Text="1" Value="1">1</option>
                            <option Text="2" Value="2">2</option>
                        </select>
                    </div>
                </div>
                <div class="row">
                    <div class="m-3 col-md-auto">
                        <input type="file" name="LoadedFile"/>
                    </div>
                    <div class="m-3 col-md-auto">
                        <input class="btn btn-outline-primary" ID="FileUploadButton" type="submit" name="Upload" value="Upload File" />
                    </div>
                </div>
            }

And read in the loaded file with this try statement within my Controller.

public IActionResult UploadForm(ViewModel model, IFormCollection form)
{
        uView = model;
        try
        {
            Stream? data = null;
            if (Request != null)
            {
                var file = Request.Form.Files["LoadFile"];

                if (file != null)
                {
                    uView!.Filename = file!.FileName;
                    byte[] fileBytes = new byte[file.Length];
                    data = file.OpenReadStream();
                }
            }
            uView!.Workbook = new XLWorkbook(data);
        }
        catch (Exception ex)
        {
            // catch and log error message
        }
}

This is how the Selection value is declare within the ViewModel definition

public class ViewModel
{
    public string Selection { get; set; }
    public string Filename { get; set; }
    public XLWorkbook? Workbook { get; set; }
}

In debugging I can view the DefaultHttpRequest Request.Form item and the file is passed in within the "Keys" field along with the select value and the button name. I have this same setup uplading excel files running elsewhere in my application and it works with this sort of implementation. The difference between them is that this one also includes a select item in the form, which sets the ViewModel's "Selection" attribute.

enter image description here

The other implementation with this sort of excel file upload does not make any updates to it's ViewModel once the file has been passed through the form into the controller.

I've tried access the file through var file = Request.Form.Keys["LoadFile"]; but this throws an error as you can not access the Keys values this way.


Solution

  • Your <input> tag has LoadedFile name. Therefore, you should use it when referencing to the Files collection:

    var file = Request.Form.Files["LoadedFile"];
    

    And the space characters should be removed from the enctype attribute: "multipart/form-data".