2012-04-04 103 views
4

我是KockoutJS的新手,所以我可能會錯過簡單的東西。KnockoutJS postJSON方法轉義我的字符串爲什麼?

我有一個形式,一個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> 

而且我有以下代碼淘汰賽:

<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對象相同嗎?

回答

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,數據,選項)將做以下爲你:

1)它將創建一組輸入內部形式

2)它會迭代你的數據參數,並且會調用 ko.utils.stringifyJson(ko.utils.unwrapObservable(data [key]));

對每個屬性,並將結果保存到該輸入。這在內部使用JSON.stringify,所以在你的情況下,它會調用

JSON.stringify('"some text"') 

這就是爲什麼你看到你的字符串「逃跑」(實際上它只是轉換到JSON)

3)萬一你通過params傳遞選項,它也會將它們附加到請求中。

例子:

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

帖子: userText 「\」 一些文字\ 「」

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

帖子: userText 「一些文本」

所以在你的情況,如果你不想裝飾[FromJson],你可以只是廣告d改爲options.params而不是數據。 Hovewer,如果你需要傳遞更復雜的json對象(不是簡單的字符串,但有一些ViewModel),你仍然需要使用這個[FromJson]屬性。

+0

謝謝。使用'{params:{}}'語法工作。我不想用[fromJSON]來裝飾我的MVC控制器方法。我其實認爲正常的jQuery ajax方法更清晰,所以我認爲我最終會走這條路。 – 2012-04-04 16:05:53

+0

我也一直使用純粹的jquery ajax方法。從我的角度來看,使用ko.utils.postJson的唯一原因是當你想要執行真實的表單發佈時,例如,在您的控制器中使用RedirectToAction之類的東西,或者只是返回完整(非部分)視圖。但是這些用例非常罕見... – Artem 2012-04-04 16:30:25

+0

如果您在控制器後操作中使用[ValidateAntiForgeryToken],則可以使用以下技巧發送令牌: params:{__RequestVerificationToken:$('input [name = __ RequestVerificationToken]') .val()} – jgarza 2012-09-17 17:37:14

相關問題