编程语言
首页 > 编程语言> > c# – 使用NodaTime自动道具向WebAPI发布模型

c# – 使用NodaTime自动道具向WebAPI发布模型

作者:互联网

我们正在项目中使用NodaTime作为时间/日期模型.该项目是一个使用WebAPI的Web应用程序.尝试发布包含LocalTime autoprops的模型时,我们会收到InsufficientExecutionStackException.

为了将我们的项目与此问题隔离开来,我创建了一个新的WebAPI项目.使用NuGet,我将NodaTime和NodaTime.Serialization.JsonNet添加到项目中.在Startup.cs中,我使用了ConfigureForNodaTime:

GlobalConfiguration.Configure(x =>
{
    x.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
    x.Formatters.JsonFormatter.SerializerSettings.ConfigureForNodaTime(
    DateTimeZoneProviders.Tzdb);
});

在(样板文件)ValuesController.cs文件中,我这样劫持了Post:

// POST api/values
public void Post(TestClass input)
{
    var x = input;
}

public class TestClass
{
    public LocalTime Open { get; set; }
    public LocalTime Close { get; set; }
}

当发布此输入模型(通过邮递员),而不是接收本地时间时,我在本文末尾收到错误.

如果我们如图所示重写TestClass,则不会发生错误,并且我们得到正确的本地时间:

public class TestClass
{
    public LocalTime;
    public LocalTime;
}

我能做些什么来让应用程序与autoprops一起工作吗?虽然我可以(也可能会)开始用字段替换autoprops,但了解这里发生的事情会很好.

这是整个错误,从中间删除了800个任意行:

{
"message":"An error has occurred.",
"exceptionMessage":"Insufficient stack to continue executing the program safely. This can happen from having too many functions on the call stack or function on the stack using too much stack space.",
"exceptionType":"System.InsufficientExecutionStackException",
"stackTrace":"   at System.Runtime.CompilerServices.RuntimeHelpers.EnsureSufficientExecutionStack()
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(IEnumerable model, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
    at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container, IEnumerable`1 validators)
    at System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, String keyPrefix)
    at System.Web.Http.ModelBinding.FormatterParameterBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
    at System.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
    at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()"
}

解决方法:

它似乎是一个WebAPI问题,但我不完全理解根本原因,我也不特别喜欢这个解决方案.但是,基于the code in this answer,我提出了一个解决方法:

public class CustomBodyModelValidator : DefaultBodyModelValidator
{
    public override bool ShouldValidateType(Type type)
    {
        return type.Namespace != "NodaTime" && base.ShouldValidateType(type);
    }
}

在您的配置lambda(或您访问全局WebAPI配置的任何位置:

x.Services.Replace(typeof(IBodyModelValidator), new CustomBodyModelValidator());

在我(或其他人)可以找到更好的解决方案之前,请考虑这是一种解决方法.谢谢.

更新:在进一步的研究中,它似乎已经作为issue #249发布到Noda Time问题跟踪器,并提出了类似的解决方案.

标签:c,asp-net-web-api,nodatime
来源: https://codeday.me/bug/20190612/1224842.html