我在MVC3上看到的大多数代码在控制器中只有很少的代码,但我似乎无法弄清楚如何使这些代码更加简化。
也许如果你看看它,你可以建议改进。如果您需要查看我的UserModel类,请告诉我。
以下是帐户控制器的代码。
namespace WebUI.Controllers
{
public class AccountController : Controller
{
public ActionResult Register()
{
UserModel model = new UserModel();
EFCityRepository cityRepo = new EFCityRepository();
model.Cities = new List<SelectListItem>();
foreach (var city in cityRepo.FindAllCities()) {
model.Cities.Add(new SelectListItem { Text = city.Name, Value = city.CityId.ToString(), Selected = true });
}
EFGenderRepository genderRepo = new EFGenderRepository();
model.Genders = new List<SelectListItem>();
foreach (var gender in genderRepo.FindAllGenders()) {
model.Genders.Add(new SelectListItem { Text = gender.Name, Value = gender.GenderId.ToString(), Selected = true });
}
return View(model);
}
[HttpPost]
public ActionResult Register(UserModel model)
{
EFCityRepository cityRepo = new EFCityRepository();
model.Cities = new List<SelectListItem>();
foreach (var city in cityRepo.FindAllCities())
{
model.Cities.Add(new SelectListItem { Text = city.Name, Value = city.CityId.ToString(), Selected = true });
}
EFGenderRepository genderRepo = new EFGenderRepository();
model.Genders = new List<SelectListItem>();
foreach (var gender in genderRepo.FindAllGenders())
{
model.Genders.Add(new SelectListItem { Text = gender.Name, Value = gender.GenderId.ToString(), Selected = true });
}
if (ModelState.IsValid)
{
Domain.User user = new Domain.User();
user.UserRoleId = 1;
user.Nickname = model.Nickname;
user.Name = model.Name;
user.Lastname = model.Lastname;
user.GenderId = model.GenderId;
user.Address = model.Address;
user.Email = model.Email;
user.Telephone = model.Telephone;
user.MobilePhone = model.MobilePhone;
user.Carnet = model.Carnet;
user.DateOfBirth = model.DateOfBirth;
user.DateOfRegistry = DateTime.Now;
user.LastDateLogin = DateTime.Now;
user.IsActive = false;
user.LanceCreditBalance = 5;
user.LancesSpent = 0;
user.Login = model.Login;
user.Password = model.Password;
user.EmailVerificationCode = "TempTokenString";
user.CityId = model.CityId;
EFUserRepository repo = new EFUserRepository();
var result = repo.CreateUser(user);
if (result == UserCreationResults.Ok)
{
FormsAuthentication.SetAuthCookie(model.Nickname, false /* createPersistentCookie */);
return RedirectToAction("Index", "Home");
}
else
{
switch (result)
{
case UserCreationResults.UsernameExists:
ModelState.AddModelError("", "El nombre de usuario ya esta siendo utilizado.");
break;
case UserCreationResults.EmailAlreadyExists:
ModelState.AddModelError("", "Ese correo ya esta en uso.");
break;
case UserCreationResults.NicknameAlreadyExists:
ModelState.AddModelError("", "El nickname ya esta siendo utilizado.");
break;
case UserCreationResults.UnknownError:
ModelState.AddModelError("", "Algo durante el registro. Por favor intente de nuevo.");
break;
default:
break;
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
}
我正在使用Entity Framework作为我的ORM,它会自动为我生成一个User类。但是,我创建了一个User * Model *类,因此我可以为要使用的视图添加数据注释。也许这是错误的想法?
答案 0 :(得分:2)
我有很多建议。首先,阅读有关依赖性注入和控制反转(DI和IoC)的信息。他们将使所有样板对象实例化成为过去。
接下来,将每个列表构建器转换为Linq表达式。更简洁,更快可能更快。
然后,在你的帖子处理程序中,再次执行相同的操作。此外,了解AutoMapper,它会自动将您的视图映射到域类,让您的生活更轻松。
如果你做了这些事情,你的代码将减少2倍,甚至可能减少3倍。
编辑:
示例linq查询,因为我真的不知道对象的定义......看起来像这样:
model.Cities = cityRepo.FindAllCities().Select(city => new SelectListItem() {
Text = city.Name, Value = city.CityId.ToString()}).ToList();
注意你不必新建一个新的List,因为它是由ToList()方法返回的。它还使用投影将项目选择为新的SelectListItem。
基本上,您可以使用Dependancy Injection,Linq和AutoMapper编写这样的方法(它看起来更长,因为我必须多次断行以适应小视图的SO):
namespace WebUI.Controllers
{
public class AccountController : Controller
{
private IGenderRepository _genderRepo;
private ICityrRepository _cityRepo;
private IUserRepository _userRepo;
public AccountController(IGenderRepository gr, ICityRepository cr,
IUserRepository ur)
{
_genderRepo = gr;
_cityRepo = cr;
_userRepo = ur;
}
public ActionResult Register()
{
UserModel model = new UserModel();
// Selected property is ignored by MVC on SelectListItems
model.Cities = _cityRepo.FindAllCities().Select(city =>
new SelectListItem() { Text = city.Name,
Value = city.CityId.ToString()}).ToList();
model.Genders = _genderRepo.FindAllGenders().Select(gender =>
new SelectListItem() { Text = gender.Name,
Value = gender.GenderId.ToString()}).ToList();
return View(model);
}
[HttpPost]
public ActionResult Register(UserModel model)
{
model.Cities = _cityRepo.FindAllCities().Select(city =>
new SelectListItem() { Text = city.Name,
Value = city.CityId.ToString()}).ToList();
model.Genders = _genderRepo.FindAllGenders().Select(gender =>
new SelectListItem() { Text = gender.Name,
Value = gender.GenderId.ToString()}).ToList();
if (ModelState.IsValid)
{
Domain.User user = Mapper.Map<Domain.User, Model>(model)
var result = _userRepo.CreateUser(user);
if (result == UserCreationResults.Ok) {
FormsAuthentication.SetAuthCookie(model.Nickname, false);
return RedirectToAction("Index", "Home");
} else {
ModelState.AddModelError("", GetErrorString(result));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
}
答案 1 :(得分:1)
你的想法很好。因为将实体类作为MVC层中的视图模型并不是一个好习惯,因为它会在表示和持久性逻辑之间建立紧密耦合。
要清理yuor代码,您可以使用AutoMapper(http://automapper.codeplex.com/)将实体类映射到查看模型,而无需编写太多代码。 http://jasona.wordpress.com/2010/02/05/getting-started-with-automapper/这是一篇很好的文章。