如何从类型PSMethod返回有意义的结果

时间:2017-07-21 11:25:34

标签: rest powershell

我正在对政府数据库进行简单的API调用。我对地址字段很感兴趣。虽然它看起来像哈希,但我无法获得值。

以下是API调用:

$searchTerm = "01446754"
$url = "https://api.companieshouse.gov.uk/search?q=$searchTerm"
$apiKey = "myregisteredapikey"

$authVal = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($apikey))

$header = @{
    "Authorization"=$authVal
}

$response = Invoke-RestMethod -Uri $url -Headers $header -Method Get -ContentType 'application/json' 
$results = $response.items
$results

在此示例中,按公司编号搜索,我返回以下数据集:

links                  : @{self=/company/01446754}
description_identifier : {incorporated-on}
kind                   : searchresults#company
company_status         : active
address                : @{premises=Lakeside Works Rocester; postal_code=ST14 5JP; locality=Staffordshire; address_line_1=Uttoxeter}
date_of_creation       : 1979-09-05
address_snippet        : Lakeside Works Rocester, Uttoxeter, Staffordshire, ST14 5JP
description            : 01446754 - Incorporated on  5 September 1979
company_type           : ltd
company_number         : 01446754
title                  : JCB LIMITED

一切都很好,直到我$results.Address返回:

OverloadDefinitions                                                                                        
-------------------                                                                                        
System.Object&, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Address(int ) 

我不确定这是告诉我的。 Intellisense为最后添加了一个括号; (我认为)这表明它是一个对象,所以我尝试了:

PS C:\> $results.Address()
Cannot find an overload for "Address" and the argument count: "0".
At line:1 char:1
+ $results.Address()
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

显然,我不知道我在这里做了什么,但我尝试使用“地址”中返回的其中一个字段。散列:

PS C:\> $results.Address('postal_code')
Cannot convert argument "0", with value: "postal_code", for "Address" to type "System.Int32": "Cannot convert value "postal_code" to type "System.Int32". Error: "Input 
string was not in a correct format.""
At line:1 char:1
+ $results.Address('postal_code')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

所以它似乎想要一个整数,所以我尝试了:

PS C:\> $results.Address(1)
Exception calling "Address" with "1" argument(s): "Operation could destabilize the runtime."
At line:1 char:1
+ $results.Address(1)
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : VerificationException

好的,让我们来看看哪种类型的地址'是:

PS C:\> $results.Address.gettype()

IsPublic IsSerial Name                                     BaseType                                                                                                      
-------- -------- ----                                     --------                                                                                                      
True     False    PSMethod                                 System.Management.Automation.PSMethodInfo

那么如何从PSMethod类型的对象中获取值?

1 个答案:

答案 0 :(得分:1)

好的,我已经知道了。虽然我不确定这是不是最好的方法。我不明白为什么明显的散列表是PSMethod类型。但后来我不是开发人员: - (。

执行$results.Address.Invoke(0).address返回:

PS C:\> $results.Address.Invoke(0).address

address_line_1 locality      postal_code premises               
-------------- --------      ----------- --------               
Uttoxeter      Staffordshire ST14 5JP    Lakeside Works Rocester

所以把它们放在一起,我最终得到:

$searchTerm = "01446754"
$url = "https://api.companieshouse.gov.uk/search?q=$searchTerm"
$apiKey = "myregisteredapikey"


$authVal = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($apikey))

$header = @{
    "Authorization"=$authVal
}

$response = Invoke-RestMethod -Uri $url -Headers $header -Method Get -ContentType 'application/json' 
$results = $response.items

$oData = @()

foreach($company in $results)
{
    $oAddress = $company.address

    $oData += [pscustomobject]@{
        CompanyName = $company.title
        CompanyType = $company.company_type
        CompanyNumber = $company.company_number
        Date = $company.date_of_creation
        Premises = $oAddress.premises
        Town = $oAddress.address_line_1
        Locality = $oAddress.locality
        PostCode = $oAddress.postal_code

    }
}

$oData

虽然在pscustomobject中,我必须删除.invoke(0).并在for循环中创建对象$oAddress

更新

我已经走得更远了。此特定API的问题是每页(或请求)限制为100条记录,因此当记录超过100条时,代码必须遍历页面。

我的初步示例使用了' JCB' (是的,黄色挖掘者!!)作为搜索词。虽然API说有448个结果,但实际上似乎没有,所以我得到了奇怪的结果。我搜索了#34;亚马逊"相反,返回372条记录,一切似乎都很好。

我本可以请求每页1个结果,这会让我的生活变得更简单但是这意味着448个单独的请求,减慢了我的代码并且我发现,我很快收到错误"请求太多&# 34;从服务器,所以必须有一个天花板。显然,这个特定API的开发人员已经考虑了这个项目的每页限制,可以阅读here。就个人而言,我不同意,他们担心的服务器资源占用必须不超过毫秒。如果一个人可以在一个请求中提取所有记录,或者将限制提高到更合理的数量,那么这将使生活变得更加容易,但这是一个政府部门,他们对其他人的看法不同(恕我直言)。

无论如何,作为一项学习练习,它很有用。我已经(没有记录)code on GitHub给任何感兴趣的人。如果您有时间/倾向,请随时改进。我应该把这段代码放到一个模块中,但那是另一天。

欢迎任何改进。

TIA。