发布与NodaTime自动道具模型的WebAPI [英] Posting models with NodaTime auto-props to WebAPI

查看:162
本文介绍了发布与NodaTime自动道具模型的WebAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们是在我们的项目中使用NodaTime时间/日期模型的过程。该项目是一个Web应用程序,使用的WebAPI。当尝试发布包含本地时间自动属性的模型,我们收到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);
});

在(样板) Values​​Controller.cs 文件,我被劫持发表这样:

  // POST API /值
公共无效后(识别TestClass输入)
{
    VAR X =输入;
}公共类识别TestClass
{
    公共本地时间打开{搞定;组; }
    公共本地时间关闭{搞定;组; }
}

在此张贴输入模型(通过邮递员),而不是接收本地时间,我收到错误在这篇文章的末尾。

如果我们重写的TestClass 如图所示,没有出现错误,我们得到正确的本地时间:

 公共类识别TestClass
{
    公共本地时间;
    公共本地时间;
}

有什么我可以做的就是应用与自动属性的工作?虽然我可以(而且可能会)开始更换领域的自动属性,这将是很好理解什么是怎么回事。

下面是整个错误,拥有800任意线条从中间删除:

  {
消息:发生了错误。
exceptionMessage:堆不足,无法继续安全地执行程序这可以不必使用太多堆栈空间堆栈上的调用堆栈或功能上有太多的功能发生。
exceptionType:System.InsufficientExecutionStackException,
堆栈跟踪:在System.Runtime.CompilerServices.RuntimeHelpers.EnsureSufficientExecutionStack()
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(IEnumerable的模型,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata元,ValidationContext validationContext)
    在System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元,ValidationContext validationContext,对象容器,IEnumerable`1验证器)
    在System.Web.Http.Validation.DefaultBodyModelValidator.Validate(对象模型,类类型,ModelMetadataProvider metadataProvider,HttpActionContext ActionContext中,串键preFIX)
    在System.Web.Http.ModelBinding.FormatterParameterBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()
    ---从previous位置堆栈跟踪,其中引发异常的结尾---
    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter.GetResult()
    在System.Web.Http.Controllers.HttpActionBinding&LT; ExecuteBindingAsyncCore&GT; d__0.MoveNext()
    ---从previous位置堆栈跟踪,其中引发异常的结尾---
    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter.GetResult()
    在System.Web.Http.Controllers.ActionFilterResult&LT; ExecuteAsync&GT; d__2.MoveNext()
    ---从previous位置堆栈跟踪,其中引发异常的结尾---
    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    在System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
    ---从previous位置堆栈跟踪,其中引发异常的结尾---
    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
    在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    在System.Web.Http.Dispatcher.HttpControllerDispatcher&下。SendAsync&GT; d__0.MoveNext()
}


解决方案

这似乎是一个问题的WebAPI,但我不完全理解的根本原因,也不是我特别喜欢这个解决方案。然而,根据在这个答案中的code,我想出了一个解决办法:

 公共类CustomBodyModelValidator:DefaultBodyModelValidator
{
    公众覆盖布尔ShouldValidateType(类型类型)
    {
        返回type.Namespace =NodaTime&放大器;!&安培; base.ShouldValidateType(类型);
    }
}

在配置拉姆达(或你正在访问全局的WebAPI配置:

  x.Services.Replace(typeof运算(IBodyModelValidator),新CustomBodyModelValidator());

考虑这个变通方法的黑客攻击,直到我(或其他人)能想出更好的解决方案。谢谢你。

更新:在进一步的研究,似乎这已经张贴到野田时间问题跟踪器的问题#249 以及类似的解决方案。

We are in the process of using NodaTime for time / date models in our project. The project is a web application, using WebAPI. When attempting to post a model containing LocalTime autoprops, we receive an InsufficientExecutionStackException.

In order to isolate our project from this issue, I created a new WebAPI project. Using NuGet, I added NodaTime and NodaTime.Serialization.JsonNet to the project. In Startup.cs, I used ConfigureForNodaTime as such:

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

In the (boilerplate) ValuesController.cs file, I hijacked Post as such:

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

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

When posting this input model (via postman), rather than receiving local times, I receive the error at the end of this post.

If we rewrite TestClass as shown, no errors occur, and we get the correct local times:

public class TestClass
{
    public LocalTime;
    public LocalTime;
}

Is there something I can do to get the application to work with autoprops? While I can (and probably will) start replacing autoprops with fields, it would be nice to understand what's going on here.

Here's the entire error, with 800 arbitrary lines removed from the middle:

{
"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()"
}

解决方案

It appears to be a WebAPI issue, but I don't fully understand the root cause, nor do I particularly like this solution. However, based on the code in this answer, I came up with a workaround:

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

In your configuration lambda (or wherever you are accessing the global WebAPI configuration:

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

Consider this a hack of a workaround until I (or someone else) can figure out a better solution. Thanks.

Update: On further research, it appears this has already been posted to the Noda Time issue tracker as issue #249, and a similar solution was proposed.

这篇关于发布与NodaTime自动道具模型的WebAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆