Reputation: 2174
I have an issue with the following piece of code that is working properly when i run this on my local machine but fails returning 404 when published on a server. At first I thought it was due to it not being able to get the file(path problem or smth) but it appears to be that when i call this method like
http://.../api/Handler/GetUserPhoto?AgentID=XXX
its not even hitting the breakpoint at the beginning of the method. So I assume Get request is not routed properly. But why this only happens on server and where should i look for the source of the problem?
[HttpGet("[action]")]
public IActionResult GetUserPhoto(int AgentID)
{
try
{
UserPhotoResponseContract response = _Client.GetUserPhotoAsync(AgentID).GetAwaiter().GetResult().Content;
//if picture not found in db then return predefined default picture
if (response.Image.Length < 10) {
string filePath = Path.Combine(_hostingEnvironment.ContentRootPath, "/wwwroot/images", "blank_agent_200.png");
Microsoft.Extensions.FileProviders.IFileProvider provider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider(_hostingEnvironment.ContentRootPath + "/wwwroot/images/");
Microsoft.Extensions.FileProviders.IFileInfo fileInfo = provider.GetFileInfo("blank_agent_200.png");
var readStream = fileInfo.CreateReadStream();
return base.File(readStream, "image/png", filePath);
}
return base.File(response.Image, System.Drawing.Imaging.ImageFormat.Png), "image/png");
}
catch (Exception)
{
return new EmptyResult();
}
}
EDIT 1
Controller attributes:
[Route("api/[controller]")]
public class HandlerController : Controller
Solution being published to the IIS server via webdeploy and running Kestrel on IIS.
i set this in web.config:
<aspNetCore processPath="dotnet" arguments=".\v10.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout">
<environmentVariables />
</aspNetCore>
but i do not see it creating any log output.
changed method to:
[HttpGet("[action]")]
public IActionResult GetUserPhoto(int AgentID)
{
return Ok("Success");
}
And it is doing the same thing, 200 on local but 404 on server.
EDIT 2
IIS log:
2019-08-15 12:28:48 10.54.0.12 GET /api/Handler/GetUserPhoto AgentID=781 80 - 10.53.0.157 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/76.0.3809.100+Safari/537.36 - 404 0 2 15
2019-08-15 12:28:49 10.54.0.12 GET /api/Handler/GetUserPhoto AgentID=781 80 - 10.53.0.157 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/76.0.3809.100+Safari/537.36 - 404 0 2 15
2019-08-15 12:29:39 10.54.0.12 GET /api/Handler/GetUserPhoto AgentID=781 80 - 10.53.0.157 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/76.0.3809.100+Safari/537.36 - 404 0 2 15
2019-08-15 12:29:39 10.54.0.12 GET /api/Handler/GetUserPhoto AgentID=781 80 - 10.53.0.157 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/76.0.3809.100+Safari/537.36 - 404 0 2 0
2019-08-15 12:29:40 10.54.0.12 GET /api/Handler/GetUserPhoto AgentID=781 80 - 10.53.0.157 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/76.0.3809.100+Safari/537.36 - 404 0 2 31
EDIT 3
Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAntiforgery antiforgery)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
//Middleware for exception filtering
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.Use(next =>
{
return async context =>
{
if (context.Request.Path.StartsWithSegments("/test"))
{
await context.Response.WriteAsync("Hit!");
}
else
{
await next(context);
}
};
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "/{controller}/{action=Index}/{id?}");
});
//Anti-forgery configuration
app.Use(next => context =>
{
string path = context.Request.Path.Value;
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
//}
return next(context);
});
//Middleware to work with headers
app.UseMiddleware(typeof(HeadersMiddleware));
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
Upvotes: 2
Views: 1755
Reputation: 2672
I'm not able to comment, so I'll post a way to debug your problem and to narrow down where it might be coming from - the server, or from ASP.NET Core's routing:
Let's check if your server actually receives any client requests, by adding a simple middleware for the job.
In the Configure method:
app.Use(next =>
{
return async context =>
{
if (context.Request.Path.StartsWithSegments("/test"))
{
await context.Response.WriteAsync("Hit!");
}
else
{
await next(context);
}
};
});
Make sure you add the above code before app.UseMvc
, just in case.
Now when you start your web server with the following code added, try going to <yourserver's ip>:<port>/test
with your favorite web browser.
If you see the message "Hit!" on the page, then your server is working properly and accepting requests. If you don't see anything, then something else is going on, and the source of the problem is almost always the server's configuration, unless you've supplied incorrect ASP.NET Core configuration for it.
It's worth trying to explicitly state the route by using the Route attribute instead of the built-in template for HttpGet
if all else fails.
[Route("[action]")]
[HttpGet]
public IActionResult UserPhoto() // removed input here and also changed
{ // the name slightly just to make it easier to test
return Ok("Success");
}
Upvotes: 2