4

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

我有一个表单中的文本区域:

<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>

我有以下淘汰赛代码:

<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 方法将转义字符串发布到我的控制器方法,我不明白为什么。我可以在提琴手中看到字符串作为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);
}
});

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

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

4

1 回答 1

7

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

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

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

属性的实现:

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(data[key]));

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

JSON.stringify('"some text"') 

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

3)如果您通过参数传递选项,它还将附加它们以供请求。

例子:

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

帖子: 用户文本“\”一些文本\“”

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

帖子: userText“一些文字”

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

于 2012-04-04T01:51:45.637 回答