【问题标题】:Knockout POST sends empty class淘汰赛 POST 发送空类
【发布时间】:2014-04-16 12:05:03
【问题描述】:

使用这篇文章http://www.mytecbits.com/microsoft/dot-net/knockout-js-and-bootstrap-with-asp-net-mvc-part-2 来获得敲除/ajax 语法我写了一个PartialView 生成以下html 和javascript:

<div id="psuAccordion" class="list-group">


    <a class="list-group-item accordion-toggle" data-toggle="collapse" data-target="#sbarQuickClientAdd">Quick Client Add</a>
    <div id="sbarQuickClientAdd" class="panel-body collapse in" style="height: auto;">

        <div class="control-group">
            <label class="control-label">Client Name: </label>
            <div class="controls">
                <input type="text" class="input-medium" data-bind="value: ClientName" ,="" placeholder="Company">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">Contact Name: </label>
            <div class="controls">
                <input type="text" class="input-medium" data-bind="value: ContactName" ,="" placeholder="Contact">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">Phone: </label>
            <div class="controls">
                <input type="text" class="input-medium" data-bind="value: Phone" ,="" placeholder="Phone">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">Email: </label>
            <div class="controls">
                <input type="text" class="input-medium" data-bind="value: Email" ,="" placeholder="Email">
            </div>
        </div>
      <div class="control-group">
          <div class="controls" style="padding-top: 15px;">


               <button class="btn btn-danger btn-xs" data-bind="click: btnCxlQuickClientAdd"><span class="glyphicon glyphicon-remove"></span></button>
               <button class="btn btn-success btn-xs pull-right" data-bind="click: btnCreQuickClientAdd"><span class="glyphicon glyphicon-save"></span></button>
          </div>
      </div>
    </div>
<script type="text/javascript">
     $(function () {
         var avpQuickClientAdd = {
             TemplateName: ko.observable(),
             ClientName : ko.observable(), ContactName : ko.observable(), Phone : ko.observable(), Email : ko.observable(),
             btnCxlQuickClientAdd: function () {
                 $(this).closest('.accordion-toggle').click();
             },
             btnCreQuickClientAdd: function () {
                 this.TemplateName("QuickClientAdd");

                 $.ajax( {
                     url: '/QuickForm/Create',
                     type: 'post',
                     dataType: 'json',
                     data: ko.toJSON(this),
                     contentType: 'application/json',
                     success: function (result) {
                        // clear the form 

                     },
                     error: function (err) {
                           alert(err.responseText);
                    },
                    complete: function () {
                    }
                }
            );}
      }

      ko.applyBindings(avpQuickClientAdd);

  });
</script> 


</div>  

如果我在form 中输入一些数据并单击保存按钮,我可以在 chrome 调试器中看到 ko.toJSON 正在创建对象并填充它,但控制器方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AVP.DAL;

namespace AVP.Controllers
{
    public class QuickFormController : Controller
    {
        //
        // GET: /QuickForm/
        [HttpPost]
        public JsonResult Create(QuickFormClient qfc)
        {
            string clientName = qfc.ClientName;
            return new JsonResult();
        }

    }
}

收到一个空对象。返回一个新的JsonResult 的控制器方法现在无关紧要。这显然是一个存根方法,只是为了测试发布机制。问题是数据没有到达服务器。

这是参数类型定义:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AVP.DAL
{
    public class QuickFormClient 
    {
        public string TemplateName;
        public string ClientName;
        public string ContactName;
        public string Phone;
        public string Email;
    }
}

成员的顺序与 KO ViewModel 中声明的顺序相同。

我也尝试过这些不同程度的语法变体:

-1- data: JSON.stringify(ko.toJSON())
-2- data: "{ qfc: " + JSON.stringify(ko.toJSON()) + "}"
-3- data: "{ qfc: " + ko.toJSON() + "}"
-4- data: JSON.stringify({qfc: ko.toJSON()})

编辑:

在给出第一个答案后,我尝试了 JSON.stringify(ko.ToJS) 并且控制器方法仍然接收到一个其成员都是 null 的对象。

http://pdvstheweb.blogspot.co.uk/2014/03/httpstackoverflowcomquestions22350097kn.html

编辑:

答案是汉斯的答案加上{ get; set; }QuickFormClient的成员的组合。

谢谢大家。

编辑:

它不适用于多态性。

public class QuickForm 
{
    public string TemplateName { get; set; }
}

public class QuickFormClient : QuickForm
{ 
    public string ClientName { get; set; }
} 

[HttpPost]
public JsonResult Create(QuickForm arg)
{
    switch(arg.TemplateName)
    {
        case "QuickClient" :
           QuickFormClient c = (QuickFormClient)arg;
           break;
    }
}

当调用控制器方法时,TemplateName 为空。

我不知道让它以这种方式工作会增加多少价值,因为为不同的表单类型编写控制器方法很容易,而且淘汰 JavaScript 必须是单独的对象,对吗?我想也许可以执行一些 javascript 魔术来使 Knockout 视图模型具有动态属性?但即使这是可能的,MVC 的类型映射魔法是否也应该与多态一起工作?

【问题讨论】:

  • 使用 ko.toJS 代替 ko.toJSON
  • 仅供参考 - 当我尝试这个时,我在设置 TemplateName 可观察值的 ajax 调用之前得到一个“全局对象不包含成员 TemplateName”。

标签: javascript asp.net-mvc json knockout.js


【解决方案1】:

正确的方法是 data: JSON.stringify(ko.toJS(this))(假设 this 确实指向您的视图模型,它似乎确实如此。

ko.toJS 创建一个纯 JavaScript 对象(没有 observable-wrappers)

JSON.stringify 是必需的,因为您的 ajax 调用显示 contentType: 'application/json'。通常不需要以 JSON 格式发送,但在某些情况下(发送复杂对象,尤其是包含列表/数组的对象)字符串化将有助于 MVC 模型映射器了解您发送的内容。

【讨论】:

  • ko.toJSON() 是 JSON.stringify() 的包装器。所以我认为无论你做 ko.toJSON(this) 还是 JSON.stringify(ko.toJS(this)) 都是一样的。
  • 那行不通。我仍然得到一个空对象。我发布了调试器的屏幕截图,显示“this”确实指向正确的对象。
  • 啊……getter 和 setter。我完全忽略了 C# 部分 :( 很高兴你找到了它。
猜你喜欢
  • 2015-03-12
  • 2017-07-07
  • 1970-01-01
  • 2012-04-08
  • 2019-01-14
  • 2013-04-10
  • 2016-08-13
  • 2017-09-19
  • 1970-01-01
相关资源
最近更新 更多