C# 如何构造视图模型-ASP.NET MVC

C# 如何构造视图模型-ASP.NET MVC,c#,asp.net-mvc,asp.net-mvc-3,model-view-controller,viewmodel,C#,Asp.net Mvc,Asp.net Mvc 3,Model View Controller,Viewmodel,我想使用ASP.NET MVC 3.0创建一个调查。有些问题会有单选按钮和一些复选框。我想知道视图端和视图模型的正确语法。 我想将答案的选项存储在集合中。IEnumerable是一个好的集合吗?下面是我的一些ViewModel代码 [DisplayName("Country")] [Required(ErrorMessage = "Country is required.")] public string Country { get; set; } public

我想使用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();
    }      
[DisplayName(“国家”)]
[必需(ErrorMessage=“国家是必需的。”)]
公共字符串国家{get;set;}
公共IEnumerable国家{get;set;}
[显示名称(“业务”)]
[必需(ErrorMessage=“请选择一个业务单位。”)]
公共字符串BusinessUnit{get;set;}
公共IEnumerable业务{get;set;}
公共布尔ToGetFit{get;set;}
公共布尔值挑战自己{get;set;}
公共布尔TobeHealther{get;set;}
公共布尔ChallengeOther{get;set;}
公共字符串OtherString{get;set;}
公共void build()
{
var myService=newsurveyservice(newsurveyrepository());
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>
你住在哪个国家
模式。国家,“加拿大”,正确)%>厄瓜多尔
模式。国家,“智利”,正确)%>加纳
模式。国家,“意大利”,正确)%>尼日利亚
型号。国家,“德国”,正确)%>罗马尼亚
  • 您在哪个业务部门工作?
    model.BusinessUnit,“Pharmaceuticals”,true)%>Pharmaceuticals
    model.BusinessUnit,“力学”,正确)%>疫苗
    model.BusinessUnit,“研发”)%>研发
    model.BusinessUnit,“Distribution”,true)%>Distribution
  • 你为什么想参加这项训练
    model.ToGetFit)%>以保持良好状态
    model.To挑战自己)%>挑战自己
    model.ToBeHealthier)%>更健康
    型号.ChallengeOther)%>其他 model.OtherString)%%>
  • 我是ASP.NET MVC新手,但我对ASP.NET和MVC模式都有经验。 我希望尽可能强调关注点的分离

    我的控制器类调用我的构建方法。我有一个服务类,它获取一个存储库对象,该对象将从我的模型/数据库中获取信息


    !!我希望我的单选按钮可以从数据库中动态获取。然后,如果用户已经从上一个会话中选择了某个内容,我希望在我的ViewModel中找到该内容,并且在加载页面时已经选择了该内容。

    我看到的上述方法的问题是,您的单选按钮和复选框是在视图中定义的。如果它们来自数据库、枚举或其他内容,这显然是个问题。您应该做的是添加一个ViewModel属性,该属性表示给定收音机/复选框组的所有可能选项,以及一个保存用户为该组选择的选定值的属性

    首先,检查“”和“”的这些GREAThelper方法。将它们复制到您的项目中

    接下来,您需要在ViewModel上将集合公开为
    IEnumerable
    。以下是radiolist/checkboxlist/dropdown元素的可能选项

    然后,在ViewModel中,需要为单个选定选项(从下拉列表或单选按钮列表)或选定选项的集合(从复选框列表)定义一个道具。可以从项的数据库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>();
            }
    }
    
    公共类OrderViewModel
    {
    public int-FavoriteMovieID{get;set;}
    公共列表MovieIDsformovieSike{get;set;}
    公共电影类别FavoriteMovieType{get;set;}
    公共列表moviecategorieslike{get;set;}
    可供选择的公映电影
    {
    得到
    {
    从OrderDetailsEPO.GetAllMovies()中的x返回
    选择新的SelectListItem{
    Text=x.标题,
    Value=x.ID.ToString(),
    选定=MovieIdsForMoviesILike.Contains(x.ID),
    };
    }
    }
    可供选择的公共i可数电影类别
    {
    得到
    {
    在Enum.GetValues(typeof(MovieCategories)).Cast()中从cat返回
    选择新的SelectListItem{
    Text=cat.ToString(),
    值=cat.ToString(),
    选定=MovieCategoriesILike.Contains(cat),
    };
    }
    }
    public OrderViewModel()
    {
    //以确保它们从不为空
    MovieIdsForMoviesILike=新列表();
    MovieCategoriesILike=新列表();
    }
    }
    
    域模型类和提供集合的方法:

     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" />
    }
    
    public静态类OrderDetailsRepo
    {
    公共静态列表GetAllMovies()
    {
    返回新列表{
    新电影{ID=0,Title=“伟大的期望”},
    新电影{ID=1,Title=“乱世佳人”},
    新电影{ID