【问题标题】:RESTier PUT/PATCH not being calledRESTier PUT/PATCH 未被调用
【发布时间】:2023-03-06 00:34:01
【问题描述】:

目前我正在开发一个安装了 RESTier 1.0 NuGet-Package 的项目。 我正在使用带有一些 DTO 的自定义模型构建器。 为了构建 API,我使用从 ODataController 继承的控制器。 查询或发布数据到现在都没有问题。

当我尝试使用 PATCH 或 PUT 请求更新记录时,相应的控制器操作不会被调用,而是会出现异常。

  1. 首先我确实得到了 ChangeSetPreparer is missing exceptions。
  2. 更改后我确实得到了空引用异常。

所以为了避免第一次,我添加了一个 ChangeSetInitializer 和一个我在一些 Github-Source 中找到的 SubmitExecutor(我不记得了):

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));
    }
}
}

添加这些之后,第一个问题似乎得到了解决,但是我得到了以下堆栈跟踪的空引用异常:

贝 Microsoft.Restier.Publishers.OData.RestierController.CreateResult(类型 resultType, Object 结果) bei Microsoft.Restier.Publishers.OData.RestierController.CreateUpdatedODataResult(对象 实体)北 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)贝 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)贝 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)贝 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)贝 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)贝 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)贝 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(任务 任务)贝 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)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)

我尝试了多种与 DTO 匹配的 JSON 对象,但即使在调用 Put 或 Patch 之前,我仍然会收到空引用异常。

【问题讨论】:

  • 我不确定这是否有帮助,但我知道您过去必须启用 PUT 和 OPTIONS,并且可能在站点中启用 PATCH 请求,因为默认情况下框架不会启用此功能。您能否对全新的 Web api 端点执行 PUT 或 PATCH 请求作为确认动词已启用的测试?
  • 或者使用AcceptVerbs 属性装饰方法以确保调用这些方法
  • 实际上我已经构建了另一个仅使用 EntityFramework 的 RESTier 服务。 Thar 服务与 GET/POST/PUT/PATCH 一起工作得很好。我必须配置我的 applicationhost 文件和 webconfig。我对这两个服务使用相同的配置。
  • 好的。我已经删除了我的以防万一的答案,因为你已经确认它有效
  • @danrichardson AcceptVerbsAttribute 不会改变行为。我试过了。

标签: c# .net asp.net-web-api2 odata restier


【解决方案1】:

我找到了解决方案,或者至少找到了解决方法。 我稍微改变了我的 WebApiConfig。

而不是: 来自 Microsoft.Restier.Publishers.OData.HttpConfigurationExtensions 的 MapRestierRoute(...) 我现在正在使用: MapODataServiceRoute(...) 来自 System.Web.OData.Extensions.HttpConfigurationExtensions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 2020-01-09
    • 2017-01-05
    相关资源
    最近更新 更多