如何将更新后的模型值传回控制器?

How to pass the updated model values back to controller?

我想创建一个 MVC 表单来编辑用户数据。

在控制器中我创建了以下方法:

public ActionResult UserEdit(DemoRes.Models.User user)
{
   checkSignIn();
   return View("User", user);
}

public ActionResult UserSave(DemoRes.Models.User user)
{
   checkSignIn();
   MongoDBManager dal = new MongoDBManager();
   dal.EditUser(user);
   return RedirectToAction("UserManagement");
}

在表单 "User Management" 中,从列表中选择一个用户并传递给控制器​​中的 UserEdit。然后出现 "User" 表单,其中包含填充的用户数据 - 因此数据已成功从控制器传递到视图。在视图中,我想让用户能够更新数据或只是 "cancel" 操作并返回到用户列表。

为此,我创建了以下 User.cshtml 表单:

@{
ViewBag.Title = "User";
}    
<script>

    $(function(){
        $("#btnCancel").click(function(){
            window.location.href = url;
            return false;
        });
    });

    $(function(){
        $("#btnSubmit").click(function(){
            $.ajax({
                url: "@Url.Action("UserSave", "Admin")",
                type: "POST",
                data: data
            });
            window.location.href = url;
            return false;
        });
    });

    function SubmitFrm(){
        var Searchtxt = document.getElementById("txtSearch").value;
        window.location = $("#RedirectTo").val();
    }

</script>
@Html.Hidden("RedirectTo", Url.Action("UserManagement", "Admin"));
<h2>User</h2>
        <div class="container">
            <form role="form">
                <div class="form-group">
                    <label for="username">Username:</label>
                    <input type="text" class="form-control" id="username" data-bind="value:username">
                </div>
                <div class="form-group">
                    <label for="email">Email:</label>
                    <input type="text" class="form-control" id="email" data-bind="value:email">
                </div>
                <div class="form-group">
                    <label for="password">Password:</label>
                    <input type="text" class="form-control" id="password" data-bind="value:password">
                </div>
                <div class="checkbox">
                    <label><input type="checkbox" id="isActive" data-bind="checked:isActive">Is active</label>
                </div>
        @if (ViewBag.Owners != null)
    {

        <div class="form-group">
                <label for="prop">Owners:</label>
                <select class="form-control">
                    @foreach (DemoRes.Entities.Owner o in ViewBag.Owners)
                {
                    <option value=@o.Id.ToString()>@o.FirstName @o.LastName</option>
                }
                </select>
            </div>
    }
                <button type="submit" class="btn btn-default" value="Cancel" name="addEditUser" id="btnCancel">Cancel</button>
                <button type="submit" class="btn btn-default" value="Submit" name="addEditUser" id="btnSubmit">Save</button>
    </form>
</div>

<script>
    var data=@(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
        function viewModel() {
            this.username=ko.observable(data.Username);
            this.password=ko.observable(data.Password);
            this.email=ko.observable(data.Email);
            this.isActive=ko.observable(data.IsActive);
        };
        ko.applyBindings(new viewModel());
        var url = $("#RedirectTo").val();

当用户点击 "Save" 按钮时,将调用以下函数:

$(function(){
        $("#btnSubmit").click(function(){
            $.ajax({
                url: "@Url.Action("UserSave", "Admin")",
                type: "POST",
                data: <modified data>
            });
            window.location.href = url;
            return false;
        });
    });

在这里,我不知道将修改后的数据传回控制器中的UserSave方法的正确方法是什么。如果有人建议正确绑定数据的方法,我将不胜感激。

您可以使用 ko.toJSON() 方法将视图模型转换为 JSON 字符串:

var vm = ko.dataFor(document.body);

$.ajax({
    url: '@Url.Action("UserSave", "Admin")',
    type: 'POST',
    data: ko.toJSON(vm),
    contentType: 'application/json',
    });

ko.toJSON 方法的主要优点是它能够自动处理 observables)

但是,由于将数据发布到服务器的实际函数不是视图模型的一部分,我不得不调用 ko.dataFor 以获得绑定的视图模型(这并不理想).

如果您将动作作为视图模型的一部分,它看起来会更好:

function viewModel()
{
    this.username=ko.observable(data.Username);
    this.password=ko.observable(data.Password);
    this.email=ko.observable(data.Email);
    this.isActive=ko.observable(data.IsActive);

    this.submit = function(e)
    {
        $.ajax({
            url: '@Url.Action("UserSave", "Admin")',
            type: 'POST',
            data: ko.toJSON(this),
            contentType: 'application/json',
            });
    }    
};

然后更改按钮HTML:

<button data-bind="click: submit"
        type="submit"
        class="btn btn-default"
        value="Submit"
        name="addEditUser"
        id="btnSubmit">Save</button>

Documentation