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
localhost:9766/service.svc?singleWsdl&user=me
Alternatively I could use svcutil
would also work as long as the resulting WSDL is flattened.
I was able to get this to work by doing the following
IContractBehavior
added to it, passing in the desired parameter into the IContractBehavior
class. Metatadaset
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");
}
}
}