web-dev-qa-db-ja.com

HTTPPOST、辞書からフォーム値を取得する方法、または?

このアクションメソッドを持つMVCコントローラーがあります。

[HttpPost]
public ActionResult SubmitAction()
{
     // Get Post Params Here
 ... return something ...
}

フォームは、単純なテキストボックスを備えた重要なフォームです。

質問

パラメータ値にアクセスするにはどうすればよいですか?

ビューから投稿するのではなく、外部から投稿します。私がアクセスできるキー/値のペアのコレクションがあると仮定しています。

Request.Params.Get("simpleTextBox");を試しましたが、「申し訳ありませんが、リクエストの処理中にエラーが発生しました。」というエラーが返されます。

106
Richard

コントローラのアクションに、フォームの入力名を反映するオブジェクトを持たせることができます。デフォルトのモデルバインダーは、このオブジェクトを自動的に作成します。

[HttpPost]
public ActionResult SubmitAction(SomeModel model)
{
    var value1 = model.SimpleProp1;
    var value2 = model.SimpleProp2;
    var value3 = model.ComplexProp1.SimpleProp1;
    ...

    ... return something ...
}

別の(明らかにobい)方法は次のとおりです。

[HttpPost]
public ActionResult SubmitAction()
{
    var value1 = Request["SimpleProp1"];
    var value2 = Request["SimpleProp2"];
    var value3 = Request["ComplexProp1.SimpleProp1"];
    ...

    ... return something ...
}
144
Darin Dimitrov

単純に、次のようにFormCollectionを使用できます。

[HttpPost] 
public ActionResult SubmitAction(FormCollection collection)
{
     // Get Post Params Here
 string var1 = collection["var1"];
}

また、フォーム値でマップされたクラスを使用することもできます。asp.netmvcエンジンは自動的にそれを埋めます:

//Defined in another file
class MyForm
{
  public string var1 { get; set; }
}

[HttpPost]
public ActionResult SubmitAction(MyForm form)
{      
  string var1 = form1.Var1;
}
99
Adeel

答えはとても良いのですが、MVCと.NETの最新リリースには、「古い学校」のFormCollectionとRequestキーの代わりに、本当に使いたい別の方法があります。


AJAXまたはFORM POSTを実行するフォームタグ内に含まれるHTMLスニペットを考えます。

<input type="hidden"   name="TrackingID" 
<input type="text"     name="FirstName"  id="firstnametext" />
<input type="checkbox" name="IsLegal"  value="Do you accept terms and conditions?" />

コントローラーは実際にフォームデータを解析し、定義されたタイプのパラメーターとしてユーザーに配信しようとします。チェックボックスを含めたのは、トリッキーなためです。チェックされている場合はテキスト「on」を返し、チェックされていない場合はnullを返します。ただし、要件は、これらの定義済み変数が存在しなければならないことです(nullable(stringがnullableであることに注意してください))、そうでない場合はAJAXまたはPOSTが失敗します。

[HttpPost]
public ActionResult PostBack(int TrackingID, string FirstName, string IsLegal){
    MyData.SaveRequest(TrackingID,FirstName, IsLegal == null ? false : true);
}

かみそりヘルパーを使用せずにモデルをポストバックすることもできます。私はこれが何回か必要であることに気づきました。

public Class HomeModel
{
  public int HouseNumber { get; set; }
  public string StreetAddress { get; set; }
}

HTMLマークアップは単純に...

<input type="text" name="variableName.HouseNumber" id="whateverid" >

コントローラ(Razor Engine)はフォーム変数 "variableName"(名前は好きですが、一貫性を保ちます)をインターセプトし、構築してMyModelにキャストしようとします。

[HttpPost]
public ActionResult PostBack(HomeModel variableName){
    postBack.HouseNumber; //The value user entered
    postBack.StreetAddress; //the default value of NULL.
}

コントローラーがモデル(この場合はHomeModel)を予期している場合、パーサーはデフォルト(通常はNULL)のままにするため、すべてのフィールドを定義する必要はありません。良いことは、マークアップでさまざまなモデルを組み合わせて一致させることができ、ポストバック解析が可能な限り多くなることです。ページでモデルを定義したり、ヘルパーを使用したりする必要はありません。

ヒント:コントローラー内のパラメーターの名前は、HTMLマークアップで定義された名前です。「name =」はモデルの名前ではなく、!内の予期される変数の名前です。


List<>の使用は、マークアップがもう少し複雑です。

<input type="text" name="variableNameHere[0].HouseNumber" id="id"           value="0">
<input type="text" name="variableNameHere[1].HouseNumber" id="whateverid-x" value="1">
<input type="text" name="variableNameHere[2].HouseNumber"                   value="2">
<input type="text" name="variableNameHere[3].HouseNumber" id="whateverid22" value="3">

List <>のインデックスは、常にゼロベースでシーケンシャルでなければなりません。 0、1、2、3。

[HttpPost]
public ActionResult PostBack(List<HomeModel> variableNameHere){
     int counter = MyHomes.Count()
     foreach(var home in MyHomes)
     { ... }
}

ポストバックのゼロ以外のインデックスおよび非シーケンシャルインデックスにIEnumerable<>を使用します。バインダーを支援するために、追加の非表示入力を追加する必要があります。

<input type="hidden" name="variableNameHere.Index" value="278">
<input type="text" name="variableNameHere[278].HouseNumber" id="id"      value="3">

<input type="hidden" name="variableNameHere.Index" value="99976">
<input type="text" name="variableNameHere[99976].HouseNumber" id="id3"   value="4">

<input type="hidden" name="variableNameHere.Index" value="777">
<input type="text" name="variableNameHere[777].HouseNumber" id="id23"    value="5">

そして、コードはIEnumerableを使用してToList()を呼び出すだけです。

[HttpPost]
public ActionResult PostBack(IEnumerable<MyModel> variableNameHere){
     int counter = variableNameHere.ToList().Count()
     foreach(var home in variableNameHere)
     { ... }
}

ページごとに単一のモデルまたはViewModel(他のモデルを含むモデルが複雑な「表示」モデルを作成する)を使用することをお勧めします。提案されたとおりにミキシングとマッチングを行うことは悪い習慣と見なされる可能性がありますが、それが機能し、読み取り可能な限り、悪いことではありません。ただし、Razorエンジンのパワーと柔軟性を実証しています。

したがって、任意のデータをドロップするか、Razorヘルパーから別の値をオーバーライドする必要がある場合、または独自のヘルパーを作成したくない場合は、データの異常な組み合わせを使用する単一のフォームで、これらのメソッドを使用して追加のデータ。

36
Piotr Kula

モデルバインディングまたはFormCollectionを使用せずに、Http要求からフォームデータを直接取得する場合は、これを使用できます。

[HttpPost] 
public ActionResult SubmitAction() {

    // This will return an string array of all keys in the form.
    // NOTE: you specify the keys in form by the name attributes e.g:
    // <input name="this is the key" value="some value" type="test" />
    var keys = Request.Form.AllKeys;

    // This will return the value for the keys.
    var value1 = Request.Form.Get(keys[0]);
    var value2 = Request.Form.Get(keys[1]);
}
15
A-Sharabiani