Created
April 13, 2012 19:45
-
-
Save PaulStovell/2379583 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@model EditUserModel | |
@using (Html.BeginForm()) | |
{ | |
<div> | |
@Html.HiddenFor(m => m.Id) | |
@Html.TextBoxFor(m => m.FirstName) | |
@Html.TextBoxFor(m => m.LastName) | |
@Html.DropDownListFor(m => m.CountryId, Model.Countries) | |
<input type="submit" /> | |
</div> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EditUserModel | |
{ | |
public string Id { get; set; } | |
public string FirstName { get; set; } | |
public string LastName { get; set; } | |
public string CountryId { get; set; } | |
public ICollection<SelectListItem> Countries { get; set; } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EditUserModelBuilder : IModelBuilder<EditUserModel, User> | |
{ | |
readonly ISession session; | |
public EditUserModelBuilder(ISession session) | |
{ | |
this.session = session; | |
} | |
public EditUserModel CreateFrom(User user) | |
{ | |
var model = new EditUserModel(); | |
model.Id = user.FirstName; | |
model.FirstName = user.FirstName; | |
model.LastName = user.LastName; | |
model.Country = user.Country.Id; | |
model.Countries = GetCountries(); | |
return model; | |
} | |
public EditUserModel Rebuild(EditUserModel model) | |
{ | |
model.Countries = GetCountries(); | |
return model; | |
} | |
public User ApplyChanges(EditUserModel model) | |
{ | |
var user = string.IsNullOrEmpty(model.Id) ? new User() : session.Find<User>(model.Id); | |
session.Store(user); | |
user.FirstName = model.FirstName; | |
user.LastName = model.LastName; | |
user.Country = session.Find<Country>(model.CountryId); | |
return user; | |
} | |
ICollection<SelectListItem> GetCountries() | |
{ | |
var countries = session.FindAll<Country>(); | |
return countries.Select(c => new SelectListItem { Value = c.Id, Text = c.Name }).ToList(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IModelBuilder<TViewModel, TEntity> | |
{ | |
TViewModel CreateFrom(TEntity entity); | |
TViewModel Rebuild(TViewModel model); | |
TEntity ApplyChanges(TViewModel viewModel); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UserController : Controller | |
{ | |
IModelBuilder<EditUserModel, User> builder = new EditUserModelBuilder(); | |
public ActionResult Edit(string id) | |
{ | |
var user = session.Find<User>(id) ?? new User(); | |
return View(model, builder.CreateFrom(user)); | |
} | |
[HttpPost] | |
public ActionResult Edit(EditUserModel model) | |
{ | |
if (!ModelState.IsValid) | |
{ | |
return View(builder.Rebuild(model); | |
} | |
builder.ApplyChanges(model); | |
session.SaveChanges(); | |
return RedirectToAction("Index"); | |
} | |
} |
Agree that this was a tidier approach. Just wanted to mention, there's a copy/paste bug in Edit.cshtml line 8.
Thanks Peter, I've fixed the bug
Looks great :)
There is another mistake in your IModelBuilder.cs line 4. It should be TEditUserModel
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This approach is based on this StackOverflow answer: http://stackoverflow.com/a/2775656/57132
I like it because the controller is much simpler, and the save code is more easily reused. In the real world I'd inject the model builder so testing would be easier too. I like that the messiness of re-filling the countries list for example is hidden inside the builder.