忒IPP REST API查询字符串逃生 [英] Intuit IPP Rest API query string escape

查看:170
本文介绍了忒IPP REST API查询字符串逃生的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,对于忒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 =htt​​p://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 =htt​​p://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: &lt;EOF&gt; after : &quot;\'A&quot;</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&amp;B</FullyQualifiedName>
        <DisplayName>A&amp;B</DisplayName>
        <PrintOnCheckName>A&amp;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屋!

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