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

时间:2012-04-04 00:35:44

标签: 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>

我有以下Knockout代码:

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

@Model.UserText是一个文字字符串。我的ASP.NET MVC控制器方法modify定义如下:

[Authorize]
[HttpPost]
public ActionResult Modify(string userText)
{
  ...
}

我的问题是 postJSON方法将转义字符串发布到我的控制器方法,我不明白为什么。我可以在fiddler中看到字符串以{{1}的形式出现}

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

userText=%22some+text%22

然后将JSON对象$.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); } }); 传递给控制器​​方法,MVC模型绑定器正确解析它并给我一个未转义的字符串。

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

1 个答案:

答案 0 :(得分:7)

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

您需要的是在行动中使用[FromJson]属性。

[Authorize]
[HttpPost]
public ActionResult Modify([FromJson]string userText)
{
  ...
}

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);
            }
        }
    }
}

只是一些评论:

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

1)它将创建带有输入集

的内部表单

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

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

JSON.stringify('"some text"') 

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

3)如果您使用参数传递了选项,它也会将它们附加到请求中。

的示例:

ko.utils.postJson('localhost',{ userText : '"some text"' });

<强>帖子: userText“\”some text \“”

ko.utils.postJson('localhost',{}, {params: { userText : '"some text"' } });

<强>帖子: userText“some text”

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