2024-10-13

ASP.NET Route results in 404 when the route ends with a filename

The Problem 

I had a custom route set on an API method that was to be used to delete a file from a ZIP created for an expense.

[HttpDelete]
[Route("api/reimbursements/expense/{expenseId}/receipt/{receiptFileName}")]
public async Task<IHttpActionResult> RemoveReceiptFromExpense(string expenseId, string receiptFileName) 
{
    // code to perform the remove here...
}

Everytime I tried to hit this endpoing using JavaScript's "fetch" API using the DELETE verb, it would always result in a 404. I spent more than an hour banging my head against the wall trying various different route changes, but could not understand why other endpoints on the same API controller worked except for this one.

The Reason

It finally dawned on me that ASP.NET has handlers that are filename-based, and they were intercepting my request and not finding a match that could fill it.  It wouldn't pass it to the routing handler that would go find my template and handle it.

The Solution

I don't have time today to research the more elegant solution, which would be to get the routing system to ignore the filename checks for this route and handle it with the filename at the end of the route, so I chose to reverse the template and put the receipt filename first and the expenseId last.  Now it looks like this:

[HttpDelete]
[Route("api/reimbursements/receipt/{receiptFileName}/expense/{expenseId}")]
public async Task<IHttpActionResult> RemoveReceiptFromExpense(string expenseId, string receiptFileName) 
{
    // code to perform remove here...
}

This made it work with no issues.  This is a quick solution for others experiencing the same issue.  

If you want to keep your route with the filename at the end, you will need to research how to force the "Extensionless" handlers to intercept your request for that template.  As I mentioned before, I don't have time today to research that, but needed to document this with the little time I have, so I can remember why next time I run into this issue.


No comments: