Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Powershell to consume a Soap complexType to keep a Soap service hot

I am writing a powershell script that will ping a soap webservice every 10 min to keep it hot and alive so performance will increase. We have tryed numerous techniques in the IIS with application pool idle timeout and just making http req for the wsdl. But it seems that we have to make real request that goes down to the sql server else an idle for 90 min will make it to slow for the requirements.

I have to construct a rather complex search object to be able to make a smart search that will keep the servicelayer cached and hot. The Soap Request Should look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fund="http://www.example.com/cmw/fff/fund" xmlns:tcm="http://www.example.com/cmw/fff/">
   <soapenv:Body>
     <fund:Get>
        <!--Optional:-->
        <fund:inputDTO>
           <fund:Fund>
              <fund:Identity>
                 <fund:Isin>SE9900558666</fund:Isin>
                 <fund:FundBaseCurrencyId>SEK</fund:FundBaseCurrencyId>
              </fund:Identity>
           </fund:Fund>
           <fund:InputContext>
              <tcm:ExtChannelId>Channelman</tcm:ExtChannelId>
              <tcm:ExtId>Rubberduck</tcm:ExtId>
              <tcm:ExtPosReference>Rubberduck</tcm:ExtPosReference>
              <tcm:ExtUser>Rubberduck</tcm:ExtUser>
              <tcm:LanguageId>809</tcm:LanguageId>
           </fund:InputContext>
        </fund:inputDTO>
     </fund:Get>
   </soapenv:Body>
</soapenv:Envelope>`

I try to use the New-WebServiceProxy which work so elegantly in this example by powershellguy. I construct my own Objects as this example from technet.

The powershell code I tried so far is this:

$fundSrvc = New-WebServiceProxy -uri http://myColdServer:82/WSFund.svc?wsdl -NameSpace "tcm"
# all the type are now defined since we called New-WebServiceProxy they are prefixed
# with ns tcm
[tcm.FundInput] $myFundGoofer = new-object tcm.FundInput 
[tcm.Fund] $myFund = new-object tcm.Fund
[tcm.Context] $myInputContext = new-object tcm.Context
[tcm.FundIdentity] $myFundIdentity = New-Object tcm.FundIdentity
# Use these commands to get member of the objects you want to investigat
# $myFundGoofer |Get-Member
# $myFund |Get-Member
# $myInputContext |Get-Member
# $myFundIdentity |Get-Member
$myFundIdentity.Isin="SE9900558666"
$myFundIdentity.FundBaseCurrencyId="SEK"
$myInputContext.ExtChannelId="ChannelMan"
$myInputContext.ExtId="RubberDuck"
$myInputContext.ExtPosReference="RubberDuck"
$myInputContext.ExtUser="RubberDuck"
$myInputContext.LanguageId="809"
$myFund.Identity=$myFundIdentity

$myFundGoofer.Fund = $myFund
$myFundGoofer.InputContext = $myInputContext

#Tada
$fundSrvc.Get($myFundGoofer)

The Error Message does not make sense to me. Its sounds like: Cannot convert the "tcm.FundInput" value of type "tcm.FundInput" to type "tcm.FundInput"

Cannot convert argument "0", with value: "tcm.FundInput", for "Get" to type "tcm.FundInput": "Cannot convert the "tcm.FundInput" value of type "tcm.FundInput" to type "tcm.FundInput"."
At C:\scripts\Service-TestTCM6.ps1:31 char:14
+ $fundSrvc.Get <<<< ($myFundGoofer)
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
like image 276
Patrik Lindström Avatar asked Sep 20 '12 16:09

Patrik Lindström


2 Answers

I followed the link that Christian (credit should go to him, but I do not know how to do that) gave and used the default namespace instead. So now I do not need to restart powershell everytime. Maybe there is another solution to kill the fundSrvc object after each call. But I gave up and went with using the default created crazy long namespace.

Here is the solution that works:

#note no -Namespace argument  
$fundSrvc = New-WebServiceProxy -uri "http://myColdServer/WSFund.svc?wsdl"


#get autogenerated namespace
$type = $fundSrvc.GetType().Namespace
$myFundGooferDt = ($type + '.FundInput')
$myFundDt = ($type + '.Fund')
$myInputContextDt = ($type + '.Context') 
$myFundIdentityDt = ($type + '.FundIdentity') 
# Create the Objects needed
$myFundGoofer = new-object ($myFundGooferDt) 
$myFund = new-object ($myFundDt) 
$myInputContext = new-object ($myInputContextDt)
$myFundIdentity = New-Object $myFundIdentityDt
# Assign values
$myFundIdentity.Isin="SE9900558666"
$myFundIdentity.FundBaseCurrencyId="SEK"
$myInputContext.ExtChannelId="ChannelMan"
$myInputContext.ExtId="RubberDuck"
$myInputContext.ExtPosReference="RubberDuck"
$myInputContext.ExtUser="RubberDuck"
$myInputContext.LanguageId="809"
$myFund.Identity=$myFundIdentity

$myFundGoofer.Fund = $myFund
$myFundGoofer.InputContext = $myInputContext

#Tada
$fundSrvc.Get($myFundGoofer)
like image 79
Patrik Lindström Avatar answered Nov 10 '22 04:11

Patrik Lindström


Your original technique is right, you just need to also include the -class parameter on New-WebServiceProxy. Leave the rest of your code as-is.

I had this exact problem while working with a webservice from PowerShell yesterday. I also had it working by discovering the auto-generated namespace, but that felt a bit too hacky for my liking.

Then I found the solution mentioned here: https://groups.google.com/d/msg/microsoft.public.windows.powershell/JWB5yueLtrg/k0zeUUxAkTMJ

$newWebService = New-WebServiceProxy -uri "http://<server>/webservices/services.php?wsdl" -NameSpace "Service" -Class "<classname>"
like image 4
Daniel.S Avatar answered Nov 10 '22 03:11

Daniel.S