将JSONAPI.NET升级到最新版本(0.3.0-pre-1)后无法查询单个资源

时间:2015-02-13 19:34:21

标签: asp.net entity-framework json-api

在将JSONAPI.NET升级到最新版本(0.3.0-pre-1)后,我无法查询单个资源(即/ {controller} / {id})。我可以查询所有多个资源端点(即/ {controller})。

它可能与JSONAPI.EntityFramework.Http.ApiController有关,因为我使用System.Web.Http.ApiController创建了一个控制器,它运行正常。我使用了相同的DbContext。

我已经关注/尝试了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&#39; PHT&#39;氪

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> {

    }
}

3 个答案:

答案 0 :(得分:1)

此错误应在https://github.com/SphtKr/JSONAPI.NET/pull/77之后修复。

答案 1 :(得分:0)

确保您的ApiContext类中定义的AssetClass为DBSet<AssetClass> AssetClass

答案 2 :(得分:0)

好的,我在我的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方法返回每个模型类型的正确键名列表。 (提示:如果这在0.2.0中适合你,那么你每次只需返回new List<string> { "Id" }就安全了......因为我最近发现旧的GetKeyNames方法永远都是如此做。); - )