RESTier PUT/PATCH 未被调用
RESTier PUT/PATCH not being called
目前我正在开发一个安装了 RESTier 1.0 NuGet-Package 的项目。
我正在使用带有一些 DTO 的自定义模型生成器。
为了构建 API,我使用了从 ODataController 继承的控制器。
目前查询或发布数据都没有问题。
当我尝试使用 PATCH 或 PUT 请求更新记录时,没有调用相应的控制器操作,而是出现异常。
- 首先我得到了 ChangeSetPreparer is missing exceptions。
- 更改后我确实得到了空引用异常。
所以为了避免第一个,我添加了一个 ChangeSetInitializer 和一个 SubmitExecutor,我在一些 Github-Source 中找到了它(我记不起来了):
public class ExternalApi : ApiBase
{
public ExternalApi(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
public static new IServiceCollection ConfigureApi(Type apiType, IServiceCollection services)
{
return ApiBase.ConfigureApi(apiType, services)
.AddService<IModelBuilder, CustomModelBuilder>()
.AddService<IChangeSetInitializer, ChangeSetInitializer>()
.AddService<ISubmitExecutor, SubmitExecutor>();
}
private class ChangeSetInitializer : IChangeSetInitializer
{
public Task InitializeAsync(SubmitContext context, CancellationToken cancellationToken)
{
context.ChangeSet = new ChangeSet();
return Task.FromResult<object>(null);
}
}
private class SubmitExecutor : ISubmitExecutor
{
public Task<SubmitResult> ExecuteSubmitAsync(SubmitContext context, CancellationToken cancellationToken)
{
return Task.FromResult(new SubmitResult(context.ChangeSet));
}
}
}
添加这些之后,第一个问题似乎已解决,但我却收到以下堆栈跟踪的空引用异常:
bei
Microsoft.Restier.Publishers.OData.RestierController.CreateResult(Type
resultType, Object result) bei
Microsoft.Restier.Publishers.OData.RestierController.CreateUpdatedODataResult(Object
entity) bei
Microsoft.Restier.Publishers.OData.RestierController.d__3f.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei
Microsoft.Restier.Publishers.OData.RestierController.d__20.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei
System.Threading.Tasks.TaskHelpersExtensions.d__3`1.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei
System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei
System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei
System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) bei
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) bei System.Web.Http.HttpServer.d__0.MoveNext()
这些是我使用的动作签名的示例:
[EnableQuery]
public IQueryable<StoreDTO> Get()
[EnableQuery]
public SingleResult<StoreDTO> Get([FromODataUri] int key)
public async Task<IHttpActionResult> Post(StoreDTO store)
public async Task<IHttpActionResult> Put([FromODataUri] int key, StoreDTO store)
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<StoreDTO> store)
我尝试了多种 JSON- 匹配 DTO 的对象,但即使在调用 Put 或 Patch 之前我仍然遇到空引用异常。
我找到了解决方案或至少是解决方法。
我稍微更改了 WebApiConfig。
而不是:
来自 Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions 的 MapRestierRoute(...)
我现在正在使用:
来自 System.Web.OData.Extensions.HttpConfigurationExtensions
的 MapODataServiceRoute(...)
目前我正在开发一个安装了 RESTier 1.0 NuGet-Package 的项目。 我正在使用带有一些 DTO 的自定义模型生成器。 为了构建 API,我使用了从 ODataController 继承的控制器。 目前查询或发布数据都没有问题。
当我尝试使用 PATCH 或 PUT 请求更新记录时,没有调用相应的控制器操作,而是出现异常。
- 首先我得到了 ChangeSetPreparer is missing exceptions。
- 更改后我确实得到了空引用异常。
所以为了避免第一个,我添加了一个 ChangeSetInitializer 和一个 SubmitExecutor,我在一些 Github-Source 中找到了它(我记不起来了):
public class ExternalApi : ApiBase
{
public ExternalApi(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
public static new IServiceCollection ConfigureApi(Type apiType, IServiceCollection services)
{
return ApiBase.ConfigureApi(apiType, services)
.AddService<IModelBuilder, CustomModelBuilder>()
.AddService<IChangeSetInitializer, ChangeSetInitializer>()
.AddService<ISubmitExecutor, SubmitExecutor>();
}
private class ChangeSetInitializer : IChangeSetInitializer
{
public Task InitializeAsync(SubmitContext context, CancellationToken cancellationToken)
{
context.ChangeSet = new ChangeSet();
return Task.FromResult<object>(null);
}
}
private class SubmitExecutor : ISubmitExecutor
{
public Task<SubmitResult> ExecuteSubmitAsync(SubmitContext context, CancellationToken cancellationToken)
{
return Task.FromResult(new SubmitResult(context.ChangeSet));
}
}
}
添加这些之后,第一个问题似乎已解决,但我却收到以下堆栈跟踪的空引用异常:
bei Microsoft.Restier.Publishers.OData.RestierController.CreateResult(Type resultType, Object result) bei Microsoft.Restier.Publishers.OData.RestierController.CreateUpdatedODataResult(Object entity) bei Microsoft.Restier.Publishers.OData.RestierController.d__3f.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei Microsoft.Restier.Publishers.OData.RestierController.d__20.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Threading.Tasks.TaskHelpersExtensions.d__3`1.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Web.Http.HttpServer.d__0.MoveNext()
这些是我使用的动作签名的示例:
[EnableQuery]
public IQueryable<StoreDTO> Get()
[EnableQuery]
public SingleResult<StoreDTO> Get([FromODataUri] int key)
public async Task<IHttpActionResult> Post(StoreDTO store)
public async Task<IHttpActionResult> Put([FromODataUri] int key, StoreDTO store)
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<StoreDTO> store)
我尝试了多种 JSON- 匹配 DTO 的对象,但即使在调用 Put 或 Patch 之前我仍然遇到空引用异常。
我找到了解决方案或至少是解决方法。 我稍微更改了 WebApiConfig。
而不是: 来自 Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions 的 MapRestierRoute(...) 我现在正在使用: 来自 System.Web.OData.Extensions.HttpConfigurationExtensions
的 MapODataServiceRoute(...)