0

会社の詳細ページ内にインデックス ページと会社ノートの作成ページの両方を持つ複雑な ViewModel を作成しようとしています。

現時点での問題は、新しい会社のメモを作成するときに、cshtml に含める EditorFor フィールド以外の情報がオブジェクトにないことです。ViewModel のすべてのデータが失われます。

Company モデルと CompanyController があり、Details アクションで、会社に関連するすべてのメモと、ユーザーが新しいメモを追加できるようにするフォームを入力します。

My Company と CompanyNotes モデルは非常に単純です。

public class Company
{
    public int CompanyID { get; set; }
    // bunch of fields related to the company

    public virtual ICollection<CompanyNote> CompanyNotes { get; set; }
}


public class CompanyNote
{
    public int CompanyNoteID { get; set; }
    public DateTime Date { get; set; }
    public string Note { get; set; }

    public Company Company { get; set; }
}

次のようなViewModelがあります。

public class CompanyViewModel
{
    public Company Company { get; set; }

    // List of all notes associated with this company
    public IEnumerable<CompanyNote> CompanyNotes { get; set; }

    // A CompanyNote object to allow me to create a new note:
    public CompanyNote CompanyNote { get; set; }
}

これは私の Details アクションです。会社のレコードにデータを入力し、関連するメモのリストを取得し、新しい空のオブジェクトを含む作成フォームを表示します。

    public ActionResult Details(int id = 0)
    {
        var viewModel = new CompanyViewModel();

        viewModel.Company = db.Companies.Find(id);

        if (viewModel.Company == null)
        {
            return HttpNotFound();
        }

        viewModel.CompanyNotes = (from a in db.CompanyNotes
                                  where a.Company.CompanyID.Equals(id)
                                  select a).OrderBy(x => x.Date);

        viewModel.CompanyNote = new CompanyNote
            {
                Date = System.DateTime.Now,
                Company = viewModel.Company
            };

        return View(viewModel);
    }

これは、CompanyController の CreateNote アクションです。(これを別の部分ビューに分割する必要がありますか?利点は何ですか?)

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateNote(CompanyViewModel companyViewModel)
    {
        CompanyNote companyNote = companyViewModel.CompanyNote;

        if (ModelState.IsValid)
        {

            db.CompanyNotes.Add(companyNote);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(companyViewModel);

    }

最後に、detail.cshtml の簡易版を次に示します。

@model Project.ViewModels.CompanyViewModel

// My company detail display is here, removed for sake of berevity 
@using (Html.BeginForm("CreateNote", "Company"))
{

    @Html.EditorFor(model => model.CompanyNote.Date)
    @Html.TextAreaFor(model => model.CompanyNote.Note})
    <input type="submit" value="Create" />
}

投稿すると、私の CreateNote アクションには基本的に空である companyViewModel があります。ただし、私のフォームのフィールドである companyViewModel.CompanyNote.Date と companyViewModel.CompanyNote.Note は例外です。ViewModel の他のすべてのデータは null なので、親会社への参照を含める方法さえわかりません。

私はここで正しい道を進んでいますか?

ありがとう、ロビー

4

1 に答える 1

7

投稿すると、CreateNote アクションには基本的に空の companyViewModel が含まれますが、フォームのフィールドである companyViewModel.CompanyNote.Date と companyViewModel.CompanyNote.Note は例外です。ViewModel の他のすべてのデータは null なので、親会社への参照を含める方法さえわかりません。

それは完全に正常な動作です。フォームを送信すると、入力フィールドとしてフォームに含まれる情報のみがサーバーに送信されます。これは、モデル バインダーが取得できることを期待できる唯一の情報です。

HttpPost アクションで CompanyNotes コレクションが必要な場合は、GET アクションで行ったのと同じ方法で、単にバックエンドにクエリを実行します。会社 ID を隠しフィールドとして渡すことで、これを行うことができます。

@Html.HiddenFor(model => model.Company.CompanyID)

したがって、ユーザーが何らかの形で変更することになっているフォーム情報に入力フィールドとしてのみ含めるという考え方です。他のすべての情報については、まあ、バックエンドに既にあるので、それを取得するために必要なことはそれを押すだけです。

従来の Web フォームとは対照的に、ASP.NET MVC には ViewState の概念がなくなりました。これは、HTTP プロトコルのステートレスな性質に非常に近いものです。

于 2013-09-09T11:31:20.297 に答える