2012-05-24 10 views
7

साथविषमता मैं newtonsoft json.net का उपयोग कर powershell

function Foo($a, $b) 
{ 
    $o = @{} 
    $o.A = $a 
    $o.B = $b 
    $post = @{} 
    $post.X="x" 
    $post.entity =$o 
    $newton::SerializeObject($post) 
} 

तो

foo "a" "b" 

मैं मिलता है

Exception calling "SerializeObject" with "1" argument(s): "Self referencing loop detected for property 'Value' with type 'System.Management.Automation.PSParameterizedProperty'. Path 'entity.Members[0]'." 

तथापि

function Foo2($o) 
{ 
    $post = @{} 
    $post.X="x" 
    $post.entity =$o 
    $newton::SerializeObject($post) 
} 

foo2 @{a="a"; b="b"} 

ठीक काम करता है। इसके अलावा

function foo3($a, $b) 
{ 
    $o = @{} 
    $o.A = $a 
    $o.B = $b 
    $newton::SerializeObject($o) 
} 

foo3 "a" "b" 

काम करता है लेकिन

foo3 "a" 1 

विफल रहता है

बाद

$o.B= [Int32]::Parse($b.Tostring()) 

सब बहुत अजीब लगता है कौन सा

powershell पर v2 करके काम करने के लिए बनाया जा सकता है खिड़की एस 7, जेसननेट 4.4.5

+1

टिप्पणियों का एक दिलचस्प सेट है यही कारण है, लेकिन मुझे यकीन नहीं कर रहा हूँ आपका सवाल क्या है। आप क्या हासिल करने का प्रयास कर रहे हैं? –

+0

मुझे पूरा यकीन है कि मेरे जवाब ने वास्तव में पुस्तकालय/आदि में बदलाव की आवश्यकता के बिना आपके मुद्दे को हल किया है ... लेकिन मैंने अपने उत्तर पर कोई टिप्पणी नहीं देखी, न ही मेरे उत्तर के लिए एक बाउंटी असाइनमेंट। – Peter

उत्तर

2

स्वयं संदर्भ लूप समस्या के बारे में सब कुछ लगता है .... जिस क्रम में आप चीजें असाइन करते हैं। नीचे दिए गए उदाहरण काम करता है:

function Foo($a, $b) 
{ 
    $o = @{} 
    $post = @{} 

    $post.entity =$o 

    $o.A = $a 
    $o.B = $b 

    $post.X="x" 

    [Newtonsoft.Json.JsonConvert]::SerializeObject($post) 
} 

Foo "a" "b" 

{"entity":{"A":"a","B":"b"},"X":"x"} 

आप प्रकार परिवर्तित तो इससे पहले कि आप तो में इसे पारित यह आपके foo3 समारोह सामान्य रखेंगे:

function foo3($a, $b) 
{ 
    $o = @{} 
    $o.A = $a 
    $o.B = $b 
    [Newtonsoft.Json.JsonConvert]::SerializeObject($o) 
} 


$var2 = [Int32]::Parse((1).Tostring()) 

Foo3 "a" $var2 

{"A":"a","B":1} 
+0

मैं वास्तव में क्या हो रहा था के बारे में एक स्पष्टीकरण चाहता था, मेरे पास पहले से ही एक कार्य दौर है, लेकिन वैसे भी अंक हैं – pm100

9

.NET फ्रेमवर्क से JavaScriptSerializer भी पावरशेल के हैंश को क्रमबद्ध करने में एक ही समस्या है। मुझे PowerShell प्रकार प्रणाली में थोड़ा अजीब लगता है। आप Json.Net को पूरी तरह से छोड़ सकते हैं और अपना खुद का रोल कर सकते हैं।

नीचे आपको शुरू करने के लिए कुछ है। यह संभवतः PowerShell 3 के अंतर्निहित ConvertTo-Json cmdlet के रूप में मजबूत नहीं है, लेकिन मुझे लगता है कि यह अधिकतर पूर्ण है।

यहां आपके उदाहरणों में सभी हैं।

# See below for ConvertTo-Json.psm1 
Import-Module ConvertTo-Json 

function Foo($a, $b) 
{ 
    $o = @{} 
    $o.A = $a 
    $o.B = $b 
    $post = @{} 
    $post.X="x" 
    $post.entity =$o 
    ConvertTo-Json $post 
} 

function Foo2($o) 
{ 
    $post = @{} 
    $post.X="x" 
    $post.entity =$o 
    ConvertTo-Json $post 
} 

function foo3($a, $b) 
{ 
    $o = @{} 
    $o.A = $a 
    $o.B = $b 
    ConvertTo-Json $o 
} 

PS> foo "a" "b" 
{"entity":{"A":"a","B":"b"},"X":"x"} 

PS> foo2 @{a="a"; b="b"} 
{"entity":{"a":"a","b":"b"},"X":"x"} 

PS> foo3 "a" "b" 
{"A":"a","B":"b"} 

PS> foo3 "a" 1 
{"A":"a","B":1} 

और यहाँ PowerShell मॉड्यूल ConvertTo-Json लागू करता है।

# Save these contents to Modules\ConvertTo-Json\ConvertTo-Json.psm1 in your 
# PowerShell documents folder, and load them in your $profile using the 
# "Import-Module ConvertTo-Json" cmdlet. This will make the ConvertTo-Json cmdlet 
# available for use. 

Set-StrictMode -Version Latest 

function convertToJsonNull($InputObject) { 
    "null" 
} 

function convertToJsonArray($InputObject) { 
    $value = ($InputObject | %{ convertToJson $_ }) -join ',' 
    "[$value]" 
} 

function convertToJsonHash($InputObject) { 
    $value = ($InputObject.Keys | %{ 
     $name = $_ | asJsonString 
     $itemValue = convertToJson ($InputObject[$_]) 
     '"{0}":{1}' -f $name, $itemValue 
    }) -join ',' 
    "{$value}" 
} 

function convertToJsonObject($InputObject) { 
    $value = ($InputObject | get-member -membertype *property | %{ 
     $name = $_.Name 
     $value = convertToJson ($InputObject.($name)) 
     '"{0}":{1}' -f ($name | asJsonString), $value 
    }) -join ',' 
    "{$value}" 
} 

function convertToJsonString($InputObject) { 
    '"{0}"' -f ($InputObject | asJsonString) 
} 

function convertToJsonBool($InputObject) { 
    $InputObject.ToString().ToLower() 
} 

function convertToJsonNumeric($InputObject) { 
    "$InputObject" 
} 

function convertToJsonDate($InputObject) { 
    $epoch = [datetime]"1970-01-01T00:00:00Z" 
    $elapsed = [long]($InputObject - $epoch).TotalMilliseconds 
    '"\/Date({0})\/"' -f $elapsed 
} 

filter isNumeric() { 
    $_ -is [byte] -or $_ -is [int16] -or $_ -is [int32] -or $_ -is [int64] -or 
    $_ -is [sbyte] -or $_ -is [uint16] -or $_ -is [uint32] -or $_ -is [uint64] -or 
    $_ -is [float] -or $_ -is [double] -or $_ -is [decimal] 
} 

filter asJsonString { 
    ($_ -replace '\\', '\\') -replace '"', '\"' 
} 

function convertToJson($InputObject) { 
    if  ($InputObject -eq $null)  { convertToJsonNull $InputObject } 
    elseif ($InputObject -is [array])  { convertToJsonArray $InputObject } 
    elseif ($InputObject -is [hashtable]) { convertToJsonHash $InputObject } 
    elseif ($InputObject -is [datetime]) { convertToJsonDate $InputObject } 
    elseif ($InputObject -is [string]) { convertToJsonString $InputObject } 
    elseif ($InputObject -is [char])  { convertToJsonString $InputObject } 
    elseif ($InputObject -is [bool])  { convertToJsonBool $InputObject } 
    elseif ($InputObject | isNumeric)  { convertToJsonNumeric $InputObject } 
    else         { convertToJsonObject $InputObject } 
} 

function ConvertTo-Json { 
    [CmdletBinding()] 
    param(
     [Parameter(
      ValueFromPipeline = $true, 
      ValueFromPipelineByPropertyName = $true 
     )] 
     $InputObject 
    ) 
    convertToJson $InputObject 
} 

Export-ModuleMember -Function ConvertTo-Json 
+0

उस मामले को नोटिस करें जहां मैं एक वैरिएबल असाइन करता हूं जिसका मान 1 है और यह विफल रहता है, लेकिन अगर मैं इसे एक स्ट्रिंग में रूपांतरित करता हूं और फिर इसे एक int में परिवर्तित करता हूं तो यह ठीक काम करता है। – pm100

+0

@ pm100 हां, मैंने देखा कि इसमें कोई हैश नहीं है। आप अभी भी मैन्युअल रूप से परिवर्तित मूल्य को '$ o.B' और' $ o' में असाइन कर रहे हैं वास्तव में हैश है। मेरा समाधान आपको ऐसा करने की अनुमति देगा बिना कॉलर को किसी भी मूल्य पर मैन्युअल चेक करने की आवश्यकता के बिना, या किसी विशेष तरीके से स्रोत ऑब्जेक्ट का निर्माण करने की आवश्यकता के बिना। –

+0

@ pm100 मैंने अभी ऑब्जेक्ट्स और पीएसओब्जेक्ट्स के लिए समर्थन जोड़ा है, इसलिए यदि आप नहीं चाहते हैं तो आपको हैश का उपयोग करने की भी आवश्यकता नहीं है। –

संबंधित मुद्दे