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,我使用 la注册了这个模型绑定器

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 时,它将尝试使用默认的 JSON 格式化程序,即标准配置中的 Newtonsoft Json.Net。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);
}

在此之后,您的第二个示例将按预期工作,并且如果输入的格式不正确,ModelState.IsValid则将是falseNoda Time。

有关 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 回答