c# - 値をnullにすることはできません type




投稿パラメータは常にnullです (20)

Angularでは、次の形式でデータを渡すことができました。

 data: '=' + JSON.stringify({ u: $scope.usrname1, p: $scope.pwd1 }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }

そしてWeb API Controlerでは:

    [HttpPost]
    public Hashtable Post([FromBody]string jsonString)
    {
        IDictionary<string, string> data = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonString);
        string username = data["u"];
        string pwd = data["p"];
   ......

あるいは、次のようにJSONデータを投稿することもできます:

    data: { PaintingId: 1, Title: "Animal show", Price: 10.50 } 

そして、コントローラで、次のようなクラス型を受け入れます:

    [HttpPost]
    public string POST(Models.PostModel pm)
    {

     ....
    }

いずれにしても、APIに公開クラスが設定されている場合はJSONを、それ以外の場合は '=' + JSON.stringify({..:...、..:..}})

WebAPIのRCにアップグレードして以来、私はWebAPIでPOSTを呼び出す際にいくつかの本当の問題を抱えています。 私は新しいプロジェクトで生成された基本バージョンに戻りました。 そう:

public void Post(string value)
{
}

フィドラーからの呼び出し:

Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29

Body:
{
    "value": "test"
}

私がデバッグすると、 "value"という文字列は決して割り当てられません。 それはちょうどNULLです。 誰でもこの問題がありますか?

(私は最初により複雑なタイプの問題を見た)

この問題はASP.NET MVC 4に縛られるだけでなく、RCインストール後の新しいASP.NET MVC 3プロジェクトでも同じ問題が発生します


Web APIメソッドのリクエストオブジェクトが常にnullだったのと同様の問題がありました。 コントローラーのアクション名の先頭に「Get」が付いていたので、Web APIはこれをPOSTではなくHTTP GETとして扱いました。 コントローラーアクションの名前を変更した後、意図したとおりに機能するようになりました。


[FromBody]アノテーションを配置し、メソッドのパラメータとしてDtoオブジェクトがあり、それでもデータを取得できない場合は、DTOのプロパティとフィールドを調べます。

私は同じ問題を抱えていました。そこでは私のDTOはnullになりました。 理由は、プロパティの1つがシリアル化できないオブジェクトを指していたことがわかりました。(メディアフォーマッタがデータを解析できないため、オブジェクトは常にnullです。


body内の単一パラメータをWebAPIに$.post(url, { '': productId }このコードが動作します$.post(url, { '': productId }

そしてそれを実際に[HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)

キーは、魔法の単語「値」を使用することです。 int型でもよいし、プリミティブ型でもよい。 内容の種類やヘッダーの訂正に関係なく、Messは、このコードはMVCのポストアクションでは機能しません。


あなたのデータ型を再確認してください。 ドットネットモデルのバインダーは、浮動小数点を整数に変換しません(そして私は他の関連する概念を想定しています)。 これにより、モデル全体が拒否されます。

あなたがこのようなjsonを持っているなら:

{
    "shoeSize": 10.5
}

あなたのC#モデルは次のようになります:

class Shoe{
    public int shoeSize;
}

モデルバインダーはモデルを拒否し、nullを取得します。


いくつかの試行の後、私はデフォルトの動作が正しいと思うし、ハッキングするものはありません。

唯一のやり方は:あなたのpostメソッドの引数が以下のような文字列の場合、本体に二重引用符を含むプレーンな文字列を送るべきです(ajaxまたはpostmanを使用する場合)

//send "{\"a\":1}" in body to me, note the outer double quotes
[HttpPost("api1")]
public String PostMethod1([FromBody]string value)
{
    return "received " + value; //  "received {\"a\":1}"
}

そうでなければ、 外側の二重引用符とエスケープされた内部引用使わないで、ポスト本体にjson文字列を送ると、 {"a":1, "b":2}なモデルクラス(引数型) {"a":1, "b":2}

public class MyPoco{
    public int a;
    public int b;
}

//send {"a":1, "b":2} in body to me
[HttpPost("api2")]
public String PostMethod2([FromBody]MyPoco value)
{
    return "received " + value.ToString();  //"received your_namespace+MyPoco"
}

データモデルとして機能するクラスを作成し、データモデルクラスのプロパティと一致するプロパティを持つJSONオブジェクトを送信してください。 (注:これはテスト済みで、今ダウンロードした最新のMVC 4 RC 2012で動作します)。

public HttpResponseMessage Post(ValueModel model)
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, "Value Recieved: " + model.Value);
}

public class ValueModel
{
    public string Value { get; set; }
}

以下のJSONオブジェクトはHTTP-POST本体で送信され、content-typeはapplication / jsonです

{ "value": "In MVC4 Beta you could map to simple types like string, but testing with RC 2012 I have only been able to map to DataModels and only JSON (application/json) and url-encoded (application/x-www-form-urlencoded body formats have worked. XML is not working for some reason" }

私は、データモデルクラスを作成しなければならない理由は、単純な値はURLパラメータからのものとみなされ、単一の複素数値はボディからのものとみなされるからです。 彼らは[FromBody][FromUrl]属性を持っていますが、 [FromBody] [FromBody] string valueを使っても私にとってはうまく[FromBody] string valueませんでした。 彼らはまだバグをたくさん解決しているようですので、将来これが変わると確信しています。

編集:身体の中で働くXMLを手に入れました。 既定のXMLシリアライザは、XmlSerializerではなくDataContractSerializerに変更されました。 Global.asaxファイルに次の行を挿入すると、この問題が修正されました( reference

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

パラメータが1つしかないので、 [FromBody]属性でそれを装飾してみるか、ここで提案したように値をプロパティとしてDTOを受け入れるようにメソッドを変更することができます: MVC4 RC WebApiパラメータバインディング

更新:正式なASP.NETサイトは、今日、優れた説明で更新されました: http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-1 : http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-1

簡単に言えば、本体に単一の単純な型を送るときには、等号(=)で始まる値だけを送ります。例:body:

=test


問題は、あなたのアクションメソッドが単純な型、すなわち文字列パラメータ値を期待しているということです。 あなたが提供しているのはオブジェクトです。

あなたの問題には2つの解決策があります。

  1. " value "プロパティを持つ単純なクラスを作成し、そのクラスをパラメータとして使用します。この場合、Web APIモデルバインディングはJSONオブジェクトを要求から読み込み、それをparamオブジェクトの "values"プロパティにバインドします。

  2. 文字列値 " test "を渡すだけで動作します。


私がMVC 6に渡す単純なJSONオブジェクトを処理するために見つけた最も簡単な方法は、NewtonSoft jObjectのようなポストパラメータの型を取得していることです。

public ActionResult Test2([FromBody] jObject str)
{
        return Json(new { message = "Test1 Returned: "+ str }); ;
}

私のようにSwaggerやPostmanで同じ問題を抱えている人にとっては、単純な属性をポストに文字列として渡しても、 "ContentType"が指定されていても、まだnull値が得られます。

合格:

MyValue

コントローラーをnullにします。

しかし、あなたが渡す場合:

"MyValue"

値は正しくなります。

引用符はここで違いを生み出しました。 もちろん、これはSwaggerとPostmanだけです。 たとえば、Angularを使用するFrontendアプリケーションでは、これはフレームワークによって自動的に解決されるべきです。


私の場合、問題はパラメータが文字列でオブジェクトではなく、パラメータをNewsoft.JsonのJObjectに変更したことです。


私はFiddlerでも同じ問題がありました。 私は既にContent-Type: application/json; charset=utf-8持っていましたContent-Type: application/json; charset=utf-8 Content-Type: application/json; charset=utf-8またはContent-Type: application/jsonをリクエストヘッダにContent-Type: application/jsonします。

私のリクエストボディも普通の文字列で、Fiddlerでは{'controller':'ctrl'}書いていました。 これは私のPOSTメソッドの文字列パラメータをnull

修正 :引用符を使用して文字列を示すことを忘れないでください 。 つまり、 "{'controller':'ctrl'}"書いて修正しました。 (注:JSONを書くときは、アポストロフィを使用するか、 "{\"controller\":\"ctrl\"}" )のように引用符をエスケープしてください。


私はこれがこの質問に対する答えではないことを知っていますが、私の問題の解決策を探すときに私はそれを見つけました。

私の場合、複雑な型はバインドされていませんでしたが、私はPOSTを実行していませんでした、私はクエリ文字列のパラメータでGETを行っていました。 解決策は[FromUri]をargに追加することでした:

public class MyController : ApiController
{
    public IEnumerable<MyModel> Get([FromUri] MyComplexType input)
    {
        // input is not null as long as [FromUri] is present in the method arg
    }
}

私はちょうどこれがフィドラーを使用して発生した。 問題は私がContent-Type指定しなかったことでした。

あなたのPOSTリクエストにContent-Typeヘッダーを含めてみてください。

Content-Type: application/x-www-form-urlencoded

また、以下のコメントのとおり、JSONヘッダーを含める必要があります

Content-Type: application/json

私はパーティーに少し遅れていますが、コントローラーを使用してNULL値を突き抜けた人はPOSTリクエストの前に単に "="を追加するだけです。

私がapplication / json Content-Typeを使用したとき、コントローラはNULL値も渡しました。 以下の「application / x-www-form-urlencoded」コンテンツタイプに注意してください。 ただし、APIの戻り値の型は "application / json"です。

 public static string HttpPostRequest(string url, Dictionary<string, string> postParameters)
    {
        string postData = "=";

        foreach (string key in postParameters.Keys)
        {
            postData += HttpUtility.UrlEncode(key) + "="
                  + HttpUtility.UrlEncode(postParameters[key]) + ",";
        }

        HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        myHttpWebRequest.Method = "POST";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);

        myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
        myHttpWebRequest.ContentLength = data.Length;

        Stream requestStream = myHttpWebRequest.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        Stream responseStream = myHttpWebResponse.GetResponseStream();

        StreamReader myStreamReader = new StreamReader(responseStream, System.Text.Encoding.Default);

        string pageContent = myStreamReader.ReadToEnd();

        myStreamReader.Close();
        responseStream.Close();

        myHttpWebResponse.Close();

        return pageContent;
    }

私は今日これで頭を傷つけている。

私の解決策は、 [FromBody]HttpRequestMessageに変更し、本質的にHTTPスタックを上げることです。

私の場合、私はz64のjsonであるワイヤを介してデータを送信しています。これはbase64'dです。 アンドロイドアプリからこのすべて。

私のWebエンドポイントの元の署名は、( [FromBody]を使用して)次のようになりました。

この問題の修正は、エンドポイントの署名にHttpRequestMessageを使用することに戻すことでした。

次のコード行を使用して、投稿データにアクセスできます。

これが機能し、元の未加工の投稿データにアクセスすることができます。 あなたは、文字列の先頭に=記号を付けるか、コンテンツタイプを変更することで、バイリンガルで回り込む必要はありません。

さて、私はまず、コンテンツタイプを "Content-Type:application / x-www-form-urlencoded"に変更するという上記の答えの1つに従おうとしました。 生データの場合、+文字を取り除くので、これは悪いアドバイスです。

"MQ0AAB + LCAAAAAA"はこのような "MQ0AAB LCAAAAAA"のようになります。 あなたが望むものではありません。

HttpRequestMessageを使用するもう1つの利点は、エンドポイント内のすべてのhttpヘッダーにアクセスできることです。


私は同じ問題があり、コンテンツタイプを "application / json"に変更しても問題は解決されないことがわかりました。 しかし、 "application / json; charset = utf-8"が働いていました。


行を追加する

        ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

関数の最後にGlobal.asax.csのprotected void Application_Start()がASP.NET MVC3の私に似た問題を修正しました。


複合型の場合、Web APIは、メディア型フォーマッタを使用して、メッセージ本文から値を読み取ろうとします。

モデルクラスを飾る[Serializable]属性があるかどうか確認してください。

属性が削除されているかどうか これは私のために働いた。





asp.net-web-api-routing