Asp.net mvc 4 将ViewModel传递回控制器

Asp.net mvc 4 将ViewModel传递回控制器,asp.net-mvc-4,twitter-bootstrap-3,viewmodel,knockout-3.0,Asp.net Mvc 4,Twitter Bootstrap 3,Viewmodel,Knockout 3.0,我有一个集成Bootstrap和Knockout的工作应用程序。这个应用程序从我的控制器中提取数据,并按照我的预期在UI中显示这些数据。当我单击或更改某个值时,我可以看到值被更新,但我似乎看不到为了保存数据而将数据传回控制器。我所需要知道的就是如何修复我所需要的,以允许我将selectedRequestorName传递回控制器 下面是一个示例类 public class Requestor { public int Id { get; set; } public string N

我有一个集成Bootstrap和Knockout的工作应用程序。这个应用程序从我的控制器中提取数据,并按照我的预期在UI中显示这些数据。当我单击或更改某个值时,我可以看到值被更新,但我似乎看不到为了保存数据而将数据传回控制器。我所需要知道的就是如何修复我所需要的,以允许我将selectedRequestorName传递回控制器

下面是一个示例类

public class Requestor
{
    public int Id { get; set; }
    public string Name { get; set; }
}
接口

interface IRequestorRepository
{
    IList<Requestor> GetAllRequestors();
}
在我的Index.cshtml中,我在页面顶部的脚本标记中有以下内容

// Global variable
var viewModel = null;

$(document).ready(function () {
    function ViewModel() {

        //Make the self as 'this' reference
        var self = this;

        // Requestors
        self.RequestorId = ko.observable("");
        self.RequestorName = ko.observable("");
        self.RequestorSourceDatabase = ko.observable("");

        var RequestorNames = {
            Id: self.RequestorId,
            Name: self.RequestorName,
            SourceDatabase: self.RequestorSourceDatabase
        };

        self.selectedRequestorName = ko.observable();
        self.RequestorNames = ko.observableArray();   // Contains the list of RequestorNames

        // Initialize the view-model for Requestors
        $.ajax({
            url: '@Url.Action("GetRequestors", "Home")',
            cache: false,
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            data: {},
            success: function (data) {
                self.RequestorNames(data);
            }
        });
        // END Requestors

        // Reset
        self.reset = function () {
            self.Name("");
        }

        // Cancel
        self.cancel = function () {
            self.Name(null);
        }
    }

    viewModel = new ViewModel();
    ko.applyBindings(viewModel);        
});

$(function () {
        $('#Save').click(function (e) {

            // Check whether the form is valid. Note: Remove this check, if you are not using HTML5
            if (document.forms[0].checkValidity()) {

                e.preventDefault();

                $.ajax({
                    type: "POST",
                    url: '@Url.Action("SaveDetails", "Home")',
                    data: ko.toJSON(viewModel.selectedRequestorName),
                    contentType: 'application/json; charset=utf-8',
                    async: true,
                    beforeSend: function () {
                        // Display loading image
                    },
                    success: function (result) {
                        if (result > 0) {
                            alert("This work request has been successfully saved in database. The Document ID is: " + result);
                        } else {
                            alert("The Work Request was not saved, there was an issue.");
                        }
                    },
                    complete: function () {
                        // Hide loading image.
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        // Handle error.
                    }
                });

            }
            else {
                alert("Form is not valid");
            }
        });
});
最后是包含显示数据的控件,供用户从中选择

<p>Current selection is <span data-bind="text:selectedRequestorName"></span></p>
<!-- Requestors -->
<div class="input-group col-sm-8">
  <input type="text" data-bind="value:selectedRequestorName" class="form-control item" placeholder="Requestor Name" name="Requestor">
    <div class="input-group-btn">
      <button type="button" class="btn btn-default dropdown-toggle item" data-toggle="dropdown">Select <span class="caret"></span></button>
        <ul class="dropdown-menu" data-bind="foreach: RequestorNames">
          <li class="dropdown">
            <a href="#" data-bind="text: Name, value: Id, click: function() { $root.selectedRequestorName(Name); }"></a>
          </li>
        </ul>
     </div>
  </div>
  <div>
    <button id="Save" type="submit" class="btn btn-default btn-success">Create</button>
  </div>
在控制器上创建接受selectedRequestorName字符串的操作方法?作为论据。 在knockout viewmodel中创建一个函数,从ko vm、jsonstringit读取selectedRequestorName,并通过ajax将其传递回上述操作方法。 如上所述,将selectedRequestorName的类型从请求者更改为字符串,这样应该可以工作

注释未测试。但请告诉我它是否有帮助。

在$'Save'内。单击,请更改行

数据:ko.toJSONviewModel.selectedRequestorName

数据:ko.toJSONviewModel.selectedRequestorName


希望,这会有所帮助。

在发布之前,我已经尝试过这个解决方案。不幸的是,将预期类型更改为字符串不会产生不同的结果。我可以通过Chrome的F12在请求负载中看到选择的值是Steve,但我最终得到的值是null。在ko模型中,尝试以下方法:data:JSON.stringify{selectedRequestorName:self.RequestorName}它找不到RequestorName。它抛出了一个错误。还有其他建议吗?正如我所说,我可以在请求头中看到viewModel,但在控制器中看不到。如果我只是在Like so->data:ko.toJSONviewModel中传递viewModel,我可以看到请求头中的所有值,但它们永远不会显示在我的控制器中。这才是真正的问题。我不确定我需要做什么来获取这些值。我怀疑您可能在ModelBinder中遇到了问题。您的KO viewmodel的命名与您的c模型的命名不匹配。在c模型中,您有Id和名称,但在KO中,您有requestorId和requestorName。
// Global variable
var viewModel = null;

$(document).ready(function () {
    function ViewModel() {

        //Make the self as 'this' reference
        var self = this;

        // Requestors
        self.RequestorId = ko.observable("");
        self.RequestorName = ko.observable("");
        self.RequestorSourceDatabase = ko.observable("");

        var RequestorNames = {
            Id: self.RequestorId,
            Name: self.RequestorName,
            SourceDatabase: self.RequestorSourceDatabase
        };

        self.selectedRequestorName = ko.observable();
        self.RequestorNames = ko.observableArray();   // Contains the list of RequestorNames

        // Initialize the view-model for Requestors
        $.ajax({
            url: '@Url.Action("GetRequestors", "Home")',
            cache: false,
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            data: {},
            success: function (data) {
                self.RequestorNames(data);
            }
        });
        // END Requestors

        // Reset
        self.reset = function () {
            self.Name("");
        }

        // Cancel
        self.cancel = function () {
            self.Name(null);
        }
    }

    viewModel = new ViewModel();
    ko.applyBindings(viewModel);        
});

$(function () {
        $('#Save').click(function (e) {

            // Check whether the form is valid. Note: Remove this check, if you are not using HTML5
            if (document.forms[0].checkValidity()) {

                e.preventDefault();

                $.ajax({
                    type: "POST",
                    url: '@Url.Action("SaveDetails", "Home")',
                    data: ko.toJSON(viewModel.selectedRequestorName),
                    contentType: 'application/json; charset=utf-8',
                    async: true,
                    beforeSend: function () {
                        // Display loading image
                    },
                    success: function (result) {
                        if (result > 0) {
                            alert("This work request has been successfully saved in database. The Document ID is: " + result);
                        } else {
                            alert("The Work Request was not saved, there was an issue.");
                        }
                    },
                    complete: function () {
                        // Hide loading image.
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        // Handle error.
                    }
                });

            }
            else {
                alert("Form is not valid");
            }
        });
});
<p>Current selection is <span data-bind="text:selectedRequestorName"></span></p>
<!-- Requestors -->
<div class="input-group col-sm-8">
  <input type="text" data-bind="value:selectedRequestorName" class="form-control item" placeholder="Requestor Name" name="Requestor">
    <div class="input-group-btn">
      <button type="button" class="btn btn-default dropdown-toggle item" data-toggle="dropdown">Select <span class="caret"></span></button>
        <ul class="dropdown-menu" data-bind="foreach: RequestorNames">
          <li class="dropdown">
            <a href="#" data-bind="text: Name, value: Id, click: function() { $root.selectedRequestorName(Name); }"></a>
          </li>
        </ul>
     </div>
  </div>
  <div>
    <button id="Save" type="submit" class="btn btn-default btn-success">Create</button>
  </div>
[HttpPost]
    public JsonResult SaveDetails(String selectedRequestorName)
    {
        int id = -1;

        return Json(id, "json");
    }