Click here to Skip to main content
15,887,135 members
Articles / Programming Languages / Visual Basic
Tip/Trick

SVCUtil User Interface

Rate me:
Please Sign up or sign in to vote.
4.82/5 (6 votes)
26 Aug 2013CPOL3 min read 29.6K   2.3K   10   3
GUI application for running SVCUtil to generate service model code

Application Image

Introduction

Visual Studio's front end implementation for adding service references to the project doesn't quite always work as intended. In addition to this, should there be any errors generating the service references they can be almost impossible to detect as the to the reason.

Running SVCUtil on the other hand, gives you complete control over the generation of the proxy model code, however, it is rather cumbersome to write, especially if you have more than three external references.

The reason for creating the User interface it to try and bride the gap between having to manually type in all the extensive arguments manually and then keep them in some undisclosed location for safety so that no one tampers with it for the next time you may require the service to be generated.

Using the Application

To generate a service reference successfully, add in a Service Reference URL (or in the case where the WSDL and XML Files are known, use the file paths with a space between each file).

The svcutil itself has a timeout of 5 minutes, so in order to combat this issue I implemented a service poll  mechanism utilizing an HTTPClient. The reasoning behind this is that the services I needed to generate were so large that they took nearly 45 minutes to compile the WSDL information after being successfully rebuilt. The HTTPClient ensures that they compile successfully in their hosted environment so they can be delivered successfully when asked for by the svcutil exe.

In the case of WSDL creation, the tick box for bypassing the poll service will need to be checked or the application will fail.

Available .NET and Silverlight Versions

The available .NET and Silverlight versions are determined by the installed SDK instances on the machine on which the application is run. The application will determine from the SDK folders which versions have a viable version of the SVCUtil and SLSVCUtil executables and allow those versions as choices.

How it Works

The application shells out all the work to the SVCUtil or SLSVCUtil directly utilising the process and then just reading the responses. This is done asynchronously utilising the Task Parallelism framework.

C#
Action runProcessAction = () =>
{
    Process process = new Process();
    process.StartInfo = new ProcessStartInfo(GetSVCUtilityFileName(), 
                ConfigViewModel.GetServiceProcessArguments());

    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

    process.OutputDataReceived += 
      new DataReceivedEventHandler(OnServiceProcess_OutputDataReceived);
    process.ErrorDataReceived += 
      new DataReceivedEventHandler(OnServiceProcess_OutputDataReceived);
    process.Start();

    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    process.WaitForExit();

    process.OutputDataReceived -= 
      new DataReceivedEventHandler(OnServiceProcess_OutputDataReceived);
    process.ErrorDataReceived -= 
      new DataReceivedEventHandler(OnServiceProcess_OutputDataReceived);
};

Depending on whether or not the poll service box is ticked, we decide on whether or not the startTask will initialize with the HTTPClient request task or dive straight into the process task.

C#
startTask = System.Threading.Tasks.Task.Factory.StartNew(
    () =>
    {
        // setup the handler, and use the default web proxy
        var handle = new System.Net.Http.HttpClientHandler()
        {
            Proxy = System.Net.HttpWebRequest.GetSystemWebProxy(),
        };

        var client = new System.Net.Http.HttpClient(handle, true);
        client.Timeout = TimeSpan.FromMinutes(ConfigViewModel.Timeout);

        var testResultTask = client.GetAsync(ConfigViewModel.ServiceReference)
            .ContinueWith(messageWithResult =>
            {
                if (messageWithResult.Result.IsSuccessStatusCode == false)
                {
                    throw new Exception("Unable to locate the service reference");
                }
            });

        testResultTask.Wait();
    })
.ContinueWith(t1 => runProcessAction());

 On completion of the run process task however, through either mechanism, the continuation task will let the main form know that this has completed successfully, and add a completed message to messages list.

C#
startTask.ContinueWith(
(completionTask) =>
{
    LoadingText = "Done";

    Messages.Add("--------------------------");
    Messages.Add("Service creation Completed");
    Messages.Add("--------------------------");

    messageShower.ScrollIntoView(Messages.LastOrDefault());

    if (ConfigViewModel.OpenFolderComplete == true)
    {
        OpenOuputFolder();
    }

    IsCompleted = true;
},
System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext())

Interesting Features

The drop-down lists have an interesting caveat in that they bind directly to the enum properties to locate their collections. This is implemented through a little bit of reflection that I came across a while back. The detailing bit though, is that the enum members are marked with an attribute that decides on whether that particular member should or should not be displayed for choice within the collection. It also has a display name property so that an alternate text value can be given - for example, the enum value is CSharp, whereas the display value should be C#.

This is particularly useful as a lot of the time, the enumerations have "default" values that you do not want as selections, but are needed in the background.

In addition to this there is a Converter that will take the display value for the enum such as MyFavouriteProperty and display it as My Favourite Property so that the user sees it correctly. This converter also looks to see if the attribute mentioned above has the display property specified so and uses that instead.

C#
/// <summary>
/// Supported Languages
/// </summary>
public enum AvailableLanguages
{
    /// <summary>
    /// Used for serialisation. Not a valid choice
    /// </summary>
    [Attributes.MemberVisible(false)]
    Unknown = 0,
    
    /// <summary>
    /// The C# Language
    /// </summary>
    [Attributes.MemberVisible(true, DisplayName="C#")]
    CSharp,
    
    /// <summary>
    /// The VB.Net Language
    /// </summary>
    VisualBasic
}

History

  • 25 August 2013 - Initial post.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
pontnou29-Dec-14 22:49
pontnou29-Dec-14 22:49 
Questionsrc download only contains an exe file Pin
rickwright200031-Jul-14 8:03
rickwright200031-Jul-14 8:03 
GeneralMy Vote of 3 Pin
the_BeatJunkie24-Jul-14 1:24
the_BeatJunkie24-Jul-14 1:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.