[Solved] ASP.NET Core Upload control works but returns error

2 Answers 102 Views
Upload
Wendy
Top achievements
Rank 1
Wendy asked on 17 Nov 2025, 08:06 PM

I'm attempting to use the Kendo Upload control asynchronously to an MVC controller, which passes the file to a WebApi controller.  The file is uploaded successfully, however when it returns to the MVC view, it reports that the file failed to upload with the error below.  We are using Azure B2C for authentication:

"Access to XMLHttpRequest at 'https... b2clogin.com...' (redirected from 'https//localhost:7074/Files/UploadFile') from origin 'https://localhost:7074' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."

Server response:

"Failed to load resource: net::ERR_FAILED"

The control is located in a partial view as part of a tab control on a CSHTML view.  Here is the code for the upload control:

<div class="row">
    <div class="col-md-8">
        @(Html.Kendo().Upload()
                .Name("uploadedFile")
            .Multiple(false)
            .Validation(v =>
            {
                v.AllowedExtensions(new string[] { ".csv" });
                v.MaxFileSize(3145728);
            })
            .Async(a => a
                .AutoUpload(false)
                .Save("UploadFile", "Files")
            )
            .Events(e =>
            {
    e.Upload("onFileUpload");
            })

         )
    </div>
    <div class="col-md-4">
    </div>

</div>

Here is the C# code for the MVC controller:

        [HttpPost]
        public async Task<ActionResult> UploadFile(IFormFile uploadedFile, string month, string year)
        {
            if (uploadedFile == null || uploadedFile.Length == 0)
                return BadRequest("No file uploaded.");

            var reportingPeriod = month + year;

            using (var content = new MultipartFormDataContent())
            {
                if (uploadedFile.Length > 0)
                {
                    var streamContent = new StreamContent(uploadedFile.OpenReadStream());
                    streamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(uploadedFile.ContentType);
                    content.Add(streamContent, "file", uploadedFile.FileName);
                }

                using (var response = await _client.HttpClient.PostAsync("/api/Files/loadbackdatedmonthlytrueupfile/" + reportingPeriod, content))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        // Kendo expects an empty string for success
                        return Content("");
                    }
                    else
                    {
                        return StatusCode((int)response.StatusCode, await response.Content.ReadAsStringAsync());
                    }

                }

            }
        }

 

Here is the code for the WebApi controller:

[HttpPost("loadbackdatedmonthlytrueupfile/{reportingPeriod}")]
public async Task<IActionResult> LoadBackdatedMonthlyTrueUpFile([FromForm] IFormFile file, string reportingPeriod)

{

     //other logic here

     return Ok(new { file.FileName, file.Length });

}

This is the info I received from Copilot:

This error is caused by trying to call the Azure AD B2C /authorize endpoint using an XMLHttpRequest (AJAX/fetch) from your frontend (https://localhost:7074). Azure AD B2C does not support CORS for this endpoint, so the browser blocks the request.
Root cause:
• The /authorize endpoint is designed for browser redirects, not AJAX/fetch/XHR.
• No CORS headers will ever be present on this endpoint, so preflight requests will always fail.
How to fix:
• Never use AJAX/fetch/XHR to call the /authorize endpoint.
• Always use a full-page redirect for authentication.
For example, set window.location.href to the login URL, or let the [Authorize] attribute and OIDC middleware handle it for you.

How can I configure this upload control to return to the view without the error (attaching screenshot)?

2 Answers, 1 is accepted

Sort by
0
Austin
Top achievements
Rank 2
Iron
answered on 15 May 2026, 08:09 PM | edited on 20 May 2026, 04:21 PM

NOTE: I'd try the fix below from Anton, first.

The upload request is being redirected to Azure B2C login, and an async upload/XHR cannot follow that redirect because B2C does not allow CORS on the authorize endpoint.

The fix is to make sure /Files/UploadFile returns a normal HTTP response, not a login redirect.

Check these items

[Authorize]
[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile uploadedFile, string month, string year)

 

If the user is not authenticated, return 401 instead of redirecting to B2C for AJAX requests:

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Events.OnRedirectToLogin = context =>
    {
        if (context.Request.Path.StartsWithSegments("/Files/UploadFile"))
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return Task.CompletedTask;
        }

        context.Response.Redirect(context.RedirectUri);
        return Task.CompletedTask;
    };
});


For OpenID Connect/B2C, handle the equivalent redirect event in your OIDC/B2C configuration so AJAX requests get 401/403, not a redirect to b2clogin.com.

Also make sure the Kendo Upload posts to the MVC endpoint only:

.Async(a => a
    .AutoUpload(false)
    .Save("UploadFile", "Files")
)

Your MVC action can then call the Web API server-side with HttpClient, as you are already doing.

 

Kendo will show success when the MVC action returns 2xx. It will show failed when the request is redirected, returns 401/4013/500, or the browser blocks the response. The browser blocked B2C redirect is the failure here.

0
Anton Mironov
Telerik team
answered on 20 May 2026, 11:10 AM

Hello,

Your analysis is correct—the Kendo Upload fails because AJAX requests redirected to Azure B2C login are blocked by CORS. To resolve this, you need to ensure that unauthenticated AJAX requests to your upload endpoint return a 401 Unauthorized status, not a redirect.

Steps to Fix the Issue:

  • Configure your authentication middleware (both cookie and OpenID Connect/Azure B2C) to detect AJAX requests and return 401 for /Files/UploadFile. This prevents a redirect to the B2C login endpoint.

  • For cookies, your code is correct:

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Events.OnRedirectToLogin = context =>
    {
        if (context.Request.Path.StartsWithSegments("/Files/UploadFile"))
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return Task.CompletedTask;
        }
        context.Response.Redirect(context.RedirectUri);
        return Task.CompletedTask;
    };
});
  • For OpenID Connect/Azure B2C, use the OnRedirectToIdentityProvider event or equivalent to return 401/403 for AJAX requests. Make sure your OIDC/B2C setup also checks for AJAX requests (look for X-Requested-With: XMLHttpRequest header or accept header).

  • The Kendo Upload control will show "failed" when it receives a 401 or other error, but will not be redirected to B2C. When your MVC action returns 2xx, the upload will show "success".

  • Ensure the Upload control posts only to your MVC endpoint:

.Async(a => a
    .AutoUpload(false)
    .Save("UploadFile", "Files")
)

Alternative Solution:

  • You can handle upload errors on the client side with the Error event to show a custom message:
function onUploadError(e) {
    alert("Upload failed. Please login and try again.");
}
@(Html.Kendo().Upload()
    .Name("uploadedFile")
    .Events(events => events.Error("onUploadError"))
)

Additional Notes:

  • If you have custom authentication logic or additional OIDC/B2C configuration, please share more details to confirm the setup.
  • After these changes, AJAX upload requests will not be redirected and the Kendo Upload will properly reflect the authentication status.

I hope this information helps.

 

    Kind Regards,
    Anton Mironov
    Progress Telerik

    Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

    Tags
    Upload
    Asked by
    Wendy
    Top achievements
    Rank 1
    Answers by
    Austin
    Top achievements
    Rank 2
    Iron
    Anton Mironov
    Telerik team
    Share this question
    or