web-dev-qa-db-ja.com

XMLHttpRequestを使用してASP.Net Core WebAPIに投稿するときのエラー415

WebAPIバックエンドサーバーを使用して新しいプロジェクトに取り組んでいますが、実際のWebサイトからコントローラーに投稿するのに問題がありますが、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

ケストレルからのログは

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のみを構成することが最善の解決策であることがわかりました。応答に必要なヘッダーを含めます。

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

エヴァンが彼のコメントで述べたように、クロスオリジンajaxリクエストを行うと、POSTOPTIONSに変わります。ブラウザのクロスオリジンセキュリティポリシーにより、ウェブAPIは、ウェブサイトがそれに対してAjaxリクエストを行うことが許可されていることをbrowser/jsに伝える必要があります。

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はアプリであるため、クロスオリジンルールから免除することができます。

7
nemec

私の場合、問題はアクションパラメーターの前にFromBody属性を置くことでした。

から:

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

に:

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

.NETコア3.0にアップグレードしたため、クエリパラメーターからオブジェクトを構築するときに[FromQuery]を使用する必要がありました。 GETリクエストで。

例:

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

理由はまだわかりませんが、私はまだ.Net Core Web APIの初心者です。コントローラー属性[ApiController]を削除すると、すべてが適切に配置されました。

私の状況では、同じプロジェクトにMVCインターフェイスとWebApiがあります。これが誰かを助けることを願っています。

0
Talon