« Battery Conscious: Using your GPS with Android | Main | Debugging JavaScript in IE8 with Developer Tools »
Thursday
Feb042010

Creating a static WSDL through reflection

If you are deploying custom services to a SharePoint site you are accustom to the following steps:

1. Deploy the signed library to the GAC.

2. Deploy the asmx file to \12\TEMPLATE\LAYOUTS\

3. Run disco.exe to generate a disco wsdl file.

4. Copy the asmx file to 12\ISAPI.

5. Modify the disco and wsdl file, rename them, and copy them to the 12\ISAPI

For more info on that read Creating a Custom SharePoint Web Service

To speed up your deployment the following code will open up the service dll, reflect it, and modify the attributes for use in SharePoint. This can be run as a post-build event so the output from your builds are the actual deployable files.

 

string assemblyFile = "C:\\temp\\WebServiceLibrary.dll";
string serviceClassName = "WebServiceLibrary.ClientPortalSvc";
string outFile = "c:\\temp\\test1.txt";
 
// Load the assembly from file
// Note: Assembly will be locked
Assembly assembly = null;
 
try
{
    assembly = Assembly.LoadFile(assemblyFile);
}
catch (Exception ex)
{
    Console.WriteLine("Error loading file " + ex.Message);
    return;
}
 
Type[] types = assembly.GetTypes();
Type referencedType = null;
 
foreach (Type typ in types)
{
    if (typ.FullName.Equals(serviceClassName))
    {
        // Found the requested type
        referencedType = typ;
    }
}
 
if (referencedType != null)
{
    var reflector = new ServiceDescriptionReflector();
    reflector.Reflect(referencedType, "http://localhost/temp.asmx");
 
    using (var ms = new MemoryStream())
    {
        var wtr = new XmlTextWriter(ms, Encoding.ASCII);
        wtr.Formatting = Formatting.Indented;
 
        // Add the SP imports and start element
        wtr.WriteStartElement("%@ Assembly Name=\"Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c\" %>\r\n" +
                              "<%@ Import Namespace=\"Microsoft.SharePoint.Utilities\" %>\r\n" +
                              "<%@ Import Namespace=\"Microsoft.SharePoint\" %>\r\n" +
                              "<% Response.ContentType = \"text/xml\"; %");
 
        reflector.ServiceDescriptions[0].Write(wtr);
 
        // Read the XML into a string
        ms.Position = 0;
        var reader = new StreamReader(ms);
        var xmlString = reader.ReadToEnd();
        ms.Position = 0;
        wtr.Close();
 
        // Rewrite the soap address for SP. This will allow the soap:address to be
        // correct regardless of service name or request location
        string spLocation =
            " location=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request))" +
            ",Response.Output); %> />";
 
        xmlString = Regex.Replace(xmlString, "\\<soap\\:address.*", "<soap:address" + spLocation);
        xmlString = Regex.Replace(xmlString, "\\<soap12\\:address.*", "<soap12:address" + spLocation);
 
        // Out to a file
        using (StreamWriter fileStream = new StreamWriter(outFile))
        {
            fileStream.Write(xmlString);                        
        }
        
    }
}
else
{
    throw new Exception("The " + serviceClassName + " was not found in " + assemblyFile);
}
}

 

Download:

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>