我有asp.net核心1.1.0项目并尝试CodeCamp示例模型。在这个我们一个控制器,它返回如下的Lookup数据:
[BreezeController]
public class BreezeController : ApiController
{
[HttpGet]
public object Lookups()
{
var rooms = _repository.Rooms;
var tracks = _repository.Tracks;
var timeslots = _repository.TimeSlots;
return new { rooms, tracks, timeslots };
}
上面的Lookups在dataContext.js中调用如下:
function getLookups() {
return EntityQuery.from('Lookups')
.using(manager).execute()
.to$q(querySucceeded, _queryFailed);
function querySucceeded(data) {
log('Retrieved [Lookups]', data, true);
return true;
}
}
现在,我试图在我的项目中按照上面的说法进行操作,它给出了如下错误:
获取http://Localhost:12345//breeze/demo/Lookups 500(内部服务器错误) 未接受(承诺)
错误:无法将此端点转换为IQueryable
上述问题的任何解决方案......在John Papa的Code camper项目中工作正常。如果我在浏览器中运行它而不是使用breezejs,我的web api查找代码工作正常。
答案 0 :(得分:0)
Breeze的.NET Core实现需要一个隐藏的第一个参数。它使用它执行REST操作的IQueryable过滤。例如,如果您有一个如下所示的操作:
[HttpGet]
public IQueryable<Order> Orders()
您想获取状态为123且价格低于$ 10的所有订单,则第一个参数将如下所示:
{
"where":{
"Status":123,
"Cost":{
"lt":10
}
},
"select":[
"OrderId"
]
}
与以前的版本有很大不同。可以通过添加以下内容来更改客户端以传递与此兼容的参数:
breeze.config.initializeAdapterInstance("uriBuilder", "json");
我将此添加到了fetchMetadata调用中。
但是,如果您有带有参数的特定get方法,并且想从Swagger或其他应用程序中调用它,则会导致很多问题。
类似这样的东西:
[HttpGet]
public IQueryable<Order> GetOrdersByStatusAndLessThanCost(int status, int cost)
将生成这样的网址:
GetOrdersByStatusAndLessThanCost?status=123&cost=10
Breeze假定第一个参数(status = 123)是其JSON。因此,它尝试将其解析出来。
在将Breeze迁移到.NET Core时,这是第一个最常见的错误:
此EntityQuery ctor需要一个有效的json字符串。以下不是json:status = 123
如果您碰巧通过了Json,但结果不是IQueryable,那么您将收到此错误:
无法将此端点转换为IQueryable
所有这些的关键是轻而易举地寻找所需的内容。对于上面的示例,以下URL将起作用:
GetOrdersByStatusAndLessThanCost?{}&status=123&cost=10
请注意添加的{}&
作为第一个参数。这告诉微风,就过滤而言,没有任何期望。
要使其适用于Swashbuckle(并扩展为Swagger \ Open API),请将其添加到ConfigureServices
调用内的Startup.cs services.AddSwaggerGen(c =>
方法中:
c.OperationFilter<AddBreezeParameter>();
然后创建所需的文件:
public class AddBreezeParameter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.MethodInfo.ReturnType.Name.StartsWith("IQueryable"))
{
if (operation.Parameters == null)
{
operation.Parameters = new List<OpenApiParameter>();
}
var exampleString = "<br>\":{}," +
"<br> \"where\":{" +
"<br> \"Status\":123," +
"<br> \"Cost\":{" +
"<br> \"lt\":10" +
"<br> }" +
"<br> }," +
"<br> \"select\":[" +
"<br> \"OrderId\"," +
"<br> \"OrderDateTime\"" +
"<br> ]" +
"<br>}";
var breezeJsonParam = new OpenApiParameter
{
Name = "{\"breezeJson",
In = ParameterLocation.Query,
AllowEmptyValue = true,
Description =
"Json used to query a REST resource. <br>Due to Breeze's nonstandardness and Swashbuckle's not able to customize to allow for it, this MUST start with \":{} and end with } In between those you can put your query if it is appropriate. If you do you must add a comma after the starting value and before you value. Here is an example: " +
exampleString,
AllowReserved = true
};
var schema = new OpenApiSchema {Type = "json", Default = new OpenApiString("\":{}}")};
breezeJsonParam.Schema = schema;
operation.Parameters.Insert(0, breezeJsonParam);
}
else
{
if (operation.Parameters == null)
{
operation.Parameters = new List<OpenApiParameter>();
}
var breezeJsonParam = new OpenApiParameter();
// Breeze looks for the first parameter so it can do an IQueryable Filter on it.
// We want it to not have anything for that parameter if it is not an IQueryable.
breezeJsonParam.Name = "{}&";
breezeJsonParam.In = ParameterLocation.Query;
breezeJsonParam.Description = "Do NOT modify this parameter. (It is here for Breeze compatibility.)";
var schema = new OpenApiSchema {Example = new OpenApiString(" ")};
//var schema = new OpenApiSchema {Type = "string", Default = new OpenApiString("\":{}}")};
breezeJsonParam.Schema = schema;
operation.Parameters.Insert(0, breezeJsonParam);
}
}
}