【问题标题】:Why I am getting 400 and 404 error for my WebAPI?为什么我的 WebAPI 出现 400 和 404 错误?
【发布时间】:2020-04-28 03:10:29
【问题描述】:

我正在使用 Angular 8 和 ASP.Net Core3.1 开发一个应用程序。

当我调用所有 API 时,很少有人工作正常,很少有人给出 400 错误,其中很少有人给出 404 错误。

API 给出 ​​400 错误:

型号详情

public class ServiceOffer
{
   public int Id { get; set; }
   public string ServiceName { get; set; }
   public string ServiceDescription { get; set; }
   public int ServicePrice { get; set; }
   public bool Status { get; set; }
} 

API 详情

[Produces("application/json")]
[ApiController]
public class ServiceofferController : ControllerBase
{
    [HttpGet]
    [Route("api/v1/serviceoffer/allservice")]
    public async Task<IActionResult> Index()
    {
        var objService = new ServiceBL();
        var mob = await objService.GetAllServices();
        return Ok(mob);
    }

    [Route("api/v1/serviceoffer/addservices")]
    public async Task<IActionResult> AddServices([FromBody] ServiceOffer objSer)
    {
        var objService = new ServiceBL();
        int flag = await objService.AddServiceOffer(objSer);
        return Ok(flag);
    }       

    [HttpPut]
    [Route("api/v1/serviceoffer/update")]
    public static async Task<int> UpdateUser([FromBody] ServiceOffer objSer)
    {
        var objService = new ServiceBL();
        return await objService.UpdateServiceOffer(objSer);
    }
}

API 工作正常:api/v1/serviceoffer/allservice

API 给出 ​​400 错误:api/v1/serviceoffer/addservices

API Giving 404 错误:api/v1/serviceoffer/update

角度服务

getAllServices(url: string): Observable<IServiceOffer[]> {
return this.http
  .get<IServiceOffer[]>(url)
  .pipe(catchError(this.handleError));
}
getServiceById(url: string, id: number): Observable<IServiceOffer> {
const editUrl = `${url}/${id}`;
// console.log(editUrl);
return this.http
  .get<IServiceOffer>(editUrl)
  .pipe(catchError(this.handleError));
}
 // insert new contact details
 saveService(url: string, cust: IServiceOffer): Observable<any> {
  var Customer = JSON.stringify(cust);
  console.log(url);
  return this.http
  .post(url, Customer, httpOptions)
  .pipe(catchError(this.handleError));
 }
// update contact details
 updateService(url: string, customer: IServiceOffer): Observable<any> {
 //const newurl = `${url}/${id}`;
  return this.http
    .put(url, customer, httpOptions)
    .pipe(catchError(this.handleError));
 }

配置详情

 public class Startup
{
    public IConfiguration Configuration { get; }
    public static string ConnectionString { get; private set; }
    public static Dictionary<string, string> MailSettings { get; private set; }
    public Dictionary<string, string> SmsSettings { get; set; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        ConnectionString = Configuration.GetSection("ConnectionString").GetSection("SalesContext").Value;

        //MailSettings = Configuration.GetSection("SMTP").GetChildren()
        //              .Select(item => new KeyValuePair<string, string>(item.Key, item.Value))
        //              .ToDictionary(x => x.Key, x => x.Value);

        MailSettings = Configuration.GetSection("SMTP").GetChildren().ToDictionary(x => x.Key, x => x.Value);

        services.AddControllersWithViews();
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });

        //services.AddMvc()
        //     .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
        //     .ConfigureApiBehaviorOptions(options =>
        //       {
        //         options.SuppressConsumesConstraintForFormFileParameters = true;
        //         options.SuppressInferBindingSourcesForParameters = true;
        //         options.SuppressModelStateInvalidFilter = true;
        //         options.SuppressMapClientErrors = true;
        //         options.ClientErrorMapping[404].Link = "https://httpstatuses.com/404";
        //     });

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        if (!env.IsDevelopment())
        {
            app.UseSpaStaticFiles();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
        });

        app.UseSpa(spa =>
        {              

            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }
}

任何人都可以解释我为什么会遇到这个可怕的错误?

提前致谢。

【问题讨论】:

  • 向我们展示您如何提出请求
  • @RomanMarusyk 感谢您的快速回复。我已经检查过了,我在运行时获得了正确的 API 路径。
  • 你发布什么数据?您是否尝试调试它?回复的内容是什么?
  • 我通过以下数据进行测试:{id: 1, serviceName: "Test", serviceDescription: "Test", servicePrice: "1000", status: true} 进行更新。无法 PUT /api/v1/serviceoffer/update 这是浏览器显示的错误。

标签: c# asp.net-core-webapi asp.net-core-3.1


【解决方案1】:

对于 400 错误请求,请确保设置 'Content-Type': 'application/json' 标头并更正 Customer Json 数据。我已经尝试过您的测试数据并且它有效(添加[HttpPost] 操作更好)。

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

const cust = { id: 1, serviceName: "Test", serviceDescription: "Test", servicePrice: "1000", status: true } 

var Customer = JSON.stringify(cust);

this.http
  .post("/api/v1/serviceoffer/addservices", Customer, httpOptions)
  .subscribe(result => {
    alert(result);
  }, error => console.error(error));

对于404 Not Found,您需要删除PUT 操作上的static

参考Can MVC action method be static or extension method?

2020 年 1 月 14 日更新

尝试使用servicePrice: 1000 而不是servicePrice: "1000"

如果不想做以上改动。对于asp.net core 3.1,它使用System.Text.Json进行序列化和反序列化。

为了使用旧行为,您可以通过引用 Json.NET support 在 ASP.NET Core 3.1 项目中使用 Json.NET。

1) 安装包 Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.1.0

2) 在startup.cs中添加services.AddControllersWithViews().AddNewtonsoftJson();

【讨论】:

  • 感谢您的回复。我注意到下面提到的错误造成了这个麻烦:“错误”:{“$ .servicePrice”:[“JSON值无法转换为System.Int32。路径:$ .servicePrice | LineNumber:0 | BytePositionInLine:78 ."]}。在 Angular 中,我将 ServicePrice 声明为数字,而在后端服务中,它是 Int32。请帮助解决此问题。
  • @S. S. Maiti 我没有注意到您使用的是 asp.net core 3.1。我更新了我的答案。
【解决方案2】:

此问题与 .Net Core 3.0 有关。内置 JSON 格式化程序无法从 Angular 数字转换为 System.Int32。在浏览了很多文章后,我才知道这是一个错误。解决方案是安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包。并添加这一行 Startup.cs services.AddControllers().AddNewtonsoftJson();

它已经解决了我的问题,现在我的所有服务都可以正常工作。谢谢大家。

【讨论】:

  • 如果您已经解决了问题,您能否标记我的答案以关闭此线程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多