4

次の問題が発生しています。チェックボックスにチェックされた値を含むフォームを AJAX 経由で API コントローラーに送信すると、ModelState オブジェクトはそれが無効であると言います。

前提条件:

  1. ビジュアル スタジオ 2012
  2. ASP.NET MVC 4 最終版
  3. 最新の jQuery および jQuery の控えめな検証機能 (バージョン 1.8.2 および 1.9.0.1)

再現する手順:

  1. Boolean フィールドを含むフォームの ViewModel を作成しました。
    public class CheckboxViewModel
    {
    [Display(Name="Test checkbox")]
    public bool TestCheckbox { get; set; }
    }
    
  2. ViewModel を準備してフォームをレンダリングするだけのコントローラー アクションを作成しました。
    public ActionResult Index()
    {
        return View(new CheckboxViewModel());
    }
    
  3. フォーム付きのビューを作成しました
    @using (Ajax.BeginForm("Post", "api/Values", null, new AjaxOptions { HttpMethod = "POST" }, new { id = "form" }))
    {
        @Html.ValidationSummary(true)
        @Html.LabelFor(model => model.TestCheckbox)
        @Html.EditorFor(model => model.TestCheckbox)
        @Html.ValidationMessageFor(model => model.TestCheckbox)
        <input type="submit" value="Submit" />
    }
    
  4. modelstate が有効かどうかを確認し、ステータス コード 200、そうでない場合は 400 を返す Web API アクションを作成しました。
    public HttpResponseMessage Post(CheckboxViewModel model)
    {
        if (!ModelState.IsValid)
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    

私はいくつかのグーグルを行っており、チェックボックスのエディターが追加の非表示フィールドをレンダリングすることを知っていますが、それは問題ないようで、モデルバインディングに必要です。したがって、チェックボックスをオフにしてフォームを送信すると、すべてが正常に機能し、サーバーは非表示フィールドのおかげでステータス 200 を返します。ただし、チェックボックスをオンにしてフォームを送信すると、サーバーはステータス 400 で応答します。これは、ModelState が無効な状態であることを意味します。この場合の ModelState には、空の ErrorMessage と次の例外メッセージを伴うエラーが含まれます。

{System.InvalidOperationException: The parameter conversion from type 'System.Collections.Generic.List`1[System.String]' to type 'System.Boolean' failed because no type converter can convert between these types.
   в System.Web.Http.ValueProviders.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
   в System.Web.Http.ValueProviders.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType)
   в System.Web.Http.ValueProviders.ValueProviderResult.ConvertTo(Type type, CultureInfo culture)
   в System.Web.Http.ValueProviders.ValueProviderResult.ConvertTo(Type type)
   в System.Web.Http.ModelBinding.Binders.TypeConverterModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)}

これを適切に処理する方法がわかりません。カスタム モデル バインダーを作成する必要がありますか? または、何か不足していますか?どんな助けでも大歓迎です。ありがとう。

私の問題を再現するソリューションを作成しました。

更新:フォームには実際に値TestCheckbox: trueとが含まれていることがわかったTestCheckbox:falseので、これはおそらくバインダーに何らかの影響を与え、例外がスローされると思います。これを回避する方法はまだありません。

4

2 に答える 2

2

JavaScript を使用してフォームを Web API に送信するという同じ問題に遭遇しました。この問題を回避するために使用できる基本的な修正方法を次に示します。私はそれが一種の単純化された、または醜いものであることを知っています - そして、チェックボックスがたくさんある場合はあまり実用的ではありません. ただし、アイデアは単純であり、要件に合わせて簡単に拡張できます。

フォームを投稿する前にこれを追加します (jQuery を使用):

if ($('[name="MyCheckbox"]:checked').length > 0)
    $('[name="MyCheckbox"]:hidden').detach();
else if ($('[name="MyCheckbox"]:hidden').length < 1)
    $('#myForm').append('<input type="hidden" name="MyCheckbox" value="false" />');

// Etc...
$.ajax({ });

したがって、チェックボックスがチェックされている場合は隠しフィールドを削除し、チェックボックスがチェックされておらず、隠しフィールドがすでに削除されている場合は追加します。

このフィドルを参照してください: http://jsfiddle.net/Hsfdg/

于 2012-10-16T10:23:16.163 に答える
1

私はこれを実装しようとしました

if ($('[name="MyCheckbox"]:checked').length > 0)
    $('[name="MyCheckbox"]:hidden').detach();
else if ($('[name="MyCheckbox"]:hidden').length < 1)
    $('#myForm').append('<input type="hidden" name="MyCheckbox" value="false" />');

しかし、非表示のチェックボックスが切り離されると、モデルプロパティが削除されてしまいました。

代わりに、非表示のチェックボックスの値を true に設定すると、モデル プロパティが true に設定されます。それ以外の場合は、デフォルトで false が期待されます。

if ($('[name="MyCheckbox"]:checked').length > 0)
    $('[name="MyCheckbox"]:hidden').val(true);
于 2012-11-01T03:43:00.790 に答える