【问题标题】:The data has been cleared after post发布后数据已清空
【发布时间】:2014-02-04 13:22:53
【问题描述】:

我有编辑页面和控制器,它创建新的模型对象并将数据库中的一些数据填充到这个对象中,然后发送一个模型对象来查看。当我单击提交按钮时,该对象中的某些字段已被清除。

例如: 之前:

    user_id
    name
    birth_date
    username
    password
    id_role
    email

之后(不为 null 或空的字段):

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

处理post请求的编辑方法:

    [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>
}

提前致谢:)

【问题讨论】:

    标签: c# asp.net-mvc post razor


    【解决方案1】:

    您只会收到表单中的值。 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】:

      post 操作只收集表单中的值。

      如果您希望其他值在控制器后处理方法中继续,例如,您可以添加隐藏字段。

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

      【讨论】:

      • 请在投反对票前给出适当的解释。我认为这个答案也是问题的可能解决方案之一。
      • 是的,这是最简单的方法。 Simons 的回答是一种更好、更安全的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 2017-07-30
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多