忒IPP REST API查询字符串逃生 [英] Intuit IPP Rest API query string escape
问题描述
所以,对于忒IPP REST API ,
说如果我要查询的客户是谁的名字是ABC,我可以使用一个HTTP GET这样的要求
https://qb.sbfinance.intuit.com/v3/company/198445012/query?query=select标识从客户那里FullyQualifiedName%3D'ABC
&放大器; 3D是'='A URL转义,这工作没有任何问题。
现在如果客户的名称是A和B,我试图查询字符串这样
从客户选择ID其中FullyQualifiedName ='A和B'
URL编码后,它看起来像这样
https://qb.sbfinance.intuit.com/v3/company/198445012/query?query=select标识从客户那里FullyQualifiedName%3D'A%26B
这将会失败。
任何想法?
更新
以上网址我从IPP的API资源管理器中复制。
下面是code,我使用 DevDefined。 OAuth的
IConsumerRequest conReq = _oSession.Request();
conReq = conReq.Get();
conReq.AcceptsType =application / xml进行;
// conReq = conReq.ForUrl(的String.Format(@https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1},Settings.Default.QuickBooksOnlineRealmId,@ SELECT * FROM客户,其中显示名称='ABC'));如果使用这一行,它工作正常
conReq = conReq.ForUrl(的String.Format(@https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1},Settings.Default.QuickBooksOnlineRealmId,@选择*从客户那里显示名称='A和B'));
尝试
{
字符串str = conReq.ReadBody(); 赶上(异常前)
{
//ex.Message
}
返回的XML数据像这样
<?XML版本=1.0编码=UTF-8独立=YES&GT?;
< IntuitResponse的xmlns =http://schema.intuit.com/finance/v3时间=2014-03-20T06:24:12.408-07:00>
<故障类型=ValidationFault>
<错误code =4000>
<消息>错误分析查询和LT; /信息>
<详情> QueryParserError:无效的内容。在1号线词法错误,列44。遇到:放大器; LT; EOF和放大器; GT;后:放大器; QUOT; \\'A和QUOT;< /详情>
< /错误>
< /故障>
< / IntuitResponse>
我不是100%肯定,昨天当我测试,它实际上返回的东西说的OAuth失败。但是,这是我今天早上。
其实,你可以IPP的API Explorer中试试吧,它给出了相同的结果。
该devdefined的code为ForUrl
公共静态IConsumerRequest ForUrl(这IConsumerRequest要求,字符串URL)
{
request.Context.RawUri =新的URI(URL);
返回请求;
}
这将连接code中的网址为
<$p$p><$c$c>https://qb.sbfinance.intuit.com/v3/company/1122502005/query?query=select%20*%20from%20Customer%20where%20DisplayName='A&B'好吧,最后后,发现这个问题:
真正的问题是开放的(URL)将难逃&放大器;在A和B',因为它不知道它是否是一个URL和放大器;或数据的一部分,所以我改变了以下行
conReq = conReq.ForUrl(的String.Format(@https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1 },Settings.Default.QuickBooksOnlineRealmId,@SELECT * FROM客户,其中显示名称='A和B'));
为
conReq = conReq.ForUrl(的String.Format(@https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1 },Settings.Default.QuickBooksOnlineRealmId,Uri.EscapeDataString(@SELECT * FROM客户,其中显示名称='A和B')));
使用Uri.EscapeDataString先躲避数据查询字符串。
如果您创建一个名客户A和B',那么V3的服务回报客户对象像下面 -
&LT;?XML版本=1.0编码=UTF-8独立=YES&GT?;
&LT; IntuitResponse的xmlns =http://schema.intuit.com/finance/v3时间=2014-03-20T01:54:46.834-07:00&GT;
&LT;客户域=QBO疏=false的&GT;
&LT;标识大于10&LT; / ID&GT;
&所述; SyncToken大于0&下; / SyncToken&GT;
&LT;元数据&GT;
&LT; CreateTime&GT; 2014-03-20T01:54:46-07:00&LT; / CreateTime&GT;
&LT; LastUpdatedTime&GT; 2014-03-20T01:54:47-07:00&LT; / LastUpdatedTime&GT;
&LT; /元&GT;
&LT; FullyQualifiedName&gt;一种&放大器;放大器; B&LT; / FullyQualifiedName&GT;
&LT;显示名称&gt;一种&放大器;放大器; B&LT; /显示名称&GT;
&LT; PrintOnCheckName&gt;一种&放大器;放大器; B&LT; / PrintOnCheckName&GT;
&LT;活动&GT;真&LT; /活动&GT;
&LT;应税&GT;真&LT; /应税&GT;
&LT;人才与GT假LT; /招聘&GT;
&LT; BillWithParent&GT;假LT; / BillWithParent&GT;
&LT;余量&GT; 100.00 LT; /平衡&GT;
&LT; BalanceWithJobs&GT; 100.00 LT; / BalanceWithJobs&GT;
&LT; preferredDeliveryMethod&GT;电子邮件和LT; / preferredDeliveryMethod&GT;
&LT; /客户&GT;
&LT; / IntuitResponse&GT;
要按名称检索这个对象,你需要使用下面的查询
SELECT * FROM客户WHERE显示名称='A和B'
但是它需要的URL连接codeD类似以下
SELECT + * + FROM +客户+ WHERE +显示名称+%3D + 27A%26B%27%
Java的code来实现这一点 -
客户客户= GenerateQuery.createQueryEntity(Customer.class);
查询字符串=选择($(客户)),其中($(customer.getDisplayName())EQ(A和B)。)。产生();
//查询输出 - SELECT * FROM客户WHERE显示名称='A和B'
字符串连接codedUrl = URLEn coder.en code(查询,UTF-8);
它完美。 (处理的devkit所有这些pretty井)
希望这回答了你的QTS。
感谢
So, for the Intuit IPP Rest API,
Say if i want to query a customer who's name is ABC, i can use a http get request like this
https://qb.sbfinance.intuit.com/v3/company/198445012/query?query=select Id from Customer where FullyQualifiedName%3D'ABC'
&3D is a url escape of '=', this works without any problem.
Now if the customer's name is A&B, I tried the query string like this
select Id from Customer where FullyQualifiedName='A&B'
After the url encoding, it looks like this
https://qb.sbfinance.intuit.com/v3/company/198445012/query?query=select Id from Customer where FullyQualifiedName%3D'A%26B'
It will fail.
Any Idea?
Update
The above urls i copied from the IPP's API explorer.
Here is the code, I am using DevDefined.OAuth
IConsumerRequest conReq = _oSession.Request();
conReq = conReq.Get();
conReq.AcceptsType = "application/xml";
//conReq = conReq.ForUrl(string.Format(@"https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1}", Settings.Default.QuickBooksOnlineRealmId, @"select * from Customer where DisplayName='ABC'")); if use this line, it works fine
conReq = conReq.ForUrl(string.Format(@"https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1}", Settings.Default.QuickBooksOnlineRealmId, @"select * from Customer where DisplayName='A&B'"));
try
{
string str = conReq.ReadBody();
catch (Exception ex)
{
//ex.Message
}
the returned xml data like this
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-03-20T06:24:12.408-07:00">
<Fault type="ValidationFault">
<Error code="4000">
<Message>Error parsing query</Message>
<Detail>QueryParserError: Invalid content. Lexical error at line 1, column 44. Encountered: <EOF> after : "\'A"</Detail>
</Error>
</Fault>
</IntuitResponse>
I am not 100% sure, yesterday when i test, it actually return something says the oauth failed. But this is what I got this morning.
Actually, you can try it within IPP's API explorer, it gives the same result.
The devdefined's code for ForUrl
public static IConsumerRequest ForUrl(this IConsumerRequest request, string url)
{
request.Context.RawUri = new Uri(url);
return request;
}
That will encode the url as
https://qb.sbfinance.intuit.com/v3/company/1122502005/query?query=select%20*%20from%20Customer%20where%20DisplayName='A&B'
Ok, finally, found the issue:
The real issue is Uri(url) won't escape the & in 'A&B' because it doesn't know if it is a url & or part of the data, So i changed the following line
conReq = conReq.ForUrl(string.Format(@"https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1}", Settings.Default.QuickBooksOnlineRealmId, @"select * from Customer where DisplayName='A&B'"));
as
conReq = conReq.ForUrl(string.Format(@"https://qb.sbfinance.intuit.com/v3/company/{0}/query?query={1}", Settings.Default.QuickBooksOnlineRealmId, Uri.EscapeDataString(@"select * from Customer where DisplayName='A&B'")));
use Uri.EscapeDataString to escape the data query string first.
If you create a customer with name 'A&B', then V3 service returns that customer object like below -
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-03-20T01:54:46.834-07:00">
<Customer domain="QBO" sparse="false">
<Id>10</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2014-03-20T01:54:46-07:00</CreateTime>
<LastUpdatedTime>2014-03-20T01:54:47-07:00</LastUpdatedTime>
</MetaData>
<FullyQualifiedName>A&B</FullyQualifiedName>
<DisplayName>A&B</DisplayName>
<PrintOnCheckName>A&B</PrintOnCheckName>
<Active>true</Active>
<Taxable>true</Taxable>
<Job>false</Job>
<BillWithParent>false</BillWithParent>
<Balance>100.00</Balance>
<BalanceWithJobs>100.00</BalanceWithJobs>
<PreferredDeliveryMethod>Email</PreferredDeliveryMethod>
</Customer>
</IntuitResponse>
To retrieve this object by name, you need to use the following query
SELECT * FROM Customer WHERE DisplayName = 'A&B'
But it needs to be url encoded like following
SELECT+*+FROM+Customer+WHERE+DisplayName+%3D+%27A%26B%27
Java code to achieve this -
Customer customer = GenerateQuery.createQueryEntity(Customer.class);
String query = select($(customer)).where($(customer.getDisplayName()).eq("A&B")).generate();
// Query output - SELECT * FROM Customer WHERE DisplayName = 'A&B'
String encodedUrl = URLEncoder.encode(query, "UTF-8");
It works perfectly. (Devkit handles all these pretty well )
Hope this answers your qts.
Thanks
这篇关于忒IPP REST API查询字符串逃生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!