如何在编辑操作中使用ViewModels?

时间:2013-04-15 18:15:11

标签: c# asp.net-mvc-4 view visual-studio-2012 ef-code-first

我想养成使用ViewModels的习惯。 过去我只在我的Create Actions中使用过它们,我从未想过如何在Edit Actions中使用它们。我用Domain Entities代替了。

假设我有以下内容:

使用Entity Framework Code First

域项目中的

POCO类

public class Person
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int PersonId { get; set; }

    public string Name { get; set; }        

    public string Website { get; set; }

    public DateTime? Created { get; set; }

    public DateTime? Updated { get; set; }
}

在我的数据项目中

抽象文件夹:

public interface IPersonRepository
{
    IQueryable<Person> People{ get; }  
    void SavePerson(Person person);     
}

具体文件夹:

EfDb类

public class EfDb : DbContext
{
    public EfDb() : base("DefaultConnection") {}

    public DbSet<Person> People{ get; set; }
}

EfPersonRepository类

#region Implementation of Person in IPersonRepository

public IQueryable<Person> People
{
    get { return _context.People; }
}

public void SavePerson(Persona person)
{
    if (person.PersonId == 0)
    {
        _context.People.Add(person);
    }
    else if (person.PersonId> 0)
    {
        var currentPerson = _context.People
            .Single(a => a.PersonId== person.PersonId);

        _context.Entry(currentPerson).CurrentValues.SetValues(person);
    }

    _context.SaveChanges();
}

#endregion
WebUI Porject ViewModels文件夹中的

PersonCreateViewModel

public class PersonCreateViewModel
{
    [Required]
    [Display(Name = "Name:")]
    public string Name { get; set; }        

    [Display(Name = "Website:")]
    public string Website { get; set; }
}

人物控制器和创建动作:

public class PersonController : Controller
{
    private readonly IPersonRepository _dataSource;

    public PersonController(IPersonRepository dataSource)
    {
        _dataSource = dataSource;
    }

    // GET: /Association/
    public ActionResult Index()
    {
        return View(_dataSource.Associations);
    }

    // GET: /Person/Details/5
    public ActionResult Details(int id)
    {
        return View();
    }

    // GET: /Person/Create
    [HttpGet]
    public ActionResult Create()
    {
       return View();
    }

    // POST: /Person/Create
    [HttpPost]
    public ActionResult Create(PersonCreateViewModel model)
    {
        if (ModelState.IsValid)
        {
            try
            {
                var Person = new Person
                      {
                          Name = Model.Name,
                          Website = model.Website,
                          Created = DateTime.UtcNow,
                          Updated = DateTime.UtcNow
                      };

                _dataSource.SavePerson(person);
                return RedirectToAction("Index", "Home");
            }
            catch
            {
                ModelState.AddModelError("", "Unable to save changes. ");
            }
        }

        return View(model);
    }
 }

现在除非我弄错了,否则我希望我的PersonEditViewlModel看起来与PersonCreateViewlModel完全一样。但我无法弄清楚如何在我的Edit操作中使用它,前提是我还必须像SavePerson(Person person)行动中那样拨打Create

注意:请不要AutoMapperValueInjecter建议。

这是怎么做到的?

1 个答案:

答案 0 :(得分:2)

除了你需要记录ID之外,它就像创建

[HttpGet]
public ActionResult Edit(int id)
{
    var personVm = _dataSource.People.Single(p => p.PersonId == id)
        .Select(e => new PersonEditViewModel {
                    e.PersonId = p.PersonId,
                    e.Name = p.Name,
                    e.Website = p.Website
                    ...
                });
    return View(personVm);
}

[HttpPost]
public ActionResult Edit(PersonEditViewModel model)
{
    if (ModelState.IsValid)
    {
        var person = _dataSource.People.Single(p => p.PersonId == model.PersonId);
        person.Name = model.Name;
        person.Website = model.Website;
        ...
        _dataSource.EditPerson(person);
        return RedirectToAction("Index", "Home");
    }
    return View(model);
}

修改 因此,您不要对编辑执行其他查询

public void EditPerson(Person person)
{
    _context.Entry(person).State = EntityState.Modified;
    _context.SaveChanges();
}