Search code examples
c#wcfwsdl

Passing parameter into WCF metadata


I have a WCF service with a class that implements IContractBehavior and IWsdlExportExtension that generates a WSDL with a user's allowed operations and excludes operations and types they do not have access to.

The limitation of this is however is that for each user, I have to manually change which user I am generating the WSDL for.

I'd like to fix this limitation by passing in the user as part of the request for the metadata for example.

  • localhost/service.svc?user=me
    or
  • localhost:9766/service.svc?singleWsdl&user=me

Alternatively I could use svcutil would also work as long as the resulting WSDL is flattened.


Solution

  • I was able to get this to work by doing the following

    The code

    const string BASE_ADDRESS = 
    "http://localhost:8731/Design_Time_Addresses/CalcService";
    var uri = new Uri(BASE_ADDRESS);
    var user = "userName";
    
    using (var serviceHost = new ServiceHost(typeof(Calc), uri))
    {
      var exporter = new WsdlExporter();
      var endpoint = serviceHost.AddServiceEndpoint(typeof(ICalc),
      new BasicHttpBinding(), "");
      endpoint.Contract.Behaviors.Add(new
      RestrictedOperationsWsdlExportExtensionAttribute(user));
      serviceHost.Open();
      Console.WriteLine("The service is ready: " + user);
      exporter.ExportEndpoint(endpoint);
      if (exporter.Errors.Count == 0)
      {
        var metadataSet = exporter.GetGeneratedMetadata();
        var asy= Assembly.GetAssembly(typeof(WsdlExporter));
        var t = asy.GetType("System.ServiceModel.Description.WsdlHelper",
          true);
        var method = t.GetMethod("GetSingleWsdl", 
          System.Reflection.BindingFlags.Public 
          | System.Reflection.BindingFlags.Static);
        var serviceDescription =
          method.Invoke(null, new object[] {metadataSet})
          as System.Web.Services.Description.ServiceDescription;
        if (serviceDescription != null)
        {
          serviceDescription.Name = "Calc";
          serviceDescription.Write(user + ".wsdl");
        }
      }
    }