2011-08-21 2 views
0

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

나는 ORM으로 Entity Framework를 사용하고 있으며 자동으로 User 클래스를 생성합니다. 그러나 User * 모델 * 클래스를 만들었으므로 사용할 뷰의 데이터 주석을 추가 할 수있었습니다. 어쩌면 이것이 잘못된 생각일까요?

+0

미스터 맨의 Linq 제안에 대한 정보가 있습니까? –

답변

2

많은 제안이 있습니다. 처음에는 Dependancy Injection과 Inversion of Control (DI 및 IoC)에 대해 읽어보십시오. 보일러 플레이트 객체 인스턴스화를 과거의 모든 것으로 만들 것입니다.

다음으로, for each each list builder를 Linq 표현식으로 변환하십시오. 훨씬 더 간결하고 가능성이 더 빠릅니다.

그런 다음 게시물 처리기에서 다시 동일한 작업을 수행하십시오. 또한, AutoMapper에 대해 알아보십시오. AutoMapper는 자동으로보기를 도메인 클래스에 매핑하고 일상 생활을 훨씬 쉽게 만듭니다.

의 예 LINQ 쿼리, 난 정말 당신의 객체의 정의를 모르기 때문에 : 당신이 그 일을했다면

, 코드는 어쩌면 3.

편집, 배 감소 될 것이다. .. 다음과 같이 보일 것이다 : 즉 ToList() 메소드에 의해 반환 이후 당신이 최대 새로운 새로운 목록에없는 방법

model.Cities = cityRepo.FindAllCities().Select(city => new SelectListItem() { 
     Text = city.Name, Value = city.CityId.ToString()}).ToList(); 

공지 사항. 또한 새로운 SelectListItem으로 항목을 선택하기 위해 투영법을 사용합니다.

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

AutoMapper는 좋은 소리가 들린다. 나는 그것에 대해 조사 할 것이다. Linq 표현에 관해서. 몇 가지 예제 코드를 보여줄 수 있습니까? SelectListItem으로'Select()'를 사용하면됩니까? –

+0

다음과 같은 목록을 매핑 할 수 있습니다. IList cityViewModels Mapper.Map , IList > (도시); –

+0

@Sergio - 업데이트 –

1
:

기본적으로, 당신은 의존성 주입은, Linq에, 그리고 AutoMapper (나는 작은 볼을 SO의 수 있습니다에 맞게 라인을 여러 번 중단했기 때문에 더 오래 보이는)를 사용하여,이 같이 당신의 방법을 쓸 수있다

아이디어가 좋습니다. 프레젠테이션과 퍼시스턴스 로직 간의 긴밀한 결합을 만들 것이므로 MVC 레이어의 뷰 모델로 엔티티 클래스를 사용하는 것은 좋지 않습니다.

yuor 코드를 정리하려면 AutoMapper (http://automapper.codeplex.com/)를 사용하여 너무 많은 코드를 작성하지 않고도 엔터티 클래스를 모델보기 쉽게 매핑 할 수 있습니다. 여기 http://jasona.wordpress.com/2010/02/05/getting-started-with-automapper/은 좋은 기사입니다.

관련 문제