14

モデルを持つビューがある場合、Car..としましょう。

@model Project.Car

そのビュー内で、新しいモデルにデータを送信するフォームを作成したい

    @using (Html.BeginForm("Add", "Controller"))
    {
        @Html.Hidden("ID", "1")
        @Html.Hidden("UserID", "44")
        @Html.TextArea("Description")
    }

アクションが ViewModel で定義されている場合、動作しないことに気付きました (モデルは常に null です)。

    [HttpPost]
    public PartialViewResult Add(ViewModels.NewModel model)

ただし、 FormCollection を使用すると機能します。

    [HttpPost]
    public PartialViewResult Add(FormCollection formCollection)

ビューモデルは次のとおりです。

public class NewModel
{
    public int ID { get; set; }
    public int UserID { get; set; }
    public string Description { get; set; }
}

私の質問は、フォームから NewModel にデータを投稿できますか? それが置かれているビューは、Project.Car に関連付けられているのが正しいです。Project.Car とは関係のない別のデータ セットを投稿する必要がある、ページ上の小さなフォームです。

4

5 に答える 5

7

はい、ビューを 1 つのモデルに強く型付けし、それを別のモデルに POST することができます。

その際、次の 2 つのオプションがあります。

  1. 各入力フィールドに正しい名前を手動で指定して、デフォルトのバインダーがそれを理解してモデルを作成できるようにします ()。

    これは機能しますが、タイプミスに注意する必要があり、プロパティ名のスペルを間違えてもコンパイル時にエラーが発生しないことも意味します。

  2. 新しいモデル タイプにバインドされたビューで HTML ヘルパーを手動で作成します。その後、適切に HTML が生成されます。

    IViewDataContainerヘルパーを作成するには、モデルのインスタンスをインターフェイスの形式で公開するラッパー オブジェクトが必要です。モデル自体を含め、どこでもそのラッパーを定義できます。

    public class NewModel
    {
      public int ID { get; set; }
      public int UserID { get; set; }
      public string Description { get; set; }
    
      public class WrapperForHtmlHelper : System.Web.Mvc.IViewDataContainer
      {
        public System.Web.Mvc.ViewDataDictionary ViewData { get; set; }
    
        public WrapperForHtmlHelper(NewModel value)
        {
            this.ViewData = new System.Web.Mvc.ViewDataDictionary<NewModel>(value);
        }
      }
    }
    

    次に、ビューで次のインスタンスにバインドされたヘルパーを作成しますNewModel

    var ModelToPost = new YourApp.Models.NewModel() { ID = 1, UserID = 43, Description = "" }
    
    var hlp = new HtmlHelper<YourApp.Models.NewModel>
             (this.ViewContext,
              new YourApp.Models.NewModel.WrapperForHtmlHelper(ModelToPost)
             );
    

    そして、通常どおりヘルパーを使用します。

    @hlp.HiddenFor(m => m.ID)
    @hlp.HiddenFor(m => m.UserID)
    @hlp.TextAreaFor(m => m.Description)
    

    その後PartialViewResult Add(ViewModels.NewModel model)、データを適切に受信します。

于 2014-02-28T18:25:15.770 に答える
6

モデルの名前とアクションの間に矛盾があります。例では、モデルが呼び出されているのAddに対し、アクションでは を使用していViewModels.NewModelます。さらに悪いことに、ビューは というモデルに強く型付けされていCarます。このすべてが面倒です。

したがって、正しいビューモデルを定義することから始めます。

public class CarViewModel
{
    public int ID { get; set; }
    public int UserID { get; set; }
    public string Description { get; set; }
}

そしてコントローラー:

public class CarsController: Controller
{
    public ActionResult Add()
    {
        var model = new CarViewModel
        {
            // don't ask me, those are the values you hardcoded in your view
            ID = 1,
            UserID = 44,
        };
        return View(model);
    }   

    [HttpPost]
    public PartialViewResult Add(CarViewModel model)
    {
        ...
    }
}

ビューモデルに対応する強く型付けされたビュー:

@model CarViewModel
@using (Html.BeginForm())
{
    @Html.HiddenFor(x => x.ID)
    @Html.HiddenFor(x => x.UserID)
    @Html.TextAreaFor(x => x.Description)
    <button type="submit">Add</button>
}
于 2013-02-26T16:28:27.180 に答える
3
My question is can I post data to NewModel from my form? 

簡単に言えば、アプリケーション内の任意のモデルに関連する任意のコントローラーの任意のコントローラー アクションにフォームを投稿できます。

たとえば、フォームをコントローラーの " Add" アクションに投稿するには、次のようにします。NewModel

@using (Html.BeginForm("Add", "NewModel"))
    {
        @Html.Hidden("ID", "1")
        @Html.Hidden("UserID", "44")
        @Html.TextArea("Description")
    }

ビューはモデルに強く型付けされているためCar、これを変更して、更新中のモデルとタイプが一致する ViewModel をビューに送信するか ( Darin が示したように)、コントローラーに投稿データCarをマップする必要があります。NewModel:

のアクションCarController(Add投稿) :

[HttpPost]
public PartialViewResult Add(Car model)
{
    //now map attribute values from the Car model onto 
    //corresponding attributes of an instance of NewModel
    NewModel new = new NewModel();
    new.ID = model.ID;
    new.UserID = model.UserID;
    new.Desc = model.Description;
    //etc...

    //update your model/db
    _db.Add(new);

    //Redirect however you wish...
}

また、ViewModel からモデルへのマッピング、およびその逆のマッピングを自動化する、オブジェクトからオブジェクトへのマッパーであるAutoMapperも確認してください。

于 2013-02-26T18:43:47.310 に答える
1

あなたのビューはタイプのモデルを使用するように設定されていますProject.Car 、アクションメソッドはタイプのモデルを取りますが、ViewModels.NewModel投稿されたモデルクラスAddタイプですか?

Addそれらをすべて一致するように変更します(正しいと仮定します):

意見:

@model Add

コントローラ:

[HttpPost]
public PartialViewResult Add(Add model)
于 2013-02-26T16:29:25.747 に答える
-6

この目的のためにカスタムモデルバインダーを作成することもできます。

于 2013-02-27T08:03:48.223 に答える