Entries in Sharepoint (1)

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: