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); } }