web-dev-qa-db-ja.com

ASP.NET Core API POSTパラメーターは常にnull

私は次を読んだ:

エンドポイント:

[HttpPost]
[Route("/getter/validatecookie")]
public async Task<IActionResult> GetRankings([FromBody] string cookie)
{
    int world = 5;
    ApiGetter getter = new ApiGetter(_config, cookie);
    if (!await IsValidCookie(getter, world))
    {
        return BadRequest("Invalid CotG Session");
    }
    HttpContext.Session.SetString("cotgCookie", cookie);
    return Ok();
}

私のリクエスト:

$http.post(ENDPOINTS["Validate Cookie"],  cookie , {'Content-Type': 'application/json'});

ここで、cookieは、ユーザー入力から送信する文字列です。

要求は、適切なデータと共にエンドポイントに投稿します。ただし、私の文字列は常にnullです。 [FromBody]タグを削除し、投稿されたデータの前に=を追加してみましたが、うまくいきませんでした。また、上記のすべての組み合わせで、異なるコンテンツタイプを追加および削除しようとしました。

この特定のアクションを実行する理由は長く、この質問には関係ありません。

何をしているように見えても、パラメーターが常にヌルになるのはなぜですか?

編集:{cookie: cookie}も使用してみました

Edit2:リクエスト:

Request URL:http://localhost:54093/getter/validatecookie
Request Method:POST
Status Code:400 Bad Request
Remote Address:[::1]:54093

応答ヘッダー

Content-Type:text/plain; charset=utf-8
Date:Mon, 23 Jan 2017 03:12:54 GMT
Server:Kestrel
Transfer-Encoding:chunked
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcRG91Z2xhc2cxNGJcRG9jdW1lbnRzXFByb2dyYW1taW5nXENvdEdcQ290RyBBcHBcc3JjXENvdEdcZ2V0dGVyXHZhbGlkYXRlY29va2ll?=

リクエストヘッダー

POST /getter/validatecookie HTTP/1.1
Host: localhost:54093
Connection: keep-alive
Content-Length: 221
Accept: application/json, text/plain, */*
Origin: http://localhost:54093
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:54093/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

リクエストペイロード

=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]
23
Douglas Gaskell

問題は、Content-Typeapplication/json、リクエストペイロードは実際にはtext/plain。これにより、415 Unsupported Media Type HTTPエラーが発生します。

整列するには少なくとも2つのオプションがあり、Content-Typeおよび実際のコンテンツ。

Application/jsonを使用する

Content-Type なので application/jsonそして、リクエストペイロードが有効なJSONであることを確認します。たとえば、リクエストのペイロードを次のようにします。

{
    "cookie": "=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]"
} 

次に、アクションシグネチャは、JSONオブジェクトと同じ形状のオブジェクトを受け入れる必要があります。

public class CookieWrapper
{
    public string Cookie { get; set; }
}

CookieWrapperクラスの代わりに、または動的を受け入れることができます、またはDictionary<string, string>そしてcookie["cookie"]エンドポイントで

public IActionResult GetRankings([FromBody] CookieWrapper cookie)

public IActionResult GetRankings([FromBody] dynamic cookie)

public IActionResult GetRankings([FromBody] Dictionary<string, string> cookie)

テキスト/プレーンを使用

他の方法は、Content-Typeからtext/plainおよびプレーンテキスト入力フォーマッタをプロジェクトに追加します。それを行うには、次のクラスを作成します。

public class TextPlainInputFormatter : TextInputFormatter
{
    public TextPlainInputFormatter()
    {
        SupportedMediaTypes.Add("text/plain");
        SupportedEncodings.Add(UTF8EncodingWithoutBOM);
        SupportedEncodings.Add(UTF16EncodingLittleEndian);
    }

    protected override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(
        InputFormatterContext context, 
        Encoding encoding)
    {
        string data = null;
        using (var streamReader = context.ReaderFactory(
            context.HttpContext.Request.Body, 
            encoding))
        {
            data = await streamReader.ReadToEndAsync();
        }

        return InputFormatterResult.Success(data);
    }
}

そして、それを使用するようにMvcを構成します。

services.AddMvc(options =>
{
    options.InputFormatters.Add(new TextPlainInputFormatter());
});

こちらもご覧ください

https://github.com/aspnet/Mvc/issues/5137

36
Shaun Luttin

Shaun Luttinの答えは機能しますが、重要な情報が1つ欠けています。文字列が認識されない理由は、それが[〜#〜] json [〜#〜]文字列ではないためです。 。

これを行う;

var payload=JSON.stringify("=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]");

その後、コントローラーをそのままにしておくことができます。

$.ajax({
    url: http://localhost:54093/getter/validatecookie,
    type: 'POST',
    contentType: 'application/json',
    data: payload
});

これが私が理解するのにどれくらい時間がかかったかは恥ずかしいです。私は本当にそれが誰かを助けることを願っています!

7
statler

ばかげて、ドットネットコアでは、「frombody文字列パラメーター」だけを使用することはできません。 1つの文字列パラメーターのみのモデルクラスを作成する必要があります。

public async Task<IActionResult> GetRankings([FromBody] string cookie)

=>

//1. make a model. MyCookie.cs
class MyCookie{
   public string Cookie { get; set; }
}
//2. edit your parameter
public async Task<IActionResult> GetRankings([FromBody] MyCookie cookie)
4
guhyeon

stringを表すように、引用符で本体を配置する必要があります。また、リクエストタイプをapplication/jsonのままにする必要があります。そのようにして、メディアタイプフォーマッタはそれを把握します。

"=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]"

トリックを行う必要があります。

1
Haney

私はこれに長い間苦労し、最後に、DevExpressコントロールがRazor Pageに「PUT」するために何をしていたかを見て、このナゲットを発見しました。

JavaScript

$.ajax({
        type: "PUT",
        url: "/GoalGrid?handler=Single",
        dataType: "json",
        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
        data: {values: single }
    })

GoalGrid.cshtml.cs

public JsonResult OnPutSingle(string values)
{ 
     // Do stuff with 'values' here 
}

トリックは、「application/x-www-form-urlencoded; charset = UTF-8」をリクエストのcontentTypeとして使用することです。この方法では、単一の文字列値のクラスを作成する必要はありません。そして、物事は期待通りに機能します。

0
Danno

.Net Desktop Clientによって.NET Core Hostに文字列データを投稿する必要がありました。サポートされていないメディアエラーが発生しました。私はショーン・ラッティンの答えに従い、うまくいきました。他の誰かが有用だと思った場合に備えて、文字列データを次のように簡単に取得できるものを見つけました:

[HttpPost]
[Route("Request/Echo")]
public async Task<string> Echo()
{
    using (var Reader = new StreamReader(Request.Body, Encoding.UTF8))
    {
        return await Reader.ReadToEndAsync();
    }
}

この投稿 は非常に便利です。

0
Demir