当使用OData查询字符串时抛出MissingManifestResourceException异常

4
我有一个使用 Microsoft.AspNetCore.OData.vNext 包的 ASP.Net Core Web API 应用程序。当尝试使用查询字符串来利用 OData 功能时,我收到了 MissingManifestResourceException 异常。以下是相关的代码:
[EnableQuery]
[HttpGet()]
public class LocationsController : Controller
{
  public IActionResult GetLocations()
  {
    IQueryable<Location> locationEntities = _locationInfoRepo.GetLocations();
    if (locationEntities == null)
    {
        return NotFound();
    }

    var results = Mapper.Map<IEnumerable<LocationDTO>>(locationEntities);

    return Ok(results);
  }
}

注意:我已经尝试将方法类型从IActionResult更改为IQueryable<>,但没有成功。我还注释掉了Automapper Map方法,以确保没有问题。
以下是使用EF返回数据的方法:
public IQueryable<Location> GetLocations()
{
    return _context.Locations;
}

这是带有查询字符串的URL: http://localhost/api/locations?$filter=Name%20eq%20'Bob'
“Name”是模型中指定的字符串字段,并且是数据库中的列。
堆栈跟踪:
System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture.  Make sure "Microsoft.AspNetCore.OData.SRResources.resources" was correctly embedded or linked into assembly "Microsoft.AspNetCore.OData.vNext" at compile time, or that all the satellite assemblies required are loadable and fully signed.
    at System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(String fileName)
    at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
    at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
    at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
    at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
    at Microsoft.AspNetCore.OData.SRResources.GetString(String name, String[] formatterNames)
    at Microsoft.AspNetCore.OData.SRResources.get_ClrTypeNotInModel()
    at Microsoft.AspNetCore.OData.ODataQueryContext..ctor(IEdmModel model, Type elementClrType, ODataPath path)
    at Microsoft.AspNetCore.OData.EnableQueryAttribute.OnActionExecuted(ActionExecutedContext context)
    at Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.<OnActionExecutionAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
    at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
    at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextExceptionFilterAsync>d__24.MoveNext()

有人能帮我指一下方向吗?

这段内容与IT技术无关。

为了交叉参考我在 WebApi GitHub 项目上与 OData 团队开启的问题,这是该问题的链接:https://github.com/OData/WebApi/issues/955 - Michael Bowman
1个回答

0
我不知道您的解决方案中有什么,但当我遇到这个问题时,只需从我的控制器中删除[RouteAttribute]就可以解决。让我给您展示一个可行的示例。

在Startup.cs文件中应该有:

public void ConfigureServices(IServiceCollection services)
{
    // Your stuff...
    services.AddOData(opt => opt.RoutingConventions
                                    .Insert(0, new DefaultODataRoutingConvention()));
    // Your stuff...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Your stuff...
    var provider = app.ApplicationServices.GetRequiredService<IAssemblyProvider>();
    var model = GetEdmModel(provider);
    app.UseMvc(builder => builder
        .MapODataRoute("odata", model)
        .MapRoute("default", "api/{controller}/{id?}"));
}

private static IEdmModel GetEdmModel(IAssemblyProvider assemblyProvider)
{
    var builder = new ODataConventionModelBuilder(assemblyProvider);
    builder.EntitySet<Product>("Products");

    return builder.GetEdmModel();
}

然后,在您的控制器中应该有:

[EnableQuery]
public class ProductsController : Controller
{        
    private readonly IProductDbContext _dbContext;

    public ProductsController(IProductDbContext dbContext)
    {
         _dbContext = dbContext;
    }        

    [HttpGet]
    public IQueryable<Product> Get()
    {
        return _dbContext.Products.AsQueryable();
    }
}

使用MapODataRoute,OData可以在不需要任何属性或自定义路由的情况下找到ProductController,您可以在这里查看。

因此,不需要RouteAttribute,现在应该可以正常工作了,例如查询“http://localhost:44302/odata/Products?$top=2&$skip=2”。

也许您可以发布更详细的代码,以便我们能够帮助您。希望您解决了问题。


这是一个有趣的解决方案。自从我遇到这个问题以来,我已经转向了完整的.NET架构,并且也转向了完整的OData。它似乎运行良好,但我有点失望我无法使AspNetCore适当地工作。也许在我的下一个项目中,我会再次尝试您的解决方案。感谢您提供的信息! - Michael Bowman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接