c# - Asp.Net Core 2.1 Get请求未通过

标签 c# asp.net-core

我遇到以下问题:当我在本地计算机上运行以下代码时,该代码可以正常工作,但在服务器上发布时无法返回 404。 起初我以为这是因为它无法获取文件(路径问题或其他问题),但似乎是当我调用这个方法时,例如

http://.../api/Handler/GetUserPhoto?AgentID=XXX

它甚至没有在方法开始处命中断点。所以我假设 Get 请求没有正确路由。但为什么这种情况只发生在服务器上,我应该在哪里寻找问题的根源?

[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();
        }
    }

编辑 1

Controller 属性:

[Route("api/[controller]")]
public class HandlerController : Controller

解决方案通过 webdeploy 发布到 IIS 服务器并在 IIS 上运行 Kestrel。

我在 web.config 中设置了这个:

<aspNetCore processPath="dotnet" arguments=".\v10.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout">
      <environmentVariables />
    </aspNetCore>

但我没有看到它创建任何日志输出。

将方法更改为:

[HttpGet("[action]")]
public IActionResult GetUserPhoto(int AgentID)
{
    return Ok("Success");
}

它也在做同样的事情,本地为 200,但服务器为 404。

编辑2

IIS日志:

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

编辑3

启动.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");
        }
    });
}

最佳答案

我无法发表评论,因此我将发布一种方法来调试您的问题并缩小问题可能来自的位置 - 服务器或 ASP.NET Core 的路由:

让我们通过为作业添加一个简单的中间件来检查您的服务器是否确实收到任何客户端请求。

在配置方法中:

app.Use(next =>
        {
            return async context =>
            {
                if (context.Request.Path.StartsWithSegments("/test"))
                {
                    await context.Response.WriteAsync("Hit!");
                }
                else
                {
                    await next(context);
                }
            };
        });

确保在 app.UseMvc 之前添加上述代码, 万一。 现在,当您启动 Web 服务器并添加以下代码时,请尝试访问 <yourserver's ip>:<port>/test使用您最喜欢的网络浏览器。

如果您在页面上看到消息“Hit!”,则您的服务器工作正常并正在接受请求。如果您没有看到任何内容,则说明发生了其他情况,问题的根源几乎总是服务器的配置,除非您为其提供了不正确的 ASP.NET Core 配置。

值得尝试使用 Route 属性而不是 HttpGet 的内置模板来显式声明路线。如果一切都失败了。

[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");
}

关于c# - Asp.Net Core 2.1 Get请求未通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57499525/

相关文章:

c# - ClientConnectionId 的单声道等效项

c# - 自定义控件覆盖命令按钮

c# - 在 .NET Core 世界中中止线程的替代方案?

asp.net - 如何撤销/无效/取消旧的电子邮件确认 token (身份)

.net - .net core 1.1 中嵌入的 power bi

c# - 使用 WCF 和通用应用程序创建/使用 REST WebService

c# - string.split() "Out of memory exception"读取制表符分隔文件时

c# - ASP.Net Core 3.1 身份 - 生成密码重置 token 问题

c# - 如何使用 WebApplicationFactory 在 TestServer 中切换服务?

c# - C# 中字符串类型的最快(内置)比较是什么