这是我的疑问:
var query = breeze.EntityQuery
.from("Mandates").skip(offset).take(pageSize).inlineCount(true);
return manager.executeQuery(query);
在响应标头中,我可以看到服务器返回计数:
X-InlineCount:63
然而,在我做的成功处理程序中:
var results = data.results;
var recordCount = data.inlineCount;
结果包含正确的记录。但是data.inlineCount为null。
为什么?
修改
getAllResponseHeaders不会返回所有标头!我刚刚注意到他们中的大多数都丢失了,包括X-InlineCount。
我相信这是因为我正在进行跨域http请求(网站在localhost中,但我的webapi(Web服务)在域上的服务器上)。怎么解决这个问题?
答案 0 :(得分:3)
我们已经确认了这个问题。我们计划通过将inlineCount
移出标题并进入结果有效负载来修复它,它可能应该放在第一位。没有确定的日期,但很快。
更新:2013年4月18日。我们已在内部实现此修复程序,它通过了我们的测试。我们将在下一个NuGet(1.3.0之后的那个)中部署。当发生这种情况时,我会再次更新这个答案。
通过调整this jsFiddle,我们可以像任何人一样重现这个问题。
小提琴向Breeze服务器发出请求,公开Todos。当然,Breeze服务器与jsFiddle位于不同的域中,因此需要CORS来执行查询和保存操作。
我将getAllTodos
方法更改为以下内容:
function getAllTodos() { var query = breeze.EntityQuery.from("Todos") // added for Cross-Origin inlineCount header testing .orderBy('Description') .skip(1).take(3) .inlineCount(true); log("Getting Todos"); return manager.executeQuery(query) .then(querySucceeded).fail(failed); function querySucceeded(data) { var count = data.results.length; log("Retrieved " + count); // added for Cross-Origin inlineCount header testing log("Inline count: "+ data.inlineCount); log("Headers: " + data.XHR.getAllResponseHeaders()); if (!count) { log("No Todos"); return; } viewModel.items(data.results); } }
@jvrdelafuente - 我很惊讶您推荐的Web.config更改确实有效。我曾经认为对Web.config进行这样的更改只会影响服务器的功能,而不会影响浏览器的功能。
当我检查网络流量时,我可以看到服务器正在发送“X-InlineCount”标头,有或没有您建议的更改。浏览器(至少IE10和Chrome)似乎隐藏了jQuery.AJAX的标题,jQuery.AJAX负责典型的微风应用程序中的AJAX通信。
当我将以下内容添加到查询成功回调中时,我看到了这种效果:
console.log("Headers: " + data.XHR.getAllResponseHeaders());
日志显示服务器实际返回的标头很少。
也许当你添加
<add name="Access-Control-Expose-Headers" value="X-InlineCount" />
到Web.config,服务器可以告诉浏览器将“X-InlineCount”标头暴露给JavaScript客户端是可以的。
我承认我没有调查这种可能性;也许这是短期内可行的解决方案。
但就我们而言,它只是一个乐队助手。我们不希望开发人员担心这种事情; CORS创造了足够的头痛。因此,我们将在有效负载而不是标题中传达inlineCount
...并一起消除这一问题。
答案 1 :(得分:1)
我遇到了同样的问题。您必须配置服务器以公开X-InlineCount标头。如果您使用的是项目ASP .NET Web API,则必须在web.config中添加下一行:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" />
<add name="Access-Control-Expose-Headers" value="X-InlineCount" />
</customHeaders>
</httpProtocol>
另外,我遇到了firefox的问题,但是在最后一个版本的firefox中,问题就解决了。
(哟不需要使用所有的行,这只是一个例子);)
- - - - - - - - 编辑
我忘记了,因为这是日志时间之前。当您进行CORS呼叫时,浏览器首先发送一个Option调用,以检查是否可以进行CORS呼叫以及允许进行哪些操作。因此,您必须在WEB API项目中实现消息处理程序以管理此OPTION调用。实施是下一个:
public class OptionsHttpMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Method == HttpMethod.Options)
{
var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer();
var controllerRequested = request.GetRouteData().Values["controller"] as string;
var supportedMethods = apiExplorer.ApiDescriptions
.Where(d =>
{
var controller = d.ActionDescriptor.ControllerDescriptor.ControllerName;
return string.Equals(
controller, controllerRequested, StringComparison.OrdinalIgnoreCase);
})
.Select(d => d.HttpMethod.Method)
.Distinct();
if (!supportedMethods.Any())
return Task.Factory.StartNew(
() => request.CreateResponse(HttpStatusCode.NotFound));
return Task.Factory.StartNew(() =>
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Headers.Add("Access-Control-Allow-Origin", "*");
resp.Headers.Add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, Security,Token-Access");
resp.Headers.Add("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
resp.Headers.Add("Access-Control-Expose-Headers", "X-InlineCount");
return resp;
});
}
return base.SendAsync(request, cancellationToken);
}
}
如果将其放在web.config中,可以省略下一节。
resp.Headers.Add("Access-Control-Allow-Origin", "*");
resp.Headers.Add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, Security,Token-Access");
resp.Headers.Add("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
resp.Headers.Add("Access-Control-Expose-Headers", "X-InlineCount");
我希望这有助于解决您的问题。
PD:对不起我的英语,这不是我的第一语言。