Search code examples
visual-studioweb-servicesmsbuildmsbuild-task

Is It Possible to Update a WCF Service Reference in a Web Deployment Project


I think the question title neatly sums up what I am after. I have a web app and a service and I would like the build script to check if the service has been updated since the last build and if so, run the "update service reference" script that is available when you right-click on a service.

Any ideas?


Solution

  • We use a PowerShell script to run the wsdl.exe tool for us(or in your case svcutil.exe). The script runs out to the service and pulls a fresh wsdl and re-gens the proxy. You can use to get to PS. The only trickery is to get the namespacing correctly, but there is an option on wsdl.exe for that.

    <Target Name="UpdateWebReferences">
    
    <Exec WorkingDirectory="$(SolutionRoot)" 
          Command="$(PS) -Noninteractive -Command $(SolutionRoot)\tools\PowerShell\Compile-Wsdl.ps1 -ukf $(ConfigFilePath)" 
          Condition=" Exists('$(ConfigFilePath)') And Exists('$(SolutionRoot)\tools\PowerShell\Compile-Wsdl.ps1') " />
    

    The above goes in your team build. The meat of the powershell function is as follows:

    $projectFile = [xml]( Get-Content $projectFilePath ) 
    
    if ( $projectFile -and $WSDL_LANGUAGE -ne "VB")
    {
        $ns = $projectFile.Project.PropertyGroup[ 0 ].RootNamespace
    }
    else
    {
        $ns = $NAMESPACE_PREFIX
    }
    
    foreach( $webRefDir in Get-ChildItem $dir.FullName )
    {
        $webRefName = $webRefDir.Name
    
        if ( [System.String]::IsNullOrEmpty( $ns ) )
        {
            $namespace = $webRefName
        }
        else
        {
            $namespace = $( "{0}.{1}" -f $ns, $webRefName )
        }
    
        Write-Host $( "Compiling Web Reference: {0} using Namespace: {1}..." -f $webRefName, $namespace )
    
        $outputPath = $( "{0}\{1}" -f $webRefDir.FullName,$REFERENCE_FILE )
    
        $xpath = "/configuration/appSettings/add[@key='{0}']" -f $webRefName
    
        if ( $URL_KEY_FILE )
        {
            $xml = [xml](Get-Content $URL_KEY_FILE)
            $url = $xml.SelectSingleNode( $xpath )
    
            if ( $url )
            {
                $urlOrPath = $url.Value
            }
            else
            {
                Write-Warning $( "Could not find key {0} in {1}..." -f $webRefName, $URL_KEY_FILE )
            }
        }
        else
        {
            $urlOrPath = $( Get-ChildItem $webRefDir.FullName -r -filter "*.wsdl" ).FullName
        }   
    
        if ( $urlOrPath )
        {
            wsdl /nologo /language:$WSDL_LANGUAGE /n:$namespace /o:$outputPath /urlkey:$webRefName $urlOrPath
        }
    
        Write-Host "....................................................."
    }
    

    All that is required for this is you must have the "Web References" folder checked in. It loops over each directory and creates the correct namespace. The script is long, but I'd be willing to email it.