使用本文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的类型映射魔法甚至假设使用多态?
答案 0 :(得分:0)
正确的方法是data: JSON.stringify(ko.toJS(this))
(假设this
确实指向了您的viewmodel,它似乎就是这样。
ko.toJS
创建一个纯JavaScript对象(没有observable-wrappers)
JSON.stringify
只是必要的,因为你的ajax调用是contentType: 'application/json'
。通常,不需要像JSON一样发送,但在某些情况下(发送复杂的对象,特别是包含列表/数组的对象),字符串化将帮助MVC模型映射器理解您要发送的内容。