MVC ViewModel示例 [英] MVC ViewModel example

查看:75
本文介绍了MVC ViewModel示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been doing tutorials and trying to learn best practice when it comes to MVC development. The design I'm using below comes from Pro ASP.Net MVC5 by Apress/Adam Freeman. So far, everything is coming along good...but I still have not completely come to grip on working with Controllers. Yes, I understand the concept of Controllers, but still struggle when it comes to post and get methods. Here is the flow of my sample MVC application:

我的应用程序.域项目

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

I have a user table in the database and reference it with 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

Next, I have an interface and it is located Abstract/IUsersRepository.cs

using System;
using System.Collections.Generic;
using app.Domain.Entities;

namespace app.Domain.Abstract
{
public interface IUsersRepository
{
    IEnumerable<Users> Users { get; }
}
}

继续前进,现在我将实体填充为Concrete/EFUsersRepository.cs

Moving along, now I fill my entities 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> Users
    {
        get { return context.Users; }
    }
}
}

此外,教科书使用的是我理解的Ninject,并且所有内容均已正确绑定.除非有人问我,否则我不会发布该代码.

Also, the textbook is using Ninject which I understand and everything is bound correctly. I won't post that code unless someone asks me to.

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

Here is my app.WebUI solution:

教科书引导我完成一个ViewModel的创建.这对我来说变得有些模糊. ViewModel是获取实体的附加渠道吗?我应该始终创建ViewModel来进行SELECT,UPDATE,INSERT,DELETE数据(Models/UsersViewModel.cs),而不是引用Models本身吗?

The textbook walks me through creating a ViewModel. This is where things get a little fuzzy for me. Is the ViewModel an additional channel to get the entities? Instead of referencing the Models themselves, should I always create ViewModels to SELECT, UPDATE, INSERT, DELETE data (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> Users { get; set; }
}
}

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

The scenario is for the user to type in an email, then the Controller checks the database for the email. If it exist, then redirect to the 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();
    }
}
}

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

And here is my View (Home/Index.cshtml):

@model app.WebUI.Models.UsersViewModel

@{
    ViewBag.Title = "Home Page";
    Layout = "~/Views/Shared/_LayoutNoMenu.cshtml";
}


@foreach (var p in Model.Users)
{ 
<div class="container">
@using (Html.BeginForm("About", "Home", FormMethod.Get, new { @class = "begin-form" }))
{
    <h1>Welcome</h1>
    <div class="required-field-block">
    <textarea rows="1" class="form-control" placeholder="Email" id="filter"></textarea>
    </div>
    <button class="btn btn-primary" type="submit">Login</button>
}
</div>
}

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

Any advice on how to correctly use a ViewModel?

推荐答案

2014年6月,我在学习MVC时问了这个问题.从今天开始,我了解了视图模型的概念.希望这将对另一位MVC初学者有所帮助:

In June 2014, I asked this question while learning MVC. As of today, I understand the concept of a viewmodel. Hopefully this will help another MVC beginner:

我代表数据库表的模型:

My model which represents the database table:

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<Property> Properties { get; set; }
    public virtual DistrictOffice DistrictOffice { get; set; }
    public virtual IList<Recipient> Recipients { get; set; }
}

有两种一对多关系和一对一关系.实体框架和依赖注入. (这对于解释视图模型不是必需的.)

There are two one-to-many relationships and a one-to-one relationship. Entity framework and dependency injection. (This is not necessary for viewmodel explaination.)

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

First, I create a viewmodel for temporary storage to pass from controller to the view. 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,但是我的视图模型是UserName.您不需要将将不使用的数据(例如整个模型)传递给View.此示例仅需要County模型的三个部分.

You have the flexibility to use different names and datatypes than your model. For example, my database column is UserID, my model is UserID, but my viewmodel is UserName. You don't need to pass data to the View that will not be used (e.g., the entire model.) This example just needs three parts of the County model.

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

Within my controller, I declare my viewmodel:

我需要数据:

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

 <div>@Model.CountyName</div>
 @Html.HiddenFor(model => model.CountyId)

 <div>
 @Html.TextBoxFor(model => model.CountyName, new { @class = "form-control" })

下面是一个简单的示例,该示例使用ViewModel传递数据,并通过Entity Framework使用对数据库的服务调用:

Here is a simple example of passing data using a viewmodel and using service calls to the database with 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

Example 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<County> 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<County> ListOfCounties();
    void Delete(County county);
    IEnumerable<State> ListOfStates();
    void Add(County county);
    County SearchByName(string county);
}


public partial class CountyService : ICountyService
{
    private readonly ICountyRepository _countyRepository;

    public CountyService(ICountyRepository countryRepository)
    {
        _countyRepository = countryRepository;
    }

    /// <summary>
    /// Returns a county
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public County Get(int id)
    {
        return _countyRepository.Get(id);
    }

    /// <summary>
    /// Returns a county by County Id
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public County GetByCountyID(int id)
    {
        return _countyRepository.GetByMedicaidCountyID(id);
    }

    /// <summary>
    /// Returns all counties
    /// </summary>
    /// <returns></returns>
    public IEnumerable<County> ListOfCounties()
    {
        return _countyRepository.ListOfCounties();
    }

    /// <summary>
    /// Deletes a county
    /// </summary>
    /// <param name="county"></param>
    public void Delete(County county)
    {
        _countyRepository.Delete(county);
    }

    /// <summary>
    /// Return a static list of all U.S. states
    /// </summary>
    /// <returns></returns>
    public IEnumerable<State> ListOfStates()
    {
        var states = ServiceHelpers.CreateStateList(); 
        return states.ToList();
    }

    /// <summary>
    /// Add a county
    /// </summary>
    /// <param name="county"></param>
    public void Add(County county)
    {
        county.CreatedUserID = System.Web.HttpContext.Current.User.Identity.Name;
        county.CreatedDate = DateTime.Now;
        _countyRepository.Add(county);
    }

    /// <summary>
    /// Return a county by searching it's name
    /// </summary>
    /// <param name="county"></param>
    /// <returns></returns>
    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<County> 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);
    }
}

这篇关于MVC ViewModel示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆