Knockout POST发送空类

时间:2014-03-12 11:29:08

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

使用本文http://www.mytecbits.com/microsoft/dot-net/knockout-js-and-bootstrap-with-asp-net-mvc-part-2获取knockout / 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

修改

答案是Hans的回答和{ 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的类型映射魔法甚至假设使用多态?

1 个答案:

答案 0 :(得分:0)

正确的方法是data: JSON.stringify(ko.toJS(this))(假设this确实指向了您的viewmodel,它似乎就是这样。

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

JSON.stringify只是必要的,因为你的ajax调用是contentType: 'application/json'。通常,不需要像JSON一样发送,但在某些情况下(发送复杂的对象,特别是包含列表/数组的对象),字符串化将帮助MVC模型映射器理解您要发送的内容。