MVC4如何只保存选择字段的更改而不影响其他字段

时间:2014-06-21 19:44:33

标签: asp.net-mvc asp.net-mvc-4

我有一个编辑页面,用户只能更新2个字段的城市和州,整个模型大约有11个不同的字段但是又一次;我只允许他们编辑那些2加1的其他ID,但他们无法编辑它。我的问题是,在编辑和保存新信息时,所有其他字段在该特定行的数据库中变为NULL,这可能导致什么?这是我的代码

        [Authorize]
    public ActionResult Edit()
    {
          //Get user uniqueID
        var ss = Convert.ToInt32(User.Identity.Name);
// basically look up uniqueID match in database and select 3 fields profileID,city,state
        string Connectionstring = ConfigurationManager.ConnectionStrings ["looglercontext"].ConnectionString;
        using (System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(Connectionstring))
        {
            sqlConnection.Open();
            var getinfo = sqlConnection.Query<profile>("Select profileID,city,state from profiles where profileID=@myprofile", new { myprofile = ss }).FirstOrDefault();
            return View(getinfo);
        }
    }

我的观点看起来像这样

     @model hackerway.Models.profile
using (Html.BeginForm("edit", "profile", FormMethod.Post
{




 @Html.HiddenFor(model => model.profileID)


                @Html.EditorFor(model => model.city)
          @Html.EditorFor(model => model.state)



 <div style="margin-left: 200px">
    <p class="name">
        <input type="submit" name="myedit" value="update" /> 

    </p>



  </div>
 }

用户点击更新按钮后,我们转到简单的HttpPost

       [HttpPost]
    public ActionResult Edit(profile profiler)
    {

              // I use the profiler to get the fields from the view and update them
            if (ModelState.IsValid)
                    {
                        db.Entry(profiler).State = EntityState.Modified;
                        db.SaveChanges();
                        ViewBag.success = "Your changes have been saved";
                        return View(profiler);
                    } 


     }

如前所述,如果某个字段得到更新,一切正常,则更改会被保存,但我在表单中输入的其他11个字段将返回“无效”状态。在SQL代码中,我只抓取我需要的字段,因此我没有使用 * 任何帮助都会很棒

1 个答案:

答案 0 :(得分:4)

您了解数据在数据库之间来回移动的方式并不完全正确。从数据库中仅选择所需的字段是绝对正确的;这没有什么不妥。

您的代码需要更改的位置在POST方法中。您的方法接受profile类型参数。当HTML表单中的数据提交到服务器时,只有表单中的输入会传递到服务器(即profileIdcitystate)。 profiler对象上的任何其他属性都将为null,因为ASP.NET应该知道它们是什么?用户只传递了这三个值。

在Entity Framework世界中,解决此问题的方法是执行以下操作:

public ActionResult Edit(profile profiler)
{
    if (ModelState.IsValid)
    {
        //Go fetch the existing profile from the database
        var currentProfile = db.Profiles.FirstOrDefault(p => p.ProfileId == profiler.ProfileId);
        //Update the database record with the values from your model
        currentProfile.City = profiler.City;
        currentProfile.State = profiler.State;
        //Commit to the database!
        db.SaveChanges();
        ViewBag.success = "Your changes have been saved";
        return View(profiler);
    }
}

要给出完整的答案,解决问题的另一种方法。但是,我强烈建议你不要这样做,我会在短期内解释原因。

解决此问题的另一种方法是在表单中为表中的任何其他字段添加其他隐藏的输入。通过这样做,当用户提交表单时,ASP.NET的模型绑定过程将确保profiler对象上的其他属性具有数据。当您将对象提交到数据库时,此时您已经拥有了所需的一切。

为什么这是一个坏主意?我们说我加载了您的页面,我想尝试更改我不应该更改的数据。我可以修改那些隐藏输入的值,提交表单,然后你的应用程序会将数据提交到数据库!坏消息。通过使用隐藏输入,您可以信任您的用户。在某些情况下,这可能是一个可接受的风险(例如,您的同事的一个小型网络应用程序),但在其他情况下,它可能是高风险甚至是欺诈。

它还会在通过线路传输的字节数方面增加不必要的开销,但与后者相比,这是一个小细节。