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.NETMVCコントローラーメソッドmodifyは次のように定義されています。

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

私の問題は、postJSONメソッドがエスケープされた文字列をコントローラーメソッドにPOSTしていることであり、その理由がわかりません。私はフィドラーで弦が次のように入ってくるのを見ることができますuserText=%22some+text%22

次のようにpostJsonを使用する代わりに通常のjQueryajaxを使用する場合:

$.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にjQueryajaxメソッドによって渡されるのと同じ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)
{
  ...
}

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(data [key]));を呼び出します。

各プロパティで、結果をその入力に保存します。これは内部でJSON.stringifyを使用するため、あなたの場合は

JSON.stringify('"some text"') 

そのため、文字列は「エスケープ」されています(実際にはJSONに変換されただけです)

3) paramsを使用してオプションを渡した場合、リクエストのためにそれらも追加されます。

例:

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

投稿: userText "\" some text \ ""

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

投稿: userText「一部のテキスト」

したがって、[FromJson]で装飾したくない場合は、データの代わりにoptions.paramsに追加するだけです。ただし、より複雑なjsonオブジェクト(単純な文字列ではなく一部のViewModel)を渡す必要がある場合でも、この[FromJson]属性を使用する必要があります。

于 2012-04-04T01:51:45.637 に答える