7

基本的に、コントローラー (WebApi) から返されたモデル状態エラーの表示に問題があります。MVC4、jQuery、ノックアウトを使用。以下から、私が達成しようとしていることを確認していただければ幸いです。よろしくお願いします。

意見:-

<div class="editor-field">
        @Html.TextBoxFor(model => model.CostCode,
                new
                {
                    placeholder = "cost/budget code",
                    data_bind = "value: CostCode"                        
                })            
    </div>
    <div>
        @Html.ValidationMessageFor(model => model.CostCode)
    </div>

投稿/送信を行うノックアウト ビューモデル:-

if (validator.valid())
    {
        console.log('is valid');
        $.ajax({
            url: '/api/Booking/CompleteBooking',
            type: 'POST',
            dataType: 'json',
            data: ko.mapping.toJS(self),
            error: function (jqXHR) { 
                extractErrors(jqXHR, validator);                                      
            },
            success: function (data) {                   
                console.log(data);
            }
        });
    }

function extractErrors(jqXhr, validator)
{
    var data = $.parseJSON(jqXhr.responseText),
    errors = { };   

    $.each(data.ModelState, function (i, item) {
       errors[i] = item;
    });   

    console.log(errors);
    validator.showErrors(errors); 
}

コントローラ:-

 [ModelValidationFilter]
    public HttpResponseMessage CompleteBooking(AdditionalBookingInfoViewModel model)
    {
        return new HttpResponseMessage(HttpStatusCode.OK);

    }  

ActionFilterAttribute (返されるモデル状態に注意してください)

public class ModelValidationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = 
                actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

レンダリングされたマークアップ:-

ここに画像の説明を入力

Firebug の応答:-

ここに画像の説明を入力

ここで、バリデーターがマークアップに表示される「CostCode」だけでなく「model.CostCode」という名前の要素を見つけようとすることはわかっていますが、一致するように ID と名前を「model.CostCode」に設定しようとしましたしかし、それは何の違いもありません。私の extractErrors 関数に問題があると思います。

エラーメッセージをハードコードすると、バリデーターは正常に動作します

validator.showErrors({
    "CostCode" : "Test test test!"
 }); 

ここに画像の説明を入力

ところで、これはサーバー側の検証メッセージを表示する受け入れ可能な方法ですか、それとも間違ったツリーを鳴らしていますか? ポインタ/コメントは大歓迎です。

4

1 に答える 1

4

推測では、console.log(errors) からの出力を示していないため、エラー項目の配列を生成していますが、実際の例では、フィールド名をキーとするハッシュテーブルしかありません。

{
    0: { 'model.CostCode': ['Please enter a valid cost code.'] }
}

{
    "CostCode" : "Test test test!"
}

したがって、エラー メッセージは配列ですが、実際の例はそうではありません。したがって、データを単にコピーするのではなく、データを解析するように extractErrors メソッドを変更する必要があります。

for(var key in data.ModelState)
{
    errors[key.replace('model.', '')] = data.ModelState[key][0];    
}

これは少しハックですが、正しい道に進むはずです!

于 2013-07-17T13:32:16.987 に答える