2

モデルに独自の検証を処理させる機能により、MVC2プレビューリリースで遊び始めることができました。これまでのところ、検証スキームの単純さが気に入っています。しかし、私は障害にぶつかりました。この検証スタイルは、単純なビューモデルオブジェクトに対して適切に機能します。たとえば、carという名前のモデルオブジェクトがあり、新しい車を作成するためのビューを作成しようとしている場合、次のようになります。

- - -モデル - - - -

public class Car
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }
}

- - -コントローラ - - - - -

public class CarController : Controller
{
    public ActionResult Create()
    {
        Car myCar = new Car();
        return View("Create", myCar);

    }

    [HttpPost]
    public ActionResult Create(Car myCar)
    {
        if (!ModelState.IsValid)
        {
            return View("Create", myCar);
        }

        //Do something on success
        return View("Index");

    }

}

- - - -意見 - - - - - - -

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Car>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

    <% 
        using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Edit User Profile</legend>
            <p>
                <label for="Id">Id:</label>
                <%= Html.TextBox("Id", Model.Id)%>
                <%= Html.ValidationMessage("Id") %>
            </p>
            <p>
                <label for="Name">Name:</label>
                <%= Html.TextBox("Name", Model.Name)%>
                <%= Html.ValidationMessage("Name") %>
            </p>
            <p>
                <label for="Color">Color:</label>
                <%= Html.TextBox("Color", Model.Color)%>
                <%= Html.ValidationMessage("Color") %>
            </p>

            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

</asp:Content>

これは魅力のように機能します。しかし、私のすべてのビュー、またはそのことに関するモデルオブジェクトが単純なわけではありません。私は次のような車のモデルオブジェクトを持っているかもしれません:

- - -モデル - - - -

public class PaintScheme
{
    public int Red { get; set; }
    public int Blue { get; set; }
    public int Green { get; set; }
}

public class Car
{
    public string Id { get; set; }
    public string Name { get; set; }
    public PaintScheme Paint{ get; set; }
}

- - - -意見 - - - - - - -

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Car>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

    <% 
        using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Edit User Profile</legend>
            <p>
                <label for="Id">Id:</label>
                <%= Html.TextBox("Id", Model.Id)%>
                <%= Html.ValidationMessage("Id") %>
            </p>
            <p>
                <label for="Name">Name:</label>
                <%= Html.TextBox("Name", Model.Name)%>
                <%= Html.ValidationMessage("Name") %>
            </p>
            <p>
                <label for="Red">Color Red:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
            </p>
            <p>
                <label for="Blue">Color Blue:</label>
                <%= Html.TextBox("Blue", Model.Paint.Blue)%>
                <%= Html.ValidationMessage("Blue") %>
            </p>
            <p>
                <label for="Green">Color Green:</label>
                <%= Html.TextBox("Green", Model.Paint.Green)%>
                <%= Html.ValidationMessage("Green") %>
            </p>

            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

</asp:Content>

PaintSchemeプロパティをビューに追加すると、コントローラーアクションに渡された「myCar」オブジェクトに引き継がれません。フォームコレクションからオブジェクトを再構築してからModelStateをチェックすることなく、これを解決する方法はありますか?

4

3 に答える 3

1

これに対処する最も簡単な方法は、dtoを使用してモデルをフラット化することです。次に、automapperを使用して、ドメインオブジェクトをビューモデルにマップします。この変換は、列挙型を文字列に変換して戻すように定義できます。そうすれば、検証が機能し、関心の分離をかなりうまく維持しながら、爆弾がビューに触れることはありません。

于 2009-09-02T03:00:21.540 に答える
1
  1. バインドするプロパティのパブリック セッターが必要です。すべてが非公開であるため、最初のサンプルはどのように機能するのだろうか.
  2. バインドできるようにするには、PaintScheme プロパティの値を少なくとも 1 つ投稿する必要があります。
  3. すべての子プロパティには、そのパスをプレフィックスとして付ける必要があります。パスは *(PropertyName.)** として定義できます

ビューではポイント3が満たされていないようです。ビューの適切な部分を次のように変更します。

        <p>
            <label for="Red">Color Red:</label>
            <%= Html.TextBox("Paint.Red")%>
            <%= Html.ValidationMessage("Red") %>
        </p>
        <p>
            <label for="Blue">Color Blue:</label>
            <%= Html.TextBox("Paint.Blue")%>
            <%= Html.ValidationMessage("Blue") %>
        </p>
        <p>
            <label for="Green">Color Green:</label>
            <%= Html.TextBox("Paint.Green")%>
            <%= Html.ValidationMessage("Green") %>
        </p>

さらに、NullReferenceException の可能性を回避するために、TextBox ヘルパーから明示的な値を削除したことに注意してください。

于 2009-09-02T02:20:46.847 に答える
0

色の部分については、このようなものを使用できます。intであるため、テキストボックスを使用するとは思いませんが、これにより赤い色がバインドされます(入力値が数値の場合)

 <p>
                <label for="Red">Color:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
 </p>
于 2009-09-02T02:48:40.203 に答える