当显式转换我的新对象时(参见第一行代码),我新创建的 EntityReference 被存储而没有被包装在PSObject中,因此序列化它工作得很好:
$entityRef1 = [Microsoft.Xrm.Sdk.EntityReference](new-object Microsoft.Xrm.Sdk.EntityReference("businessunit", [System.Guid]::NewGuid()))
$unit = new-object Microsoft.Xrm.Sdk.Entity("businessunit")
$unit.Attributes["parentbusinessunitid"] = $entityRef1
$unit.Attributes["parentbusinessunitid"].GetType() # Produces "EntityReference"
# Serialize $unit including the entityRef, and write its xml representation
$serializer = New-Object System.Runtime.Serialization.DataContractSerializer($unit.GetType())
$stream = New-Object System.IO.MemoryStream
$serializer.WriteObject($stream, $unit)
$stream.Flush()
$stream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = New-Object System.IO.StreamReader($stream)
$reader.ReadToEnd()
但是,当我不使用演员表时:
$entityRef1 = (new-object Microsoft.Xrm.Sdk.EntityReference("businessunit", [System.Guid]::NewGuid()))
当我想序列化它时,PowerShell 会抱怨:
Exception calling "WriteObject" with "2" argument(s): "Type 'System.Management.Automation.PSObject' with data contract name 'PSObject:http://schemas.datacontract.org/2004/07/System.Management.Automation' is not expected.
现在,我已经阅读了为什么 Get-Date 似乎返回 DateTime 对象,但 BinarySerializer 表明它返回一个 PSObject?,并且看起来这是同一个问题....除了我使用 PowerShell 3.0($PSVersionTable.psversion
生成版本 3.0.-1.-1)并且该帖子中的“错误”代码片段在我的 PowerShell 环境中运行良好。 ..
在那篇文章中,有人建议PowerShell 3 中基于DLR的新引擎不应再导致这些问题,所以他们对此过于乐观,还是我遇到了其他问题?
编辑:下面的代码产生相同的行为,而不依赖于 CRM SDK。使用强制转换,PowerShell 抱怨无法序列化System.UriBuilder
,而没有强制转换,它抱怨获取System.Management.Automation.PSObject
实例:
# $uriBuilder = [UriBuilder](New-Object UriBuilder)
$uriBuilder = (New-Object UriBuilder)
$dict = new-object Hashtable
$dict["mykey"] = $uriBuilder
$dict["mykey"].GetType() # Produces "UriBuilder"
# Serialize $dict including the uriBuilder, and write its xml representation
$serializer = New-Object System.Runtime.Serialization.DataContractSerializer($dict.GetType())
$stream = New-Object System.IO.MemoryStream
$serializer.WriteObject($stream, $dict)
$stream.Flush()
$stream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = New-Object System.IO.StreamReader($stream)
$reader.ReadToEnd()