升级 JSONAPI.NET 到最新版本 (0.3.0-pre-1) 后无法查询单个资源
Can not query a single resource after upgrading JSONAPI.NET to latest version (0.3.0-pre-1)
升级 JSONAPI.NET 到最新版本 (0.3.0-pre-1) 后,我无法查询单个资源(即 /{controller}/{id})。我可以查询所有多个资源端点(即 /{controller})。
它可能与 JSONAPI.EntityFramework.Http.ApiController
有关,因为我已经使用 System.Web.Http.ApiController
创建了一个控制器并且它工作正常。我使用了相同的 DbContext。
我有 followed/tried 来自 JSONAPI.TodoMVC.API 的所有代码。
这是我得到的错误:
{
"errors": [
{
"id": "6b49c8a9-d7b4-473e-80cd-c771fe1e7d13",
"status": "500",
"title": "System.AggregateException",
"detail": "One or more errors occurred.",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The Type AssetClass was not found in the DbContext with Type ApiContext",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The member with identity 'ConeTec.DataServices.Web.Areas.WebApi.Models.AssetClass' does not exist in the metadata collection.\r\nParameter name: identity",
"inner": null,
"stackTrace": " at System.Data.Entity.Core.Metadata.Edm.ItemCollection.GetItem[T](String identity, Boolean ignoreCase)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)"
},
"stackTrace": " at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyProperties(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetByIdAsync(Type type, Object[] idValues)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.<GetByIdAsync>d__0`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at JSONAPI.Http.ApiController`1.<Get>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()"
}
}
]
}
知道为什么会出现此错误吗?
谢谢!
S'pht'Kr
@S'pht'Kr
csantero
@csantero
这是完整的错误跟踪:
{
"errors": [
{
"id": "57a5f40e-b170-407f-982a-c7cad64539e9",
"status": "500",
"title": "System.AggregateException",
"detail": "One or more errors occurred.",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The Type AssetClass was not found in the DbContext with Type ApiContext",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The member with identity 'ConeTec.DataServices.Web.Areas.WebApi.Models.AssetClass' does not exist in the metadata collection.\r\nParameter name: identity",
"inner": null,
"stackTrace": " at System.Data.Entity.Core.Metadata.Edm.ItemCollection.GetItem[T](String identity, Boolean ignoreCase)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)"
},
"stackTrace": " at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyProperties(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetByIdAsync(Type type, Object[] idValues)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.<GetByIdAsync>d__0`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at JSONAPI.Http.ApiController`1.<Get>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()"
},
"stackTrace": " at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n at System.Threading.Tasks.Task.Wait()\r\n at ConeTec.DataServices.Web.Filters.ApiUserContextAttribute.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func`1 continuation) in c:\CDS\ConeTecGeoDb\ConeTec.DataServices.Web\Filters\UserContextAttribute.cs:line 160\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
]
}
这是我的例子 AssetClassesController
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ConeTec.DataServices.Web.Areas.WebApi.Models;
using JSONAPI.EntityFramework.Http;
namespace ConeTec.DataServices.Web.Areas.WebApi.Controllers {
public class AssetClassesController : ApiController<AssetClass, ApiContext> {
}
}
确保您在 ApiContext class 中将 AssetClass 定义为 DBSet<AssetClass> AssetClass
好的,我正在空气编码...在我的 iPhone...但试一试。
创建自己的 EntityFrameworkMaterializer
子类并覆盖 GetKeyNames
方法,如下所示:
protected override IEnumerable<string> GetKeyNames(Type type)
{
this.DbContext.MetadataWorkspace.LoadFromAssembly(this.DbContext.GetType().Assembly);
return base.GetKeyNames(type);
}
然后在您的 ApiController
覆盖中...
protected override JSONAPI.Core.IMaterializer MaterializerFactory()
{
return new MyMaterializer(new ApiContext());
}
这样做会有些效率低下,但如果这能解决您的问题,那么我可以想办法在库中做什么。
作为备用计划,只需使用重写的 GetKeyNames 方法 return 为每个模型类型创建一个正确的键名列表。 (提示:如果这在 0.2.0 中对你有用,你可以安全地每次简单地 return new List<string> { "Id" }
,因为我最近发现这就是旧的 GetKeyNames 方法所能做的。 );-)
此错误应从 https://github.com/SphtKr/JSONAPI.NET/pull/77 开始修复。
升级 JSONAPI.NET 到最新版本 (0.3.0-pre-1) 后,我无法查询单个资源(即 /{controller}/{id})。我可以查询所有多个资源端点(即 /{controller})。
它可能与 JSONAPI.EntityFramework.Http.ApiController
有关,因为我已经使用 System.Web.Http.ApiController
创建了一个控制器并且它工作正常。我使用了相同的 DbContext。
我有 followed/tried 来自 JSONAPI.TodoMVC.API 的所有代码。
这是我得到的错误:
{
"errors": [
{
"id": "6b49c8a9-d7b4-473e-80cd-c771fe1e7d13",
"status": "500",
"title": "System.AggregateException",
"detail": "One or more errors occurred.",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The Type AssetClass was not found in the DbContext with Type ApiContext",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The member with identity 'ConeTec.DataServices.Web.Areas.WebApi.Models.AssetClass' does not exist in the metadata collection.\r\nParameter name: identity",
"inner": null,
"stackTrace": " at System.Data.Entity.Core.Metadata.Edm.ItemCollection.GetItem[T](String identity, Boolean ignoreCase)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)"
},
"stackTrace": " at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyProperties(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetByIdAsync(Type type, Object[] idValues)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.<GetByIdAsync>d__0`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at JSONAPI.Http.ApiController`1.<Get>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()"
}
}
]
}
知道为什么会出现此错误吗?
谢谢!
S'pht'Kr @S'pht'Kr
csantero @csantero
这是完整的错误跟踪:
{
"errors": [
{
"id": "57a5f40e-b170-407f-982a-c7cad64539e9",
"status": "500",
"title": "System.AggregateException",
"detail": "One or more errors occurred.",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The Type AssetClass was not found in the DbContext with Type ApiContext",
"inner": {
"id": null,
"status": "500",
"title": "System.ArgumentException",
"detail": "The member with identity 'ConeTec.DataServices.Web.Areas.WebApi.Models.AssetClass' does not exist in the metadata collection.\r\nParameter name: identity",
"inner": null,
"stackTrace": " at System.Data.Entity.Core.Metadata.Edm.ItemCollection.GetItem[T](String identity, Boolean ignoreCase)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)"
},
"stackTrace": " at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyNames(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetKeyProperties(Type type)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.GetByIdAsync(Type type, Object[] idValues)\r\n at JSONAPI.EntityFramework.EntityFrameworkMaterializer.<GetByIdAsync>d__0`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at JSONAPI.Http.ApiController`1.<Get>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()"
},
"stackTrace": " at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n at System.Threading.Tasks.Task.Wait()\r\n at ConeTec.DataServices.Web.Filters.ApiUserContextAttribute.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func`1 continuation) in c:\CDS\ConeTecGeoDb\ConeTec.DataServices.Web\Filters\UserContextAttribute.cs:line 160\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
]
}
这是我的例子 AssetClassesController
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ConeTec.DataServices.Web.Areas.WebApi.Models;
using JSONAPI.EntityFramework.Http;
namespace ConeTec.DataServices.Web.Areas.WebApi.Controllers {
public class AssetClassesController : ApiController<AssetClass, ApiContext> {
}
}
确保您在 ApiContext class 中将 AssetClass 定义为 DBSet<AssetClass> AssetClass
好的,我正在空气编码...在我的 iPhone...但试一试。
创建自己的 EntityFrameworkMaterializer
子类并覆盖 GetKeyNames
方法,如下所示:
protected override IEnumerable<string> GetKeyNames(Type type)
{
this.DbContext.MetadataWorkspace.LoadFromAssembly(this.DbContext.GetType().Assembly);
return base.GetKeyNames(type);
}
然后在您的 ApiController
覆盖中...
protected override JSONAPI.Core.IMaterializer MaterializerFactory()
{
return new MyMaterializer(new ApiContext());
}
这样做会有些效率低下,但如果这能解决您的问题,那么我可以想办法在库中做什么。
作为备用计划,只需使用重写的 GetKeyNames 方法 return 为每个模型类型创建一个正确的键名列表。 (提示:如果这在 0.2.0 中对你有用,你可以安全地每次简单地 return new List<string> { "Id" }
,因为我最近发现这就是旧的 GetKeyNames 方法所能做的。 );-)
此错误应从 https://github.com/SphtKr/JSONAPI.NET/pull/77 开始修复。