当使用"startsWith"时,BreezeJS的OData查询网址格式错误. [英] BreezeJS malformed OData query Url when using "startsWith"

查看:55
本文介绍了当使用"startsWith"时,BreezeJS的OData查询网址格式错误.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在尝试使用breezejs 1.3.4执行查询.我的查询如下

  function getContacts(){var query = breeze.EntityQuery.from("Contacts").where("Desc","startsWith","P");返回manager.executeQuery(query).then(getSucceeded).fail(getFailed);} 

"Desc"是我的"Contacts" C#后端模型中的字符串属性.问题是查询URL的格式如下 .../api/Application/Contacts?$ filter = startswith(Desc%2Ctime'P')%20eq%20true

时间一词被添加到"P"之前,并且我在响应中得到此异常

  {"$ id":"1","$ type":"System.Web.Http.HttpError,System.Web.Http","Message":在URI中指定的查询不是有效.","ExceptionMessage":无法识别的'Edm.Time'文字'time'P' 

如果在比较中我使用小写的"p",则构造URL,因为它应该像这样"$ filter = startswith(Desc%2C'p')%20eq%20true`.

使用其他英文字母的UpperCase字母时,我没有相同的问题.

有人知道我想念的东西吗,我不知道为什么在该特定查询中添加了时间"一词?

谢谢.

解决方案

我们能够重现该问题.

虽然异常消息令人困惑,但我认为您可能会收到错误消息,因为您尚未将资源名称"Contacts"与可能是"Contact"的 EntityType 相关联.

发生的事情是,当Breeze尝试构建查询时,它通常将使用其元数据来正确设置要发送到服务器的url查询字符串的格式.此过程的关键部分涉及确定与查询的'from'子句中给出的 resourceName 相关的 EntityType (在您的情况下为"Contacts").Breeze使用资源名称到实体类型映射来执行此操作,但是如果找不到映射,它仍将继续构建url,因为我们仍然需要针对没有元数据的端点支持临时请求.

您可以通过 MetadataStore.setEntityTypeForResourceName 方法.如果您使用的是Entity Framework,则最初是根据EDMX模型中的EntityType名称/实体集名称映射来填充此映射的.因此,根据您的情况,您可以修改EDMX模型或直接调用setEntityTypeForResourceName方法.

不幸的是,如果没有元数据,Breeze必须推断查询中的数据类型.因此,就您而言

 "Desc","startsWith","P" 

由于Breeze无法确定"Desc"是您的Contract EntityType的字符串"属性,因此它会尝试基于值"P"来推断"Desc"的"dataType".不幸的是,"P"是有效的ISO8601持续时间"值(一种表达时间"数据类型的方式),因此Breeze错误地尝试构造将"P"视为时间"常量的查询字符串.这就是为什么您的代码使用小写字母"p"(无效的持续时间值)的原因.

此推理逻辑当然可以得到改进,并且我们有一个修复程序将使我们能够完全做到这一点,将在下一个版本中发布.但是,对于这种类型的问题,更好,更通用的解决方案是首先确保正确的"resourceName/entityType"映射.

希望这会有所帮助.

Hello I am trying to execute a query using breezejs 1.3.4 . My query is the following

function getContacts() {

            var query = breeze.EntityQuery
                .from("Contacts").where("Desc", "startsWith", "P");


            return manager.executeQuery(query)
              .then(getSucceeded).fail(getFailed); 

        }

"Desc" is a string property in my "Contacts" C# backend model. Tha problem is that the Query URL is formatted like this .../api/Application/Contacts?$filter=startswith(Desc%2Ctime'P')%20eq%20true

The word time is added before "P" and I get a this exception in the Response

{"$id":"1","$type":"System.Web.Http.HttpError, System.Web.Http","Message":"The query specified in the URI is not valid.","ExceptionMessage":"Unrecognized 'Edm.Time' literal 'time'P''

If in the comparison I use a lower case "p" then the Url is costructed as it should be like this "$filter=startswith(Desc%2C'p')%20eq%20true` .

I don't have the same problem when using other UpperCase letters of the english alphabet.

Does anyone have an idea what am I missing, I can't figure out why the word "time" is added in that specific query?

Thank you.

解决方案

We were able to reproduce the problem.

While the exception message is confusing, I believe you might be getting the error because you have not associated that the resource name 'Contacts' with an EntityType of presumably 'Contact'.

What is happening is that when Breeze tries to build the query it will usually use its metadata to correctly format the url query string to send to the server. The critical part of this process involves determining the EntityType associated with the resourceName given in the 'from' clause of the query ('Contacts' in your case). Breeze uses a resource name to entity type map to do this, but if it cannot find a mapping, it will still continue to build the url because we still need to support ad-hoc requests against endpoints for which we have no metadata.

You can update this map yourself via the MetadataStore.setEntityTypeForResourceName method. If you are using the Entity Framework, this map is initially populated based on the EntityType name/Entity Set name mapping that is part of your EDMX model. So in your case you can either modify your EDMX model or call the setEntityTypeForResourceName method directly.

Unfortunately, without the metadata Breeze has to infer the datatypes in the query. So in your case

"Desc", "startsWith", "P"

since Breeze can't determine that "Desc" is a 'string' property of your Contract EntityType it tries to infer the 'dataType' of "Desc" based on the value 'P'. Unfortunately, 'P' is a valid ISO8601 'duration' value ( a way to express a 'Time' datatype), so Breeze incorrectly tries to construct a query string with 'P' treated as a 'Time' constant. This is why your code works with a lower case 'p' ( not a valid duration value).

This inference logic can certainly be improved and we have a fix that will allow us to do exactly that coming out in the next release. However... the better and more general solution to this type of issue is to get the 'resourceName/entityType' mappings correct in the first place.

Hope this helps.

这篇关于当使用"startsWith"时,BreezeJS的OData查询网址格式错误.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆