2010-05-05 3 views
0

У меня есть сложный объект пользователь:ASP.Net MVC 2 является возможностью получить тот же экземпляр модели (с небольшими изменениями) в HttpPost метод, который был принят в HttpGet

public class User : BaseEntity 
    {   
    public virtual Taxi Taxi { get; set; } --> That is why i call it "complex" 
    public virtual string Login { get; set; }   
    public virtual string Password { get; set; } 
    } 

где такси является parent of User (Taxi has-many Users):

public class Taxi : BaseEntity 
    { 
     public virtual string Name { get; set; } 
     public virtual string ClientIp { get; set; } 
    } 

BaseEntity состоит из открытого виртуального int Id {get; частный набор; }

Проблема возникает при попытке изменить User

[Authorize] 
    public ActionResult ChangeAccountInfo() 
    { 
     var user = UserRepository.GetUser(User.Identity.Name); 
     return View(user); 
    } 

Мой ChangeAccountInfo.aspx

 <fieldset> 
     <legend>Fields</legend> 
     <% %> 
     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Login) %> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextBoxFor(model => model.Login) %> 
      <%: Html.ValidationMessageFor(model => model.Login) %>  
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Password) %> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextBoxFor(model => model.Password) %> 
      <%: Html.ValidationMessageFor(model => model.Password) %> 
     </div> 

     <div class="editor-field"> 
      <%: Html.HiddenFor(model => model.Taxi.Name)%>    
     </div>  

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
     </fieldset> 

сообщение изменения:

[Authorize] 
    [HttpPost] 
    public ActionResult ChangeAccountInfo(User model) 
    { 
     if (ModelState.IsValid) 
     { 
      UserRepository.UpdateUser(model); 

      return RedirectToAction("ChangeAccountInfoSuccess", "Account"); 
     } 

     return View(model); 
    } 

Но, то (модель пользователя) параметр имеет User.Id == 0 -> Пользовательский объект имел 5 перед редактированием
User.Login == "мой новый Логин"
User.Password == "мой новый пароль"
User.Taxi.Id == 0 -> User.Taxi объект имел 3 перед тем редактировать
User.Taxi. имя == «старое скрытое название»
User.Taxi.ClientIp == NULL -> объект пользователя было 192.168.0.1 до редактирования

Q: можно не отметить все поля объекта (который должен быть в моем UpdateUser) с тегом «скрытый», но все еще не изменился в моем методе HttpPost? , например. не User.Taxi.ClientIp = null, но User.Taxi.ClientIp = 192.168.0.1

Я использую nhibernate, если это имеет значение.

+2

Модель домена! = Просмотр модели. – Paco

+0

@Paco - И это важно, потому что ??? Ни в коем случае MVC REQUIRE не рассматривает модели (и это не должно). –

+0

@Charles Boyung - шаблон MVC не требует отдельных моделей доменов и просмотров. На языке с утиным типом, подобным Ruby, вы можете легко использовать одну модель. В .Net нет утиной печати. Вы можете использовать одну модель, но будет очень сложно подогнать все данные логики, данных и отображения в объекте одного домена, когда представления и контроллеры станут более сложными, чем стандартный сценарий. Создание специализированных классов может быть меньше в .net. В сценарии MVC есть свои преимущества и недостатки как утиного, так и статического скомпилированного подхода. – Paco

ответ

1

Не без тяжелого подъема. Я не уверен, что nhibernate заботится о том, что это тот же самый точный пример или нет; вам может потребоваться только сохранить идентификатор объекта для вашей формы.

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

<%= Html.HiddenFor(model => model.Id) %> 

Вы можете указать (через белый список или черный список), какие свойства могут/не могут быть отредактированы в форме, если вы беспокоитесь о людях, хакерские (и вы должно быть).

+0

Я думал, что есть какой-то способ получить экземпляр объекта после редактирования с изменением только нескольких редактируемых полей, а все остальные поля readonly сохраняют свои старые значения. Я новичок в asp mvc так же, как и в nhibernate, поэтому мне все еще нужно проверить, достаточно ли для nhibernate указать только User.Taxi.Id, чтобы иметь правильную ссылку между User и Taxi и не вызывать недействительное обновление Taxi , – jjjjj

+0

@jjj вы должны понимать, что ASP.NET MVC (и в целом в Интернете) является апатридом. Помимо нескольких исключений, все уходит между вызовами от клиента к серверу. Поэтому, если вы не используете какой-либо механизм хранения, чтобы «удерживать» ссылку на экземпляр модели между вызовами (сколько бы она ни была), она будет удаляться и собираться системой сразу же после выхода вашего метода контроллера. Дешевый и грязный метод заключается в том, чтобы сохранить Пользователь в хранилище. Лучшее решение - это тот, который я предоставил, imho. Есть и другие способы, в зависимости от требований ура ... – Will

+0

Да, я не нуждаюсь в объекте пользователя в моей http-сессии для этого долго. Теперь я застрял с моим свойством Id, которое является приватным для всех моих сущностей (общее решение для приложений с использованием nhib), поэтому Html.HiddenFor (model => model.Id) возвращает 0 для Id. Даже если сделать это общедоступным, это не решает проблему, но по-прежнему не обновляет пользовательские причины незаполненных полей notnull в User.Taxi. Теперь я вижу, как получить oldUser по id в моем методе httpPost, обновить его вручную с помощью полученного (отправленного) экземпляра newUser, а затем сохранить oldUser с изменениями. Я понял ваше объяснение о сети, спасибо, проблема сейчас в nhibernate – jjjjj

0

Ответ предложил Волей лучший соответствие мой вопрос:
Чтобы Редактировать объект
- Предоставьте Вид с идентичностью объекта, который вы хотите редактировать
- Опубликуйте модель с единицей в скрытом поле (в моем case i не может использовать model.Id private setter из-за настроек отображения nhib)
- В методе httpPost используйте GetById (idFromHiddenField) для извлечения вашей сущностиFromDatabase
- используйте UpdateModel (entityFromDatabase) - который объединит старую версию (entityFromDatabase) и новая версия объекта
- Затем ISession.Обновление (entityFromDatabase) для сохранения изменений в базе данных