1

ASP.NET MVC 3.0 を使用してアンケートを作成したいと考えています。一部の質問には、ラジオ ボタンといくつかのチェック ボックスがあります。ビュー側とビューモデルの正しい構文を知りたいです。回答のオプションをコレクションに保存したいと思います。IEnumerable は使用するのに適したコレクションでしょうか? これが私のViewModelコードの一部です。

    [DisplayName("Country")]
    [Required(ErrorMessage = "Country is required.")]
    public string Country { get; set; }

    public IEnumerable<string> Countries { get; set; }

    [DisplayName("Business")]
    [Required(ErrorMessage = "Please select a business unit.")]
    public string BusinessUnit { get; set; }

    public IEnumerable<string> Businesses { get; set; }

    public Boolean ToGetFit { get; set; }
    public Boolean ToChallengeMyself { get; set; }      
    public Boolean ToBeHealthier { get; set; }
    public Boolean ChallengeOther { get; set; }
    public string OtherString { get; set; }

    public void build()
    {
        var myService = new SurveyService(new SurveyRepository());
        Name = myService.getName();
        Email = myService.getEmail();
    }      

ビルド メソッドが呼び出されたときに ViewModel に情報を取得する最良の方法は何ですか? IEnumerable を使用する必要がありますか、それとも単に文字列を使用する必要がありますか?

これが私の.aspxページの私のコードです。

<li>    What country do you live in? <br />   
    <%= Html.RadioButtonFor(model => model.Country, "Canada", true) %> Ecuador<br />   
    <%= Html.RadioButtonFor(model => model.Country, "Chile", true) %> Ghana   <br />
    <%= Html.RadioButtonFor(model => model.Country, "Italy", true) %> Nigeria   <br />
    <%= Html.RadioButtonFor(model => model.Country, "Germany", true) %> Romania   
</li>

<li> What business unit do you work in?<br />
    <%= Html.RadioButtonFor(model => model.BusinessUnit, "Pharmaceuticals", true ) %> Pharmaceuticals <br />        
    <%= Html.RadioButtonFor(model => model.BusinessUnit, "Mechanics", true) %> Vaccines  <br />
    <%= Html.RadioButtonFor(model => model.BusinessUnit, "R&D") %> R&D   <br />
    <%= Html.RadioButtonFor(model => model.BusinessUnit, "Distribution", true) %> Distribution   <br />
</li>           

<li>    Why do you want to take part in this workout? <br />
    <%= Html.CheckBoxFor(model => model.ToGetFit ) %>   To get in shape   <br />
    <%= Html.CheckBoxFor(model => model.ToChallengeMyself ) %> To challenge myself     <br />       
    <%= Html.CheckBoxFor(model => model.ToBeHealthier) %>   To be healthier     <br />
    <%= Html.CheckBoxFor(model => model.ChallengeOther) %>  Other  
    <%= Html.TextBoxFor(model => model.OtherString) %>
</li>

ASP.NET MVC は初めてですが、ASP.NET と MVC パターンの両方の経験があります。可能な限り関心の分離に重点を置きたいと思います。

コントローラー クラスがビルド メソッドを呼び出します。モデル/データベースから情報を取得するリポジトリ オブジェクトを取得する Service クラスがあります。

! ラジオ ボタンをデータベースから動的に取得したい。そして、ユーザーが以前のセッションから既に何かを選択している場合は、それを ViewModel で見つけて、ページをロードするときに既に選択されていることを望みます。

4

1 に答える 1

4

上記のアプローチで見られる問題は、ラジオ ボタンとチェック ボックスがビューで定義されていることです。それらがデータベースまたは列挙型などから出ている場合、これは明らかに問題です。すべきことは、特定のラジオ/チェックボックス グループのすべての可能なオプションを表す ViewModel プロパティと、ユーザーがそのグループに対して選択した値を保持するプロパティを追加することです。

まず、 「 CheckBoxListFor」と「RadioButtonListFor 」の優れたヘルパー メソッドを確認してください。それらをプロジェクトにコピーします。

次に、ViewModel でコレクションを として公開する必要がありますIEnumerable<SelectListItem>。これらは、radiolist/checkboxlist/dropdown 要素の可能なオプションです。

次に、ViewModel で、選択された単一のオプション (ドロップダウンまたはラジオ ボタン リストから) または選択されたオプションのコレクション (チェックボックス リストから) の prop を定義する必要があります。アイテムのデータベース ID から int/string を使用できます。選択するタイプが列挙型の場合は、それに直接バインドできます。

最後に、ビューは非常にシンプルになり、新しいオプションを追加しても変更する必要はありません。データベース主導のオプションの場合、コードをまったく変更する必要はありません。

以下は、私が開いているデモページのサンプルです。それを見て、自分のプロジェクトに適用できるはずだと思います。

ビューモデル:

public class OrderViewModel
    {
        public int FavoriteMovieID { get; set; }
        public List<int> MovieIdsForMoviesILike { get; set; }

        public MovieCategories FavoriteMovieType { get; set; }
        public List<MovieCategories> MovieCategoriesILike { get; set; }

        public IEnumerable<SelectListItem> MoviesToSelectFrom 
        {
            get
            {
                return from x in OrderDetailsRepo.GetAllMovies()
                       select new SelectListItem {
                           Text = x.Title,
                           Value = x.ID.ToString(),
                           Selected = MovieIdsForMoviesILike.Contains(x.ID),
                       };
            }
        }

        public IEnumerable<SelectListItem> MovieCategoriesToSelectFrom
        {
            get
            {
                return from cat in Enum.GetValues(typeof(MovieCategories)).Cast<MovieCategories>()
                       select new SelectListItem {
                           Text = cat.ToString(),
                           Value = cat.ToString(),
                           Selected = MovieCategoriesILike.Contains(cat),
                       };
            }
        }

        public OrderViewModel()
        {
            // to ensure they are never NULL
            MovieIdsForMoviesILike = new List<int>();
            MovieCategoriesILike = new List<MovieCategories>();
        }
}

ドメイン モデル クラスとコレクションを提供するメソッド:

 public static class OrderDetailsRepo
        {
            public static List<Movie> GetAllMovies()
            {
                return new List<Movie> {
                    new Movie { ID = 0, Title = "Great Expectation" },
                    new Movie { ID = 1, Title = "Gone with the Wind" },
                    new Movie { ID = 2, Title = "Lion of Winter" },
                };
            }
        }

    public class Movie
        {
            public string Title { get; set; }
            public int ID { get; set; }
        }

    public enum MovieCategories
        {
            Horror,
            Drama,
            Comedy,
        }

そして超単純化されたビュー:

@model MVC3App.ViewModels.OrderViewModel
@using MVC3App.MVCHtmlHelpers @* RadioButtonList and CheckBoxList are defined in here *@

@{
    ViewBag.Title = "ViewPage1";
}

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <div class="editor-label">
        What's your favorite movie?
    </div>
    <div class="editor-field">
        @Html.RadioButtonListFor(model => model.FavoriteMovieID, Model.MoviesToSelectFrom)
        @Html.ValidationMessageFor(model => model.FavoriteMovieID)
    </div>

    <div class="editor-label">
        What movies do you like in general?
    </div>
    <div class="editor-field">
        @Html.CheckboxListFor(model => model.MovieIdsForMoviesILike, Model.MoviesToSelectFrom)
        @Html.ValidationMessageFor(model => model.MovieIdsForMoviesILike)
    </div>

    <div class="editor-label">
        What's your favorite Movie Genre?
    </div>
    <div class="editor-field">
        @Html.RadioButtonListFor(model => model.FavoriteMovieType, Model.MovieCategoriesToSelectFrom)
        @Html.ValidationMessageFor(model => model.FavoriteMovieType)
    </div>

    <div class="editor-label">
        What Movie Genres do you like in general?
    </div>
    <div class="editor-field">
        @Html.CheckboxListFor(model => model.MovieCategoriesILike, Model.MovieCategoriesToSelectFrom)
        @Html.ValidationMessageFor(model => model.MovieCategoriesILike)
    </div>

    <br /><br />
    <input type="submit" value="Save" />
}
于 2013-03-21T15:14:35.270 に答える