14

受信日付を常に英国形式で処理するには、何らかのカスタム モデル バインダーを使用する必要があります。カスタム モデル バインダーをセットアップし、次のように登録しました。

GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new DateTimeModelBinder());

これは、クエリ文字列パラメーターに対してのみ機能するようで、パラメーターに [ModelBinder] を指定した場合にのみ機能するようです。すべてのアクションでモデル バインダーを使用する方法はありますか。

public IList<LeadsLeadRowViewModel> Get([ModelBinder]LeadsIndexViewModel inputModel)

また、投稿されたフォームを Api コントローラーに取得して、モデル バインダーを使用するにはどうすればよいですか?

4

4 に答える 4

6

ModelBinderProvider を実装し、それをサービスのリストに挿入することで、モデル バインダーをグローバルに登録できます。

Global.asax での使用例:

GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, new Core.Api.ModelBinders.DateTimeModelBinderProvider());

以下は、(現在のスレッド カルチャを使用して) カルチャに対応した方法で DateTime 引数を変換する ModelBinderProvider および ModelProvider 実装を示すコード例です。

DateTimeModelBinderProvider の実装:

using System;
using System.Web.Http;
using System.Web.Http.ModelBinding;

...

public class DateTimeModelBinderProvider : ModelBinderProvider
{
    readonly DateTimeModelBinder binder = new DateTimeModelBinder();

    public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
    {
        if (DateTimeModelBinder.CanBindType(modelType))
        {
            return binder;
        }

        return null; 
    }
}

DateTimeModelBinder の実装:

public class DateTimeModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        ValidateBindingContext(bindingContext);

        if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName) ||
            !CanBindType(bindingContext.ModelType))
        {
            return false;
        }

        bindingContext.Model = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName)
            .ConvertTo(bindingContext.ModelType, Thread.CurrentThread.CurrentCulture);

        bindingContext.ValidationNode.ValidateAllProperties = true;

        return true;
    }

    private static void ValidateBindingContext(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }

        if (bindingContext.ModelMetadata == null)
        {
            throw new ArgumentException("ModelMetadata cannot be null", "bindingContext");
        }
    }

    public static bool CanBindType(Type modelType)
    {
        return modelType == typeof(DateTime) || modelType == typeof(DateTime?);
    }
}
于 2013-02-21T16:28:23.760 に答える
5

モデルバインダーは必要ないと思います。あなたのアプローチは正しくありません。日付に対する正しいアプローチは、globalize ライブラリのようなクライアント側のグローバリゼーション ライブラリを使用して任意の言語でフォーマットされた日付を解析し、それらを JavaScript 日付オブジェクトに変換することです。次に、ブラウザを使用してJSONでdatascriptデータ構造をシリアル化できますJSON.stringify。これは機能するはずです。日付には常に標準形式を使用し、モデル バインダーの代わりにフォーマッターを使用することをお勧めします。C# の DateTime オブジェクトのkindパラメータを使用して日時をローカル時間で表すか UTC 時間で表すかを指定すると、使用可能なフォーマッタは TimeZones も正しく処理します。

于 2012-09-09T23:33:22.873 に答える
3

属性ルーティングは、モデル バインディングと競合しているようです。属性ルーティングを使用する場合、global.asax設定を単一のGlobalConfiguration.Config呼び出しにラップして、初期化の問題を回避できます。

GlobalConfiguration.Configure(config =>
{
    config.BindParameter(typeof(DateTime), new DateTimeModelBinder());
    config.MapHttpAttributeRoutes();
}

(バグ #1165に関連する場合、これは今後の ASP.NET 5 で修正される可能性があります。)

于 2014-12-02T20:57:16.330 に答える
0

そのためのカスタム モデル バインダーは必要ありません。スレッド カルチャを UK に変更するか、 web.config 設定を UK に設定することで問題が解決するはずです (これがサイトで常に使用されている場合)。

そうでない場合でも、CurrentCulture の DateTimeFormatInfo を UK のものに変更できます。

Scott Hanselman によるモデル バインダーに関する良い記事もここにあります。

これを Global.asax に入れることができます。

ModelBinders.Binders[typeof(DateTime)] = new DateAndTimeModelBinder()  
于 2012-09-07T18:14:35.960 に答える