MVC ViewModel示例

在进行MVC开发时,我一直在做教程并尝试学习最佳实践。 我在下面使用的设计来自Apress / Adam Freeman的Pro ASP.Net MVC5。 到目前为止,一切都很顺利……但我还没有完全掌握与控制器的合作。 是的,我理解控制器的概念,但在发布和获取方法时仍然很难。 以下是我的示例MVC应用程序的流程:

我的app.Domain项目

我在数据库中有一个用户表,并使用Entities / Users.cs引用它

using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace app.Domain.Entities { public class Users { [Key] public int UserID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string City { get; set; } public string State { get; set; } public DateTime CreateDate { get; set; } public DateTime LastLogin { get; set; } } } 

接下来,我有一个接口,它位于Abstract / IUsersRepository.cs

 using System; using System.Collections.Generic; using app.Domain.Entities; namespace app.Domain.Abstract { public interface IUsersRepository { IEnumerable Users { get; } } } 

继续前进,现在我填写我的实体Concrete / EFUsersRepository.cs

 using System; using System.Collections.Generic; using app.Domain.Entities; using app.Domain.Abstract; namespace app.Domain.Concrete { public class EFUsersRepository : IUsersRepository { private EFDbContext context = new EFDbContext(); public IEnumerable Users { get { return context.Users; } } } } 

此外,教科书正在使用我理解的Ninject,并且一切都正确绑定。 除非有人问我,否则我不会发布该代码。

这是我的app.WebUI解决方案:

教科书指导我创建一个ViewModel。 这对我来说有点模糊。 ViewModel是获取实体的额外渠道吗? 我应该始终将ViewModel创建为SELECT,UPDATE,INSERT,DELETE数据(Models / UsersViewModel.cs),而不是引用模型本身吗?

 using System; using System.Collections.Generic; using app.Domain.Entities; namespace app.WebUI.Models { public class UsersViewModel { //public string FirstName { get; set; } //public string LastName { get; set; } //public string Email { get; set; } //public string City { get; set; } //public string State { get; set; } public IEnumerable Users { get; set; } } } 

该方案是用户键入电子邮件,然后Controller检查数据库中的电子邮件。 如果存在,则重定向到About View(Controllers / HomeController.cs)。

 using System.Linq; using System.Web.Mvc; using app.Domain.Abstract; using app.WebUI.Models; namespace app.Controllers { public class HomeController : Controller { private IUsersRepository repository; public HomeController(IUsersRepository usersRepository) { this.repository = usersRepository; } [HttpGet] public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index() { UsersViewModel userViewModel = new UsersViewModel() { Users = repository.Users .Where(p => p.Email == "LearningMVC5@gmail.com") }; return View("About", userViewModel); } public ActionResult About() { ViewBag.Message = "Your application description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } } 

这是我的View(Home / Index.cshtml):

 @model app.WebUI.Models.UsersViewModel @{ ViewBag.Title = "Home Page"; Layout = "~/Views/Shared/_LayoutNoMenu.cshtml"; } @foreach (var p in Model.Users) { 
@using (Html.BeginForm("About", "Home", FormMethod.Get, new { @class = "begin-form" })) {

Welcome

}
}

有关如何正确使用ViewModel的任何建议?

2014年6月,我在学习MVC时问了这个问题。 截至今天,我理解了viewmodel的概念。 希望这将有助于另一个MVC初学者:

我的模型代表数据库表:

 public partial class County : Entity { public int CountyID { get; set; } public string CountyName { get; set; } public string UserID { get; set; } public DateTime? CreatedDate { get; set; } public string ModifiedUserID { get; set; } public DateTime? ModifiedDate { get; set; } public virtual IList Properties { get; set; } public virtual DistrictOffice DistrictOffice { get; set; } public virtual IList Recipients { get; set; } } 

有两个一对多的关系和一对一的关系。 entity framework和dependency injection。 (这对于viewmodel解释不是必需的。)

首先,我创建一个用于临时存储的视图模型,以便从控制器传递到视图。 CountyViewModel.cs

 public class CountyViewModel { [HiddenInput] public int? CountyId { get; set; } [DisplayName("County Name")] [StringLength(25)] public string CountyName { get; set; } [DisplayName("Username")] [StringLength(255)] public string Username{ get; set; } } 

您可以灵活地使用与模型不同的名称和数据类型。 例如,我的数据库列是UserID,我的模型是UserID,但我的viewmodel是UserName。 而且您不需要将数据传递给不会使用的视图(整个模型)。这个示例只需要County模型的三个部分。

在我的控制器中,我声明了我的视图模型:

我需要数据:

 var county = _countyService.Get(countyId); 

下一个,

 CountyViewModel countyViewModel = new CountyViewModel(); countyViewModel.CountyId = county.CountyID; countyViewModel.CountyName = county.CountyName; countyViewModel.UserName = county.UserID; 

您也可以这样声明:

 CountyViewModel countyViewModel = new CountyViewModel { CountyId = county.CountyID, CountyName = county.CountyName, UserName = county.UserID }; 

现在是传递视图的时候了:

 return View(countyViewModel); 

在视图内:

 @model Project.Web.ViewModels.CountyViewModel @{ Layout = "~/Views/Shared/_Layout.cshtml"; } 
@Model.CountyName
@Html.HiddenFor(model => model.CountyId)
@Html.TextBoxFor(model => model.CountyName, new { @class = "form-control" })

下面是一个使用viewmodel传递数据并使用Entity Framework对数据库进行服务调用的简单示例:

示例控制器

 public class PropertyController : Controller { private readonly ICountyService _countyService; public PropertyController(ICountyService countyService) : base() { _countyService = countyService; } [HttpGet] public ActionResult NewProperty() { using (UnitOfWorkManager.NewUnitOfWork()) { ListAllCountiesViewModel listAllCountyViewModel = new ListAllCountiesViewModel() { ListAllCounty = _countyService.ListOfCounties().ToList() }; PropertyViewModel viewModel = new PropertyViewModel() { _listAllCountyViewModel = listAllCountyViewModel, _countyViewModel = new CountyViewModel(), }; return View(viewModel); } } } 

示例 ViewModels

 public class CountyViewModel { [HiddenInput] public int? CountyId { get; set; } [DisplayName("County Name")] [StringLength(25)] public string CountyName { get; set; } [DisplayName("County URL")] [StringLength(255)] public string URL { get; set; } } public class ListAllCountiesViewModel { public string CountyName { get; set; } public IEnumerable ListAllCounty { get; set; } } public class PropertyViewModel { public ListAllCountiesViewModel _listAllCountyViewModel { get; set; } public CountyViewModel _countyViewModel { get; set; } } 

示例服务层

 public partial interface ICountyService { County Get(int id); County GetByCompanyCountyID(int id); IEnumerable ListOfCounties(); void Delete(County county); IEnumerable ListOfStates(); void Add(County county); County SearchByName(string county); } public partial class CountyService : ICountyService { private readonly ICountyRepository _countyRepository; public CountyService(ICountyRepository countryRepository) { _countyRepository = countryRepository; } ///  /// Returns a county ///  ///  ///  public County Get(int id) { return _countyRepository.Get(id); } ///  /// Returns a county by County Id ///  ///  ///  public County GetByCountyID(int id) { return _countyRepository.GetByMedicaidCountyID(id); } ///  /// Returns all counties ///  ///  public IEnumerable ListOfCounties() { return _countyRepository.ListOfCounties(); } ///  /// Deletes a county ///  ///  public void Delete(County county) { _countyRepository.Delete(county); } ///  /// Return a static list of all US states ///  ///  public IEnumerable ListOfStates() { var states = ServiceHelpers.CreateStateList(); return states.ToList(); } ///  /// Add a county ///  ///  public void Add(County county) { county.CreatedUserID = System.Web.HttpContext.Current.User.Identity.Name; county.CreatedDate = DateTime.Now; _countyRepository.Add(county); } ///  /// Return a county by searching it's name ///  ///  ///  public County SearchByName(string county) { return _countyRepository.SearchByName(county); } } 

示例存储库层

 public partial class CountyRepository : ICountyRepository { private readonly Context _context; public CountyRepository(IContext context) { _context = context as Context; } public County Get(int id) { return _context.County.FirstOrDefault(x => x.CountyID == id); } public County GetByCompanyCountyID(int id) { return _context.County.FirstOrDefault(x => x.CountyID == id); } public IList ListOfCounties() { return _context.County.ToList() .OrderBy(x => x.CountyName) .ToList(); } public void Delete(County county) { _context.County.Remove(county); } public County Add(County county) { _context.County.Add(county); return county; } public County SearchByName(string county) { return _context.County.FirstOrDefault(x => x.CountyName == county); } }