2014-02-04 4 views
0

У меня есть страница редактирования и контроллер, который создает новый объект модели и заполняет некоторые данные из db в этот объект, а затем отправляет объект модели для просмотра. Когда я нажимаю кнопку отправки, некоторые поля этого объекта очищаются.Данные были удалены после сообщения

Например: До:

user_id 
    name 
    birth_date 
    username 
    password 
    id_role 
    email 

После (поля, которые не являются нулевым или пустым):

name 
    username 
    birth_date 

Модель:

public partial class Users 
{ 
    public Users() 
    { 
     this.Albums = new HashSet<Albums>(); 
     this.History = new HashSet<History>(); 
     this.Country = new HashSet<Country>(); 
     this.Artists = new HashSet<Artists>(); 
     this.SelectedCountries = new List<string>(); 
    } 
    [DisplayName("User ID")] 
    public System.Guid user_id { get; set; } 
    [DisplayName("Name")] 
    public string name { get; set; } 
    [DisplayName("Birth date")] 
    public Nullable<System.DateTime> birth_date { get; set; } 
    [DisplayName("Username")] 
    public string username { get; set; } 
    [DisplayName("Password")] 
    public string password { get; set; } 
    [DisplayName("Rights")] 
    public System.Guid id_role { get; set; } 
    [DisplayName("User Email")] 
    public string email { get; set; } 
    public bool isRemember { get; set; } 

    public virtual ICollection<Albums> Albums { get; set; } 
    public virtual ICollection<History> History { get; set; } 
    public virtual Role Role { get; set; } 
    public virtual ICollection<Country> Country { get; set; } 
    public virtual ICollection<Artists> Artists { get; set; } 
    public virtual List<string> SelectedCountries { get; set; } 
} 

Изменить метод:

public ActionResult Edit() 
    { 
     if (HttpContext.User.Identity.IsAuthenticated) 
     { 
      var userName = HttpContext.User.Identity.Name; 
      var user = db.Users.Where(x => x.username == userName).FirstOrDefault(); 

      ViewBag.Countries = new MultiSelectList(db.Country, "id_country", "name", user.SelectedCountries); 

      return View(user); 
     } 
     return HttpNotFound(); 
    } 

Изменить способ для запроса послеуборочной:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit(Users users) 
    { 
     if (ModelState.IsValid) 
     { 
      foreach (var country in users.SelectedCountries) 
      { 
       var dbCountry = db.Country.Find(new Guid(country)); 
       if (dbCountry != null) 
        users.Country.Add(dbCountry); 
      } 
      db.Entry(users).State = System.Data.Entity.EntityState.Modified; 
      //There handle of string array goes 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(users); 
    } 

Вид:

<h2>Edit</h2> 
@using (Html.BeginForm()) { 
@Html.AntiForgeryToken() 
@Html.ValidationSummary(true) 

<fieldset> 
    <legend>Users</legend> 
    <div class="editor-label"> 
     @Html.LabelFor(model => model.name) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.name) 
     @Html.ValidationMessageFor(model => model.name) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.birth_date) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.birth_date) 
     @Html.ValidationMessageFor(model => model.birth_date) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.username) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.username) 
     @Html.ValidationMessageFor(model => model.username) 
    </div> 
    <div class="editor-label"> 
     @Html.Label("Country") 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownList("SelectedCountries", (ViewBag.Countries as MultiSelectList), new { multiple = "multiple", @class = "chosen", style = "width: 350px;"}) 
    </div> 
    <p> 
     <input type="submit" value="Save" /> 
    </p> 
</fieldset> 
} 

Заранее спасибо :)

ответ

3

Вы получите только те значения, которые указаны в вашей форме. Http является апатридом ..

Что вам нужно сделать .. это создать ViewModel. Этот ViewModel является подмножеством свойств из вашей модели домена, которые отображаются в представлении. Пример:

public class UserViewModel { 
    public string Name { get; set; } 
    public string Username { get; set; } 
    public DateTime? DateofBirth { get; set; } 
} 

Используйте эту модель на ваш взгляд. Затем, в контроллере .. заставить пользователя и обновить соответствующие поля:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit(UserViewModel viewModel) { 
    var user = db.Users.Where(x => x.username == viewModel.Username).FirstOrDefault(); 

    user.Name = viewModel.Name; 
    user.Username = viewModel.Username; 
    // .. etc. 

    db.SaveChanges(); 
} 

Если вы беспокоитесь обо всех ручного отображения участвующих в этом, существует рамки, чтобы помочь вам в этом:

вы возглавляете вниз очень и очень непростой путь, если вы начинаете добавлять скрытые поля в вашей точки зрения. Его кошмар обслуживания и очень склонный к ошибкам.

2

Операция пост собирает только значения, которые вы имеете в форме.

Если вы хотите, чтобы другие значения выполнялись в пост-методе контроллеров, вы можете, например, добавить скрытые поля.

@Html.HiddenFor(x => x.HiddenPostBack) 
+1

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

+0

Ye, это легкий выход. Ответ Саймонса - намного лучший и более безопасный подход. – user373455

Смежные вопросы