Есть ли способ очистить этот код контроллера? - PullRequest
0 голосов
/ 21 августа 2011

Большая часть кода, который я вижу онлайн на 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 *, чтобы добавить аннотации данных для используемых представлений.Может быть, это неправильная идея?

Ответы [ 2 ]

2 голосов
/ 21 августа 2011

У меня много предложений.Для начала, прочитайте о Dependancy Injection и Inversion of Control (DI и IoC).Они сделают все эти эталонные экземпляры объектов ушедшими в прошлое.

Затем преобразуем эти построители списков для каждого в выражения Linq.Гораздо лаконичнее и, скорее, быстрее.

Затем, в вашем пост-обработчике, снова сделайте там то же самое.Кроме того, познакомьтесь с AutoMapper, который автоматически сопоставит ваше представление с классами доменов и сделает вашу жизнь намного проще.

Если вы это сделаете, ваш код будет сокращен в 2 раза, а может даже и в 3 раза.

РЕДАКТИРОВАТЬ:

Пример запроса linq, потому что я действительно не знаю определения ваших объектов ... будет выглядеть примерно так:

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

Обратите внимание, как выне нужно создавать новый список, так как он возвращается методом ToList ().Он также использует проекцию для выбора элементов в новом SelectListItem.

По сути, вы можете написать свой метод следующим образом, используя Dependancy Injection, Linq и AutoMapper (он выглядит длиннее, потому что мне пришлось разбивать строки несколько разчтобы соответствовать маленькому просмотру ТАК):

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 голос
/ 21 августа 2011

ваша идея хороша. Потому что не рекомендуется использовать классы сущностей в качестве моделей представления на уровне MVC, потому что это создаст тесную связь между вашей логикой представления и персистентности.

Для очистки вашего кода вы можете использовать AutoMapper (http://automapper.codeplex.com/), чтобы отобразить ваши классы сущностей для простого просмотра модели без написания слишком большого количества кодов. http://jasona.wordpress.com/2010/02/05/getting-started-with-automapper/ вот хорошая статья для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...