繁体   English   中英

使用 XMLHttpRequest 发布到 ASP.Net Core WebAPI 时出现错误 415

[英]Error 415 when posting to ASP.Net Core WebAPI using XMLHttpRequest

使用 WebAPI 后端服务器处理一个新项目,尽管 Postman 向控制器发布没有问题,但我无法从实际网站向控制器发布信息。 我收到错误 415,浏览器控制台日志记录:

HTTP415: UNSUPPORTED MEDIA TYPE - The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
(XHR)OPTIONS - http://localhost:5000/api/Users

虽然来自 Kestrel 的日志是

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/Users  0
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/Users  0
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 415
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 415
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action SchoolsChat.Controllers.UserContoller.Post (SchoolsChat) in 2.5323ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action SchoolsChat.Controllers.UserContoller.Post (SchoolsChat) in 2.5323ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 6.6615ms 415 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 6.6615ms 415 

我正在尝试发布以下 JSON:

{
    UserDOB: "2016-12-18",
    UserFirstName: "asdf",
    UserLastName: "asasdf",
    UserName: "asdf",
    UserSecret: "asdf"
}

使用这个 TypeScript 类

/**
 * JsonPost
 */
class JsonPost {
    private _response: number;
    public get Reponse(): number {
        return this._response;
    }
    constructor(link: string, data: Object) {
        let request = new XMLHttpRequest();
        request.withCredentials = true;

        request.open("POST", APIUri + link, true);
        request.setRequestHeader("content-type", "application/json");
        request.setRequestHeader("cache-control", "no-cache");
        request.onreadystatechange = () => this._response = request.status;
        console.log(request);
        request.send(JSON.stringify(data));
    }
}

用户模型为

public class User
    {
        [KeyAttribute]
        public int UserId { get; set; }
        [RequiredAttribute]
        public int SchoolId { get; set; }
        [RequiredAttribute]
        public string UserName { get; set; }
        [RequiredAttribute]
        [DataTypeAttribute(DataType.Password)]
        public string UserSecret { get; set; } // Unnecessary due to school linking?
        [RequiredAttribute]
        public virtual School UserSchool { get; set; }
    }

虽然发布的控制器很简单,只是输出名字

[HttpPost]
    public IActionResult Post([FromBody]User user)
    {
        Console.WriteLine(user.UserName);
        return StatusCode(200);
    }

编辑虽然 nemec 的答案有助于解决问题,但我发现对于 WebAPI,最好的解决方案是仅使用 app.UseCors 作为服务配置 cors。AddCors 在许多情况下实际上并未在响应中包含必要的标头.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
            app.UseMvc();
        }

就我而言,问题是我在操作参数之前放置了FromBody属性。

从:

[HttpPost("Contact")]
public async Task<IActionResult> NewContact([FromBody]Contact contact)

到:

[HttpPost("Contact")]
public async Task<IActionResult> NewContact(Contact contact)

正如 Evan 在他的评论中提到的,当您发出跨域 ajax 请求时,您的POST正在变成一个OPTIONS 由于浏览器的跨域安全策略,您的 web api 需要告诉浏览器/js 您的网站被允许对其发出 ajax 请求。

https://docs.microsoft.com/en-us/aspnet/core/security/cors

要为您的应用程序设置 CORS,请将Microsoft.AspNetCore.Cors包添加到您的项目中。

在 Startup.cs 中添加 CORS 服务:

 public void ConfigureServices(IServiceCollection services) { services.AddCors(); }

如果您按照链接的说明进行操作,您甚至可以使用IApplicationBuilder.UseCors进一步自定义允许哪些站点。

例如:

app.UseCors(builder =>
    builder.WithOrigins("http://example.com")
           .AllowAnyHeader()
);

Postman 是一个应用程序,因此可以免除跨域规则的约束。

不知道为什么,我对 .Net Core Web API 还是很陌生。 我删除了控制器属性 [ApiController],一切都到位了。

在我的情况下,我在同一个项目中有一个 MVC 接口和 WebApi。 希望这可以帮助某人。

我们升级到 .NET 核心 3.0,当您从查询参数(例如,使用 GET 请求)构建对象时,这需要使用 [FromQuery]。

例子:

[HttpGet("Hierarchy")]
public virtual async Task<IActionResult> GetHierarchy([FromServices] IDeviceHierarchyService service, [FromQuery] HierarchyStructureRequest structureLoad)

我同意@mohas。 对我来说,ASP.Net Core导致415错误的常见原因是缺少绑定属性或请求与声明的绑定之间不匹配([FromBody],[FromForm],[FromQuery]等)。

较旧版本的MVC在没有绑定属性的情况下通常可以正常运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM