【发布时间】: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