我有一个ASPNet Core Web API应用程序,它使用Microsoft.AspNetCore.OData.vNext包.当使用查询字符串尝试使用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 eq’Bob’
“名称”是模型中指定的字符串字段,是数据库中的列.
堆栈跟踪:
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()
有人能指出我正确的方向吗?
解决方法:
我不知道你的解决方案有什么,但是当我遇到这个问题时,我已经解决了从控制器中删除[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,而不需要任何属性或自定义路由,就像你可以看到here一样.
因此,不需要RouteAttribute,此查询“http://localhost:44302/odata/Products?$top = 2& $skip = 2”现在应该可以正常工作.
也许,您可以发布更详细的代码,以便我们能够为您提供帮助.希望你解决了你的问题.