1

カスタム IModelBinder を使用して、文字列を NodaTime LocalDates に変換しようとしています。私LocalDateBinderはこのように見えます:

public class LocalDateBinder : IModelBinder
{
    private readonly LocalDatePattern _localDatePattern = LocalDatePattern.IsoPattern;

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType != typeof(LocalDate))
            return false;

        var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (val == null)
            return false;

        var rawValue = val.RawValue as string;

        var result = _localDatePattern.Parse(rawValue);
        if (result.Success)
            bindingContext.Model = result.Value;

        return result.Success;
    }
}

私の WebApiConfig では、このモデルバインダーを を使用して登録しますSimpleModelBinderProvider

var provider = new SimpleModelBinderProvider(typeof(LocalDate), new LocalDateBinder());
config.Services.Insert(typeof(ModelBinderProvider), 0, provider);

これは、タイプ LocalDate のパラメーターを受け取るアクションがある場合はうまく機能しますが、別のモデル内で LocalDate を使用するより複雑なアクションがある場合は、決して起動されません。例えば:

[HttpGet]
[Route("validateDates")]
public async Task<IHttpActionResult> ValidateDates(string userName, [FromUri] LocalDate beginDate, [FromUri] LocalDate endDate)
{
     //works fine
}

[HttpPost]
[Route("")]
public async Task<IHttpActionResult> Create(CreateRequest createRequest)
{
     //doesn't bind LocalDate properties inside createRequest (other properties are bound correctly)
     //i.e., createRequest.StartDate isn't bound
}

これは、モデル バインダーを Web API に登録する方法と関係があると思いますが、何を修正する必要があるのか​​途方に暮れています - カスタム バインダー プロバイダーが必要ですか?

4

1 に答える 1

3

モデル バインダーの型コンバーターCreateRequestが定義されていない複合型です。この場合、Web Api はメディア タイプのフォーマッタを使用しようとします。JSON を使用しているため、標準構成の Newtonsoft Json.Net であるデフォルトの JSON フォーマッタを使用しようとします。Json.Net は、そのままでは Noda Time 型を処理する方法を知りません。

Json.Net で Noda Time 型を処理できるようにするには、NodaTime.Serialization.JsonNetをインストールし、スタートアップ コードに次のようなものを追加する必要があります...

public void Config(IAppBuilder app)
{
    var config = new HttpConfiguration();
    config.Formatters.JsonFormatter.SerializerSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    app.UseWebApi(config);
}

この後、2 番目の例は期待どおりに機能し、入力が正しい形式の Noda Time でない場合になりますModelState.IsValidfalse

Web API でのパラメーター バインディングの詳細については、 http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-apiを参照してください。

于 2015-06-11T16:56:12.047 に答える