我正在使用PowerShell的Box.V2 SDK。 我打电话给这里记录的方法:
https://github.com/box/box-windows-sdk-v2/blob/master/Box.V2/Managers/BoxUsersManager.cs
这是我的代码:
# Load Assemblies
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\System.IdentityModel.Tokens.Jwt.5.1.4\lib\net45\System.IdentityModel.Tokens.Jwt.dll")
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll")
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\Box.V2.3.3.0\lib\net45\Box.V2.dll")
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\Microsoft.IdentityModel.Logging.1.1.4\lib\net45\Microsoft.IdentityModel.Logging.dll")
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\Microsoft.IdentityModel.Tokens.5.1.4\lib\net45\Microsoft.IdentityModel.Tokens.dll")
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll")
[Reflection.Assembly]::LoadFile("C:\Users\jfrank\Documents\BoxSDKV2\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll")
# Configure
$jsonConfig = Get-content "C:\Users\jfrank\Documents\WindowsPowerShell\Scripts\Box\config.json" | ConvertFrom-Json
$boxConfig = New-Object Box.V2.config.BoxConfig (($jsonConfig.boxAppSettings).clientID, ($jsonConfig.boxAppSettings).clientSecret, $jsonConfig.enterpriseID, (($jsonConfig.boxAppSettings).appAuth).privateKey, (($jsonConfig.boxAppSettings).appAuth).passphrase, (($jsonConfig.boxAppSettings).appAuth).publicKeyID)
$boxJWT = New-Object Box.V2.JWTAuth.BoxJWTAuth ($boxConfig)
# Authenticate
$adminToken = $boxJWT.AdminToken()
$adminClient = $boxJWT.AdminClient($adminToken)
# Get Users
$enterpriseUsers = $adminClient.UsersManager.GetEnterpriseUsersAsync().Result
# Get Admin by name
Foreach ($entry in $enterpriseUsers.Entries) {
if ($entry.Name -eq "Johannes Frank") {
$admin = $entry
}
}
# Get User
$userToken = $boxJWT.UserToken($admin.Id)
$userClient = $boxJWT.UserClient($userToken, $admin.Id)
$fields = [System.Collections.Generic.IEnumerable`1[System.String]]"role, enterprise"
$userClient.UsersManager.GetCurrentUserInformationAsync($fields).Result | Format-List
如果没有参数$ fields,则最后一行完美无缺。但是用参数调用是很乏味的。
我目前正在接受其他尝试以下错误消息:
GAC Version Location
--- ------- --------
False v4.0.30319 C:\Users\jfrank\Documents\BoxSDKV2\System.IdentityModel.Tokens.Jwt.5.1.4\lib\net45\System.IdentityModel.Tokens.Jwt...
False v1.1.4322 C:\Users\jfrank\Documents\BoxSDKV2\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll
False v4.0.30319 C:\Users\jfrank\Documents\BoxSDKV2\Box.V2.3.3.0\lib\net45\Box.V2.dll
False v4.0.30319 C:\Users\jfrank\Documents\BoxSDKV2\Microsoft.IdentityModel.Logging.1.1.4\lib\net45\Microsoft.IdentityModel.Logging...
False v4.0.30319 C:\Users\jfrank\Documents\BoxSDKV2\Microsoft.IdentityModel.Tokens.5.1.4\lib\net45\Microsoft.IdentityModel.Tokens.dll
False v4.0.30319 C:\Users\jfrank\Documents\BoxSDKV2\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
False v4.0.30319 C:\Users\jfrank\Documents\BoxSDKV2\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
Cannot convert the "role, enterprise" value of type "System.String" to type "System.Collections.Generic.IEnumerable`1[System.String]".
At C:\Users\jfrank\Documents\WindowsPowerShell\Scripts\Box\BoxJWTAuth.ps1:34 char:1
+ $fields = [System.Collections.Generic.IEnumerable`1[System.String]]"r ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
Cannot convert argument "fields", with value: "Box.V2.Models.BoxUser", for "GetCurrentUserInformationAsync" to type
"System.Collections.Generic.IEnumerable`1[System.String]": "Cannot convert the "Box.V2.Models.BoxUser" value of type
"Box.V2.Models.BoxUser" to type "System.Collections.Generic.IEnumerable`1[System.String]"."
At C:\Users\jfrank\Documents\WindowsPowerShell\Scripts\Box\BoxJWTAuth.ps1:36 char:1
+ $userClient.UsersManager.GetCurrentUserInformationAsync($fields).Resu ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
有人可以告诉我如何调用此
public async Task<BoxUser> GetCurrentUserInformationAsync(IEnumerable<string> fields = null)
方法及其参数字段?
编辑:你会在那里找到答案:[string []]作为正确的类型转换。还有另外两种方式。
个人评论: 但我现在真的更重视Python。而Python不是GW Basic。我也有类型安全。 花费(浪费)的时间来为参数获取值。在compenstation中我获得了什么样的“安全性”并且还没有完全理解“通用类型”的原因?无论如何,我打算进行单元测试。如果有人喜欢评论这个系统的优势,我很乐意学习。
答案 0 :(得分:2)
我真的看不出这些问题是如何相关的。我以前读过这个答案,我最初的尝试来自那个答案。我花了(可能浪费了)时间试图做那个单一的类型转换。在python中,我会立即分配并拥有正确的类型。你能解释为什么这些问题是相关的,我通过这种类型获得了什么?#34;安全&#34;?
您没有获得任何安全保障。您正在使用原始泛型类创建非常特定类型的对象。当你需要这样做时,情况非常狭窄,这就是为什么它不容易。
看,我从未使用过box-windows-sdk-v2。但是,您的代码告诉我,我需要加载七个程序集并将现有的JSON配置文件仅用于实例Box.V2.config.BoxConfig
。我甚至没有Box用户帐户。了解某人设置仅仅是为了测试您的代码是不合理的。
我看到的是此错误消息:
&#34;无法转换&#34; Box.V2.Models.BoxUser&#34;类型的价值 &#34; Box.V2.Models.BoxUser&#34;输入&#34; System.Collections.Generic.IEnumerable`1 [System.String]&#34;
现在,你的问题和你问的方式让我相信你明白IEnumerable<T>
是什么。但是,现在,我不认为你这样做,所以你还没有尝试过我已经尝试过的东西。
@Andrei的回答是构建自己的自定义类,实现IEnumerable
而不是使用已经完成的任何现有类。但是,根据您提出问题的方式,您所要求的。
所以,让我们从头开始:
IList<T>
,ICollection<T>
和IEnumerable<T>
对象是generic interfaces。它们是C#中的原始类型,允许您构建自定义集合类型。它们还由内置的通用集合类型(如List<T>
和Stack<T>
以及Dictionary<TKey, TValue>
实现。这意味着如果您需要编写需要枚举集合的C#方法,您可以使用IEnumerable<T>
类型编写它,并且它将能够枚举任何对象集合只要该集合实现IEnumerable<T>
接口。即使是System.Array
was extended to include these types,也有一些具体的警告说某些方法会失败:
一维数组实现System.Collections.Generic.IList,System.Collections.Generic.ICollection,System.Collections.Generic.IEnumerable,System.Collections.Generic.IReadOnlyList和System.Collections.Generic.IReadOnlyCollection通用接口。这些实现在运行时提供给数组,因此,泛型接口不会出现在Array类的声明语法中。此外,没有关于接口成员的参考主题,只能通过将数组转换为通用接口类型(显式接口实现)来访问它们。将数组转换为其中一个接口时要注意的关键是添加,插入或删除元素的成员会抛出NotSupportedException。
那么,你的错误信息是什么,&#34;我需要一个实现System.String
接口的IEnumerable<T>
集合的对象。&#34;
这意味着我假设您最初尝试过其中一种:
$fields = "role", "enterprise" # Creates a [System.Object[]], so should error
$fields = @("role", "enterprise") # Creates a [System.Object[]], so should error
PowerShell中的默认数组是[System.Object[]]
类型,因为PowerShell尝试尽可能通用。 PowerShell的命令都接受该类型。但是,当您从已加载的库中调用对象方法时,您实际上是在C#land中工作,而不是在PowerShell中工作。您必须制作符合C#要求的对象。这就是为什么你感觉自己在迷雾中写作系统并没有明确表达它想要的东西。您实际上是使用PowerShell编写C#代码(尝试静态类型)(尝试不进行静态类型化)。
这里的问题是.Net Framework中没有内置的方法来自动将[Object []]转换为实现[IEnumerable [String]]的东西。就像你不能说'Hello' + 1 + 'World'
一样,在Python中,语言并不知道如何为你做转换。
如果上述任何内容无效,您应该尝试其中任何一个:
$fields = [System.String[]]("role", "enterprise") # Creates a [System.String[]], so may work
# [System.String[]] implements [IEnumerable[String]], but not completely
$fields = [System.Collections.Generic.List[System.String]]("role", "enterprise")
# Creates a [List[String]], and should work because that implements [IEnumerable[String]]
$fields = New-Object -TypeName "System.Collections.Generic.List[System.String]"
$fields.Add('role')
$fields.Add('enterprise')
# Also creates a [List[String]]
$fields = New-Object -TypeName "System.Collections.Generic.Stack[System.String]"
$fields.Push('role')
$fields.Push('enterprise')
# Creates a [Stack[String]], and should work because that also implements [IEnumerable[String]]
$fields = New-Object -TypeName "System.Collections.Generic.HashSet[System.String]"
[void]$fields.Add('role')
[void]$fields.Add('enterprise')
# See also System.Collections.Generic.Queue, System.Collections.Generic.SortedSet, System.Collections.Generic.LinkedList, etc.
然而我不知道Box.V2.Models.BoxUser
做了什么,也不知道对象有多挑剔。它实际上需要可能你需要原始的泛型,这就是我所假设的,因为你经历了如此多的麻烦来尝试创建它。这显然也是这里的另一个答案。
至于,#34;当Python如此简单时,为什么PowerShell如此复杂?&#34;:
好吧,你没有在这个脚本中编写PowerShell。你没有。 PowerShell看起来像这样:
Get-ChildItem *.pdf -File | Where-Object {
$_.LastWriteTime -lt $CutoffDate
} | Move-Item -Destination C:\archive\ -Verbose
您在这里做的是使用PowerShell编写解释性C#。您可以这样做,因为PowerShell为您提供了对.Net Framework的完全访问权限,但使用第三方库是一个高级PowerShell主题。它根本不应该是你写的第一个脚本。它大约有30%的PowerShell和70%的C#,你真的需要至少对两者的理解,因为很多惯例使得PowerShell快速且易于使用,一旦你完成就不会工作开始呼叫第三方图书馆。
您必须明白使用PowerShell执行此操作会起作用,但不您的任何库的作者都希望您使用它。 PowerShell不是C#。你会遇到奇怪的库,它没有以PowerShell正常运行的方式实现,因为通过使用PowerShell来实现它,你自动将自己置于一个约1%的开发人员组成的小组中。那个图书馆。 PowerShell 的约定不会 100%与C#和第三方库的约定保持一致。
答案 1 :(得分:1)
&{ # About this http://community.idera.com/powershell/powertips/b/tips/posts/using-custom-scopes
$OFS=', ' # About $OFS https://blogs.msdn.microsoft.com/powershell/2006/07/15/psmdtagfaq-what-is-ofs/
$PSVersionTable # The Powershell version and not only https://stackoverflow.com/questions/1825585/determine-installed-powershell-version
# The way number one to takle the problem
$fields = [activator]::createinstance([System.Collections.Generic.List``1].makegenerictype([System.String]))
$fields.AddRange([string[]]("role", "enterprise"))
# The next three lines are needed just to show the result
$fields.gettype().fullname
$fields.gettype().getInterfaces() | ?{$_.Name.startswith('IEnumerable') -and $_.IsGenericType} | Select -ExpandProperty FullName
"""${fields}"""
rv fields # rv is the alias of Remove-Variable cmdlet
# The way number two
$fields = [System.Collections.Generic.List[System.String]][string[]]("role", "enterprise")
$fields.gettype().fullname
$fields.gettype().getInterfaces() | ?{$_.Name.startswith('IEnumerable') -and $_.IsGenericType} | Select -ExpandProperty FullName
"""${fields}"""
rv fields
# The way number three
$fields = [string[]]("role", "enterprise")
$fields.gettype().fullname
$fields.gettype().getInterfaces() | ?{$_.Name.startswith('IEnumerable') -and $_.IsGenericType} | Select -ExpandProperty FullName
"""${fields}"""
}
Name Value CLRVersion 2.0.50727.8762 BuildVersion 6.1.7601.17514 PSVersion 2.0 WSManStackVersion 2.0 PSCompatibleVersions {1.0, 2.0} SerializationVersion 1.1.0.1 PSRemotingProtocolVersion 2.1 System.Collections.Generic.List`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] "role, enterprise" System.Collections.Generic.List`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] "role, enterprise" System.String[] System.Collections.Generic.IEnumerable`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] "role, enterprise"