ASP.NET Core .NET 8 receives null form values from certain iPhone 13 Pro Max devices

Ibrahim Akuetiemhe 0 Reputation points
2026-10-29T09:15:57.76+00:00

I am troubleshooting a device-specific issue with multipart form data submission in my ASP.NET Core .NET 8 application.

Application details

The frontend uses vanilla JavaScript fetch with the FormData API to submit customer information and uploaded files. The backend is a C# ASP.NET Core controller action that accepts the request using FromForm model binding.

Problem

Two iPhone 13 Pro Max devices running iOS 27 fail to submit the form correctly. The browser-side diagnostic confirms that the form data contains the expected values before submission, but the backend receives null values.

The issue is inconsistent across devices. One of the two iPhone 13 Pro Max devices works against my local development server, while the other fails. some iPhone including XR and a substantial number of Android devices have submitted successfully in my testing.

I have tested both Safari and Chrome on the affected iPhone, with the same result.

Troubleshooting performed

Changed hosting from SmarterASP to AWS EC2. The issue persisted.

Changed the local development server from Kestrel to IIS Express. The issue persisted.

Tested the application locally and on the hosted environments.

Verified that the expected data exists in the browser before the request is submitted.

Technical environment

Backend: ASP.NET Core .NET 8 Frontend: Vanilla JavaScript fetch and FormData Request format: multipart/form-data Model binding: C# FromForm Affected devices: Two iPhone 13 Pro Max devices running iOS 27 Successful devices: iPhone XR and numerous Android devices

Question

What could cause multipart form data submitted from specific iPhone devices to arrive with null values in an ASP.NET Core .NET 8 controller when other iPhones and Android devices work correctly?

What diagnostics would help determine whether the problem is caused by the request generated by the browser, multipart encoding or transmission, or ASP.NET Core model binding?

I can provide the JavaScript submission code, DTO, controller action, and further diagnostic logs if needed.

Developer technologies | ASP.NET Core | Other
0 comments No comments

6 answers

Sort by: Most helpful
  1. Ibrahim Akuetiemhe 0 Reputation points
    2026-10-30T09:30:19.2066667+00:00

    These are my code samples

    **Controller
    ** public async Task<IActionResult> Get([FromForm] BuyInsuranceDTO b)

    {
    
        //if (!User.HasClaim("Permission", Permissions.PurchasePolicy))
    
        //{
    
        //    return StatusCode(403, new
    
        //    {
    
        //        success = false,
    
        //        message = "Sorry, you cant purchase policy at the moment."
    
        //    });
    
        //}
    
    
    
        var loggedInCustomer = Convert.ToInt16(User.FindFirst(ClaimTypes.NameIdentifier)?.Value);
    
        var upload = Request.Form.Files.Where(x => x.Name == "Identification").FirstOrDefault();
    
        var createPolicy = await service.CreateService(b, upload, loggedInCustomer, User.Identity.IsAuthenticated);
    
        if (!createPolicy.Success)
    
        {
    
            return Json(new MyResponse { Success = false, Message = createPolicy.Message });
    
        }
    
        return Json(new MyResponse { Success = true, Message = createPolicy.Message });
    
    }**  
    ```DTO  
    **    public class BuyInsuranceDTO
    
    ```powershell
    {
    
        // ================= BASIC =================
    
        [Required]
    
        public string FirstName { get; set; }
    
        [Required]
    
        public string LastName { get; set; }
    
        public string MiddleName { get; set; }
    
        [Required]
    
        [Range(1, 2)]
    
        public int Sex { get; set; }
    
        [Required]
    
        public DateTime DOB { get; set; }
    
        [Required]
    
        public string PhoneNumber { get; set; }
    
        [Required]
    
        public string Address { get; set; }
    
        public string EmailAddress { get; set; }
    
        public string Agent { get; set; }
    
        // ================= NEXT OF KIN =================
    
        [Required]
    
        public string NOKFullName { get; set; }
    
        public int NOKRelationship { get; set; }
    
        [Required]
    
        public string NOKPhoneNumber { get; set; }
    
        [Required]
    
        public string NOKAddress { get; set; }
    
        // ================= POLICY =================
    
        public Guid? PolicyID { get; set; }
    
        [Required]
    
        public List<CoverItemDTO> Covers { get; set; }
    
        // ================= IDENTIFICATION =================
    
        [Required]
    
        public int IdentificationTypeId { get; set; }
    
        [Required]
    
        public string IdentificationNumber { get; set; }
    
        public DateTime? ExpiryDate { get; set; }
    
        public IFormFile Identification { get; set; }
    
        // ================= BUSSINESS ADDRESS =================
    
        public string StreetNumber { get; set; }
    
        [Required]
    
        public string StreetName { get; set; }
    
        public string LandMark { get; set; }
    
        [Required]
    
        public int StateID { get; set; }
    
        [Required]
    
        public int LGAID { get; set; }
    
        [Required]
    
        public int AccountID { get; set; }
    
        // ================= COVER UPLOADS =================
    
        public List<CoverFileUploadDTO> CoverFiles { get; set; }
    
        //============ Declared Items=================
    
        public List<DeclarationItemsDTO> DeclarationItems { get; set; }
    
    }
    ```**Java Script  
    **async function handleFinalSubmission() {
    
    ```javascript
    if (!confirm('Are you sure you want to submit this policy application?')) {
    
        return;
    
    }
    
    const formData = buildPolicyFormData();
    
    const result = await sendPolicy(formData);
    
    if (!result) {
    
        return;
    
    }
    
    alert(result.message);
    
    if (result.success) {
    
        window.location.href =
    
            '/policylisting/insuranceproduct';
    
    }
    ```}
    
    async function sendPolicy(formData) {
    
    ```typescript
    if (isSubmitting) return;
    
    isSubmitting = true;
    
    showLoader();
    
    try {
    
        const res = await fetch(`/policyListing/get`, {
    
            method: 'POST',
    
            body: formData
    
        });
    
        const data = await res.json();
    
        return data;
    
    } catch (err) {
    
        console.error(err);
    
        alert("Failed to submit policy");
    
        return null;
    
    } finally {
    
        isSubmitting = false;
    
        hideLoader();
    
    }
    ```}
    
      
    function appendIfExists(formData, key, elementId) {
    
    ```sql
    const el = document.getElementById(elementId);
    
    if (el)
    
        formData.append(key, el.value.trim());
    ```}
    
    function buildPolicyFormData() {
    
    ```javascript
    const formData = new FormData();
    
    appendIfExists(formData, "FirstName", "firstName");
    
    appendIfExists(formData, "MiddleName", "middleName");
    
    appendIfExists(formData, "LastName", "lastName");
    
    appendIfExists(formData, "PhoneNumber", "phone");
    
    appendIfExists(formData, "Sex", "sex");
    
    appendIfExists(formData, "DOB", "dob");
    
    appendIfExists(formData, "Agent", "agent");
    
    appendIfExists(formData, "Address", "address");
    
    appendIfExists(formData, "EmailAddress", "email");
    
    appendIfExists(formData, "NOKFullName", "nokName");
    
    appendIfExists(formData, "NOKRelationship", "nokRelationship");
    
    appendIfExists(formData, "NOKPhoneNumber", "nokPhone");
    
    appendIfExists(formData, "NOKAddress", "nokAddress");
    
    appendIfExists(formData, "IdentificationTypeId", "idType");
    
    appendIfExists(formData, "IdentificationNumber", "idNumber");
    
    appendIfExists(formData, "ExpiryDate", "expiryDate");
    
    appendIfExists(formData, "StateID", "businessState");
    
    appendIfExists(formData, "LGAID", "businessLga");
    
    appendIfExists(formData, "StreetNumber", "businessStreetNumber");
    
    appendIfExists(formData, "StreetName", "businessAddress");
    
    appendIfExists(formData, "LandMark", "businessLandmark");
    
    const idFile = document.getElementById('idUpload')?.files[0];
    
    if (idFile) formData.append("Identification", idFile);
    
    if (policyId) {
    
        formData.append("PolicyID", policyId);
    
    }
    
    // Covers
    
    if (isCustomPolicy && selectedCovers.length > 0) {
    
        selectedCovers.forEach((cover, i) => {
    
            formData.append(`Covers[${i}].CoverID`, cover.CoverID);
    
            formData.append(`Covers[${i}].RiskCovered`, coverRisks[cover.CoverID] || 0);
    
        });
    
    } else if (selectedCoverIds.length > 0) {
    
        selectedCoverIds.forEach((id, i) => {
    
            formData.append(`Covers[${i}].CoverID`, id);
    
        });
    
    }
    
    // Dynamic Cover Files
    
    let fileIndex = 0;
    
    let itemIndex = 0;
    
    document.querySelectorAll('.cover-upload').forEach(input => {
    
        const file = input.files[0];
    
        if (file) {
    
            formData.append(`CoverFiles[${fileIndex}].File`, file);
    
            formData.append(`CoverFiles[${fileIndex}].CoverId`, input.dataset.coverid);
    
            formData.append(`CoverFiles[${fileIndex}].Label`, input.dataset.label);
    
            formData.append(`CoverFiles[${fileIndex}].coverUploadRequirementID`, input.name);
    
            fileIndex++;
    
        }
    
    });
    
    // Declaration Items
    
    document.querySelectorAll("#tblDeclarationItems tbody tr").forEach(row => {
    
        const itemName = row.querySelector(".item-name")?.value.trim();
    
        const amount = row.querySelector(".item-amount")?.value;
    
        // Ignore empty rows
    
        if (!itemName || !amount)
    
            return;
    
        formData.append(`DeclarationItems[${itemIndex}].ItemName`, itemName);
    
        formData.append(`DeclarationItems[${itemIndex}].Amount`, amount);
    
        itemIndex++;
    
    });
    
    return formData;
    ```}
    

    Was this answer helpful?

    1 person found this answer helpful.

  2. Ibrahim Akuetiemhe 0 Reputation points
    2026-10-29T12:14:16.7433333+00:00

    This is from a working device
    {

    "contentType": "multipart/form-data; boundary=----WebKitFormBoundaryPgoBscBBF4qYl6KM",
    
    "contentLength": 111491,
    
    "fields": {
    
        "FirstName": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "MiddleName": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "LastName": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "PhoneNumber": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "Sex": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "DOB": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "Agent": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "Address": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "EmailAddress": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "NOKFullName": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "NOKRelationship": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "NOKPhoneNumber": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "NOKAddress": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "IdentificationTypeId": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "IdentificationNumber": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "ExpiryDate": {
    
            "count": 1,
    
            "hasValue": false
    
        },
    
        "StateID": {
    
            "count": 1,
    
            "hasValue": false
    
        },
    
        "LGAID": {
    
            "count": 1,
    
            "hasValue": false
    
        },
    
        "StreetNumber": {
    
            "count": 1,
    
            "hasValue": false
    
        },
    
        "StreetName": {
    
            "count": 1,
    
            "hasValue": false
    
        },
    
        "LandMark": {
    
            "count": 1,
    
            "hasValue": false
    
        },
    
        "PolicyID": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "Covers[0].CoverID": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "CoverFiles[0].CoverId": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "CoverFiles[0].Label": {
    
            "count": 1,
    
            "hasValue": true
    
        },
    
        "CoverFiles[0].coverUploadRequirementID": {
    
            "count": 1,
    
            "hasValue": true
    
        }
    
    },
    
    "files": [
    
        {
    
            "name": "Identification",
    
            "fileName": "NIA.png",
    
            "contentType": "image/png",
    
            "length": 54168
    
        },
    
        {
    
            "name": "CoverFiles[0].File",
    
            "fileName": "NIA.png",
    
            "contentType": "image/png",
    
            "length": 54168
    
        }
    
    ],
    
    "totalFields": 26,
    
    "totalFiles": 2
    

    }

    And this is from the iPhone
    {

    "contentType": "multipart/form-data; boundary=----WebKitFormBoundaryqXbmvYh367BCwgcB",

    "contentLength": 0,

    "fields": 0,

    "files": 0,

    "totalFields": 0,

    "totalFiles": 0

    }

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments

  3. Nguyen Dam (WICLOUD CORPORATION) 1,010 Reputation points Microsoft External Staff Moderator
    2026-10-29T10:57:40.5366667+00:00

    Hello @Ibrahim Akuetiemhe and thank you for reaching out.

    The behavior differs even between similar iPhone devices so I would suggest first determining whether the form values are already missing when ASP.NET Core parses the request, or whether they are present and only become null during model binding.

    You can temporarily bypass the DTO with a diagnostic endpoint, for example:

    [HttpPost("diagnose-upload")]
    public async Task<IActionResult> DiagnoseUpload()
    {
        var request = Request;
    
        if (!request.HasFormContentType)
        {
            return BadRequest(new
            {
                request.ContentType,
                request.ContentLength
            });
        }
    
        var form = await request.ReadFormAsync();
    
        return Ok(new
        {
            request.ContentType,
            request.ContentLength,
            FormValues = form.ToDictionary(
                item => item.Key,
                item => item.Value.ToArray()),
            Files = form.Files.Select(file => new
            {
                file.Name,
                file.FileName,
                file.ContentType,
                file.Length
            })
        });
    }
    

    Compare the result from a working device with the affected iPhone

    • Values are missing/incorrect in Request.Form -> the issue is before model binding. Compare the requests from both devices, including the form data, Content-Type, multipart boundary, files, and payload.
    • Values are correct in Request.Form but null in [FromForm] -> the issue is likely with model binding or the DTO. Check ModelState for binding errors.

    If possible, please provide the JavaScript submission code, DTO, controller action, and the diagnostic results from both a working and affected device. These should help identify where the values are being lost.

    Hopefully, this should help narrow down the root cause. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation. Thank you.

    Was this answer helpful?

    1 person found this answer helpful.

  4. Paul Thomas 80 Reputation points
    2026-10-29T12:25:24.5166667+00:00

    One likely cause that fits "only some iPhones" is the request body size limit. By default, ASP.NET Core rejects request bodies larger than 30,000,000 bytes (about 28.6 MB), and IIS and IIS Express have the same default limit. Photos from newer iPhones can push a multipart request over that, especially ProRAW images or several photos in one form, so one iPhone 13 Pro Max can work while another, with different photos or camera settings, fails.

    What makes this confusing is that, on a controller without [ApiController], a body that's too large doesn't produce an obvious error: the form can't be read, so the [FromForm] model comes through as null.

    What I tested (.NET 9, Kestrel, same defaults as .NET 8)

    I posted a multipart form with two text fields and one file to a [FromForm] DTO:

    RequestController without [ApiController]Controller with [ApiController]5 MB fileAll values arriveAll values arrive5 MB fileAll values arriveAll values arrive35 MB fileThe whole [FromForm] model is null400: "Failed to read the request form. Request body too large. The max request body size is 30000000 bytes."1. Check whether this is your problem

    In the JavaScript, log the size of what you're sending, just before fetch, on a failing and a working device:

    const totalBytes = [...formData.values()]
        .reduce((sum, value) => sum + (value instanceof File ? value.size : 0), 0);
    console.log(`Upload size: ${(totalBytes / 1_000_000).toFixed(1)} MB`);
    

    On the server, stop the failure from being silent. Check the model and ModelState at the start of the action, and the error message tells you directly:

    if (form is null || !ModelState.IsValid)
    {
        var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage);
        return BadRequest(errors); // e.g. "Request body too large. The max request body size is 30000000 bytes."
    }
    

    2. If that's it, raise the limit for this action

    [HttpPost]
    [RequestSizeLimit(100_000_000)] // 100 MB for this action only
    public IActionResult Submit([FromForm] CustomerForm form) { ... }
    
    

    In my test, the 35 MB request bound correctly with this attribute. If a single upload can exceed 128 MB, also add [RequestFormLimits(MultipartBodyLengthLimit = ...)].

    When the app is hosted in IIS (which SmarterASP uses) or run under IIS Express, IIS request filtering has its own limit, so raise it in web.config as well:

    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="104857600" />
        </requestFiltering>
      </security>
    </system.webServer>
    

    Pick the smallest limit that covers your real uploads. Resizing or compressing photos in the browser before upload is often a better fix than accepting very large requests.

    If the logged sizes on the failing iPhones are well under 28 MB, it's something else, and Nguyen's diagnostic endpoint, comparing Request.Form on both devices, is the right next step.

    Let me know what sizes you see. If this solves it, please consider marking it as the accepted answer so others with the same problem can find it.

    Was this answer helpful?


  5. Ibrahim Akuetiemhe 0 Reputation points
    2026-10-29T12:17:50.69+00:00

    These are my code samples

    **Controller
    ** public async Task<IActionResult> Get([FromForm] BuyInsuranceDTO b)

    {
    
        //if (!User.HasClaim("Permission", Permissions.PurchasePolicy))
    
        //{
    
        //    return StatusCode(403, new
    
        //    {
    
        //        success = false,
    
        //        message = "Sorry, you cant purchase policy at the moment."
    
        //    });
    
        //}
    
    
    
        var loggedInCustomer = Convert.ToInt16(User.FindFirst(ClaimTypes.NameIdentifier)?.Value);
    
        var upload = Request.Form.Files.Where(x => x.Name == "Identification").FirstOrDefault();
    
        var createPolicy = await service.CreateService(b, upload, loggedInCustomer, User.Identity.IsAuthenticated);
    
        if (!createPolicy.Success)
    
        {
    
            return Json(new MyResponse { Success = false, Message = createPolicy.Message });
    
        }
    
        return Json(new MyResponse { Success = true, Message = createPolicy.Message });
    
    }**  
    

    DTO
    public class BuyInsuranceDTO**

    **{**
    
        **// ================= BASIC =================**
    
        **[Required]**
    
        **public string FirstName { get; set; }**
    
        **[Required]**
    
        **public string LastName { get; set; }**
    
        **public string MiddleName { get; set; }**
    
        **[Required]**
    
        **[Range(1, 2)]**
    
        **public int Sex { get; set; }**
    
        **[Required]**
    
        **public DateTime DOB { get; set; }**
    
        **[Required]**
    
        **public string PhoneNumber { get; set; }**
    
        **[Required]**
    
        **public string Address { get; set; }**
    
        **public string EmailAddress { get; set; }**
    
        **public string Agent { get; set; }**
    
        **// ================= NEXT OF KIN =================**
    
        **[Required]**
    
        **public string NOKFullName { get; set; }**
    
        **public int NOKRelationship { get; set; }**
    
        **[Required]**
    
        **public string NOKPhoneNumber { get; set; }**
    
        **[Required]**
    
        **public string NOKAddress { get; set; }**
    
        **// ================= POLICY =================**
    
        **public Guid? PolicyID { get; set; }**
    
        **[Required]**
    
        **public List<CoverItemDTO> Covers { get; set; }**
    
        **// ================= IDENTIFICATION =================**
    
        **[Required]**
    
        **public int IdentificationTypeId { get; set; }**
    
        **[Required]**
    
        **public string IdentificationNumber { get; set; }**
    
        **public DateTime? ExpiryDate { get; set; }**
    
        **public IFormFile Identification { get; set; }**
    
        **// ================= BUSSINESS ADDRESS =================**
    
        **public string StreetNumber { get; set; }**
    
        **[Required]**
    
        **public string StreetName { get; set; }**
    
        **public string LandMark { get; set; }**
    
        **[Required]**
    
        **public int StateID { get; set; }**
    
        **[Required]**
    
        **public int LGAID { get; set; }**
    
        **[Required]**
    
        **public int AccountID { get; set; }**
    
        **// ================= COVER UPLOADS =================**
    
        **public List<CoverFileUploadDTO> CoverFiles { get; set; }**
    
        **//============ Declared Items=================**
    
        **public List<DeclarationItemsDTO> DeclarationItems { get; set; }**
    
    **}**
    

    Java Script
    async function handleFinalSubmission() {

    **if (!confirm('Are you sure you want to submit this policy application?')) {**
    
        **return;**
    
    **}**
    
    **const formData = buildPolicyFormData();**
    
    **const result = await sendPolicy(formData);**
    
    **if (!result) {**
    
        **return;**
    
    **}**
    
    **alert(result.message);**
    
    **if (result.success) {**
    
        **window.location.href =**
    
            **'/policylisting/insuranceproduct';**
    
    **}**
    

    }

    async function sendPolicy(formData) {

    **if (isSubmitting) return;**
    
    **isSubmitting = true;**
    
    **showLoader();**
    
    **try {**
    
        **const res = await fetch(`/policyListing/get`, {**
    
            **method: 'POST',**
    
            **body: formData**
    
        **});**
    
        **const data = await res.json();**
    
        **return data;**
    
    **} catch (err) {**
    
        **console.error(err);**
    
        **alert("Failed to submit policy");**
    
        **return null;**
    
    **} finally {**
    
        **isSubmitting = false;**
    
        **hideLoader();**
    
    **}**
    

    }

    function appendIfExists(formData, key, elementId) {

    const el = document.getElementById(elementId);
    
    if (el)
    
        formData.append(key, el.value.trim());
    

    }

    function buildPolicyFormData() {

    const formData = new FormData();
    
    appendIfExists(formData, "FirstName", "firstName");
    
    appendIfExists(formData, "MiddleName", "middleName");
    
    appendIfExists(formData, "LastName", "lastName");
    
    appendIfExists(formData, "PhoneNumber", "phone");
    
    appendIfExists(formData, "Sex", "sex");
    
    appendIfExists(formData, "DOB", "dob");
    
    appendIfExists(formData, "Agent", "agent");
    
    appendIfExists(formData, "Address", "address");
    
    appendIfExists(formData, "EmailAddress", "email");
    
    appendIfExists(formData, "NOKFullName", "nokName");
    
    appendIfExists(formData, "NOKRelationship", "nokRelationship");
    
    appendIfExists(formData, "NOKPhoneNumber", "nokPhone");
    
    appendIfExists(formData, "NOKAddress", "nokAddress");
    
    appendIfExists(formData, "IdentificationTypeId", "idType");
    
    appendIfExists(formData, "IdentificationNumber", "idNumber");
    
    appendIfExists(formData, "ExpiryDate", "expiryDate");
    
    appendIfExists(formData, "StateID", "businessState");
    
    appendIfExists(formData, "LGAID", "businessLga");
    
    appendIfExists(formData, "StreetNumber", "businessStreetNumber");
    
    appendIfExists(formData, "StreetName", "businessAddress");
    
    appendIfExists(formData, "LandMark", "businessLandmark");
    
    const idFile = document.getElementById('idUpload')?.files[0];
    
    if (idFile) formData.append("Identification", idFile);
    
    if (policyId) {
    
        formData.append("PolicyID", policyId);
    
    }
    
    // Covers
    
    if (isCustomPolicy && selectedCovers.length > 0) {
    
        selectedCovers.forEach((cover, i) => {
    
            formData.append(`Covers[${i}].CoverID`, cover.CoverID);
    
            formData.append(`Covers[${i}].RiskCovered`, coverRisks[cover.CoverID] || 0);
    
        });
    
    } else if (selectedCoverIds.length > 0) {
    
        selectedCoverIds.forEach((id, i) => {
    
            formData.append(`Covers[${i}].CoverID`, id);
    
        });
    
    }
    
    // Dynamic Cover Files
    
    let fileIndex = 0;
    
    let itemIndex = 0;
    
    document.querySelectorAll('.cover-upload').forEach(input => {
    
        const file = input.files[0];
    
        if (file) {
    
            formData.append(`CoverFiles[${fileIndex}].File`, file);
    
            formData.append(`CoverFiles[${fileIndex}].CoverId`, input.dataset.coverid);
    
            formData.append(`CoverFiles[${fileIndex}].Label`, input.dataset.label);
    
            formData.append(`CoverFiles[${fileIndex}].coverUploadRequirementID`, input.name);
    
            fileIndex++;
    
        }
    
    });
    
    // Declaration Items
    
    document.querySelectorAll("#tblDeclarationItems tbody tr").forEach(row => {
    
        const itemName = row.querySelector(".item-name")?.value.trim();
    
        const amount = row.querySelector(".item-amount")?.value;
    
        // Ignore empty rows
    
        if (!itemName || !amount)
    
            return;
    
        formData.append(`DeclarationItems[${itemIndex}].ItemName`, itemName);
    
        formData.append(`DeclarationItems[${itemIndex}].Amount`, amount);
    
        itemIndex++;
    
    });
    
    return formData;
    

    }

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.