I am having a terrible time getting a REST API controller that is located in an external assembly (in other words, a Razor Class Library) to work. Whenever I make a call to the API via JavaScript, I get a 404 error.
In the Razor Class Library (RCL) I put the controller in its own Area in this structure:
The LookupController is decorated with Route attributes:
namespace Case.Coding.Areas.CaseCoding.Controllers
{
[Route("CaseCoding/[controller]")]
[ApiController]
public class LookupsController : ControllerBase
{
[HttpPost]
[Route("External")]
public async Task<IActionResult> ExternalAsync()
{
return Ok("This is a value. Hoo boy.");
}
}
}
In the calling project I put a button on the Index page like this:
<button id="ClickHere" onclick="GetApiResult();">Click Here</button>
<div id="ClickResult"></div>
And the GetApiResult function looks like this:
function GetApiResult() {
var container = $('#ClickResult');
$.ajax({
url: '/CaseCoding/Lookups/External',
method: 'POST',
contentType: 'application/json'
})
.done(function (result, statusText, xhr) {
var isUndefined = typeof result === 'undefined';
if (isUndefined || result.length == 0) {
container.append('<p class="pat-comment err">Nothing returned.</p>');
}
else {
container.append(result);
}
})
.fail(function (xhr, statusText, err) {
container.append('<p class="pat-comment err">' + err + '</p>');
});
}
I thought the URL to the controller might be different and tried several combinations. Nothing worked, so I thought I might explore the routes attached to the calling project to find out, and found some code (courtesy of https://www.meziantou.net/list-all-routes-in-an-asp-net-core-application.htm) that allowed me to explore them:
if (app.Environment.IsDevelopment())
{
app.MapGet("/debug/routes", (IEnumerable<EndpointDataSource> endpointSources) =>
string.Join("\n", endpointSources.SelectMany(source => source.Endpoints)));
}
Placed right before the app.Run() statement, this code let me see what I want, but the results flummoxed me. I found the controller in the routes, but the EndPoint was no URL. When navigating to /debug/routes I got this list:
/Error
/Index
/Index
/Privacy
/Page1
Case.Coding.Areas.CaseCoding.Controllers.LookupsController.ExternalAsync (Case.Coding)
HTTP: GET /debug/routes
There the API is listed out (2nd from bottom), but why isn't it a URL? Does anyone have any idea what is happening here, and (more importantly) how to make my controller route be recognized as a URL so I can call it from JavaScript?
I didn't reproduce your issue, I can only show you how I did in my side.
I created a new .net 6 MVC project, and I created a web API project in the same solution. Then I create the same
Area
and the same folder and the same Controller.Then I right click on the MVC project to add reference. Then choose the web api project.
This will make the MVC project csproj file be modified.
Since I created the MVC project first, so I don't need to change the startup project, pressing F5 to run the MVC project, then hitting the URL
https://localhost:7089/CaseCoding/Lookups/External
. Here I changed the POST request to GET for easier to test.After making sure the URL, then I write an ajax request in the
index.cshtml
in MVC project.