KnockoutJS postJSON方法逃脱了我的字符串为什么?

Bra*_*ham 4 jquery asp.net-mvc-3 knockout.js

我是KockoutJS的新手,所以我可能会遗漏一些简单的东西.

我有一个textarea形式:

<form method="POST" data-bind="submit: save" id="theForm">
    <textarea name="Text" rows="10" cols="100" data-bind="value: userText" ></textarea>
    <input type="submit" value="Save" />
</form>
Run Code Online (Sandbox Code Playgroud)

我有以下Knockout代码:

<script type="text/javascript">
    var MyViewModel = {
        userText: ko.observable('@Model.UserText'),
        save: function () {
              ko.utils.postJson('@Url.Action("modify")',{userText : this.userText});
            }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

@Model.UserText文字字符串在哪里.我的ASP.NET MVC控制器方法modify定义如下:

[Authorize]
[HttpPost]
public ActionResult Modify(string userText)
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是postJSON方法将转义字符串POST到我的控制器方法,我不明白为什么.我可以在提琴手中看到字符串是以字符串形式出现的userText=%22some+text%22

如果我使用普通的jQuery ajax而不是像这样使用postJson:

$.ajax(
{
url: '@Url.Action("modify")',
contentType: 'application/json',
type: 'POST',
data: ko.toJSON({userText: ko.toJS(this.userText)}),
success: function(result) {
    ko.mapping.updateFromJS(this, result);
}
});
Run Code Online (Sandbox Code Playgroud)

然后将JSON对象{'userText': 'some text'}传递给控制器​​方法,MVC模型绑定器正确解析它并给我一个未转义的字符串.

我可以让postJson传递jQuery ajax方法传递的相同JSON对象吗?

Art*_*tem 7

完整信息位于本文 http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/

您需要的是在您的操作中使用[FromJson]属性.

[Authorize]
[HttpPost]
public ActionResult Modify([FromJson]string userText)
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

atttribute的实现:

using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace koListEditor
{
    public class FromJsonAttribute : CustomModelBinderAttribute
    {
        private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();

        public override IModelBinder GetBinder()
        {
            return new JsonModelBinder();
        }

        private class JsonModelBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
                if (string.IsNullOrEmpty(stringified))
                    return null;
                return serializer.Deserialize(stringified, bindingContext.ModelType);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

只是一些评论:

ko.utils.postJson(urlOrForm,data,options)将为您做以下事情:

1)它将创建带有一组输入的内部表单

2)它将迭代你的数据参数,并将调用ko.utils.stringifyJson(ko.utils.unwrapObservable(data [key]));

在每个属性上,并将结果保存到该输入.这在内部使用JSON.stringify,因此在您的情况下它将调用

JSON.stringify('"some text"') 
Run Code Online (Sandbox Code Playgroud)

这就是为什么你看到你的字符串'转义'(实际上它只是转换为JSON)

3)如果您通过params选项,它也会将它们附加到请求中.

例子:

ko.utils.postJson('localhost',{ userText : '"some text"' });
Run Code Online (Sandbox Code Playgroud)

帖子: userText"\"一些文字\""

ko.utils.postJson('localhost',{}, {params: { userText : '"some text"' } });
Run Code Online (Sandbox Code Playgroud)

帖子: userText"some text"

所以在你的情况下,如果你不想用[FromJson]装饰,你可以添加到options.params而不是数据.Hovewer,如果你需要传递更复杂的json对象(不是一个简单的字符串,而是一些ViewModel),你仍然需要使用这个[FromJson]属性.