Monday 15 September 2014

c# - How to publish the WSDL at the public domain name in a WCF service hosted in an Azure worker role? -



c# - How to publish the WSDL at the public domain name in a WCF service hosted in an Azure worker role? -

i host wcf service in azure worker role. service accessible @ public domain name of cloud services instance (myservice.cloudapp.net), however, links wsdl, , urls within wsdl utilize internal ip address instead, cannot accessed outside. tools add together service reference , wcftestclient.exe not work smoothly should, because seek access internal ip address.

i creating service next code:

roleinstanceendpoint endpoint = roleenvironment.currentroleinstance.instanceendpoints["myserviceendpoint"]; string endpointaddr = string.format( "http://{0}/myinteropservice", endpoint.ipendpoint ); this.servicehost = new servicehost( typeof( myinteropservice ), new uri( endpointaddr ) ); basichttpbinding binding = new basichttpbinding(); servicehost.addserviceendpoint( typeof( imyinteropservice ), binding, "" ); servicemetadatabehavior smb = new servicemetadatabehavior { httpgetenabled = true, httpsgetenabled = true, }; servicehost.description.behaviors.add( smb ); //servicehost.addserviceendpoint( servicemetadatabehavior.mexcontractname, metadataexchangebindings.createmexhttpbinding(), "mex"); not matter whether include line or not. servicehost.open();

what doing wrong? how should configure service utilize public domain name in wsdl well?

update: peter's reply helped me solve problem, in case had add together userequestheadersformetadataaddressbehavior behavior service, after wsdl used public domain name (i guess uses domain client sending request to).

so finish working code following:

roleinstanceendpoint endpoint = roleenvironment.currentroleinstance.instanceendpoints["myserviceendpoint"]; string endpointaddr = string.format( "http://{0}/myinteropservice", endpoint.ipendpoint ); this.servicehost = new servicehost( typeof( myinteropservice ), new uri( endpointaddr ) ); basichttpbinding binding = new basichttpbinding(); servicehost.addserviceendpoint( typeof( imyinteropservice ), binding, "" ); servicemetadatabehavior smb = new servicemetadatabehavior { httpgetenabled = true, httpsgetenabled = true, }; servicehost.description.behaviors.add( smb ); // part solved problem. var requestheaderbehavior = new userequestheadersformetadataaddressbehavior(); this.servicehost.description.behaviors.add(requestheaderbehavior); servicehost.open();

edit: situation complicated bit security binding believe, may bit easier you

okay, there's few issues here. i'll see if can remember them correctly.

firstly, expose endpoints in manner wish don't have right permissions (even if run in elevated context - still need do). it'll throw internal error when tries register endpoint.

i had alter application pool user did have rights (it'll same credentials utilize rdp worker roles.

var roleendpoint = roleenvironment.currentroleinstance.instanceendpoints["sslendpoint"]; this.roleprotocol = roleendpoint.protocol; this.roleport = roleendpoint.ipendpoint.port.tostring(); if (!roleenvironment.isemulated) { this.rolehostname = "yourexternalhostname.com"; var apppooluser = "user"; var apppoolpass = "password"; using (var servermanager = new servermanager()) { string apppoolname = servermanager.sites[0].applications.first().applicationpoolname; var apppool = servermanager.applicationpools[apppoolname]; apppool.processmodel.username = apppooluser; apppool.processmodel.identitytype = processmodelidentitytype.specificuser; apppool.processmodel.password = apppoolpass; apppool.autostart = true; apppool["startmode"] = "alwaysrunning"; apppool.processmodel.idletimeout = timespan.zero; apppool.recycling.periodicrestart.time = timespan.zero; servermanager.commitchanges(); } } else { this.rolehostname = roleendpoint.ipendpoint.address.tostring(); }

this gave me ability configure service below, may need modify needs. pay close attending settings marked of import believe these vital in exposing service.

var clienturl = new uri(string.format("{0}://{1}:{2}/{3}", protocol, ip, port, serviceaddress + clientid)); var contractdescription = contractdescription.getcontract(typeof(tserviceinterface)); var host = new servicehost(typeof(tserviceimplementation), clienturl); var servicebehaviorattribute = new servicebehaviorattribute(); servicebehaviorattribute.addressfiltermode = addressfiltermode.any; // of import servicebehaviorattribute.concurrencymode = concurrencymode.multiple; servicebehaviorattribute.instancecontextmode = instancecontextmode.percall; host.description.behaviors.remove<servicebehaviorattribute>(); host.description.behaviors.add(servicebehaviorattribute); var servicemetadatabehavior = new servicemetadatabehavior(); servicemetadatabehavior.httpgetenabled = false; servicemetadatabehavior.httpsgetenabled = true; host.description.behaviors.remove<servicemetadatabehavior>(); host.description.behaviors.add(servicemetadatabehavior); var servicedebugbehavior = new servicedebugbehavior(); servicedebugbehavior.includeexceptiondetailinfaults = true; host.description.behaviors.remove<servicedebugbehavior>(); host.description.behaviors.add(servicedebugbehavior); var requestheaderbehavior = new userequestheadersformetadataaddressbehavior(); // of import host.description.behaviors.remove<userequestheadersformetadataaddressbehavior>(); host.description.behaviors.add(requestheaderbehavior); host.addserviceendpoint(new serviceendpoint( contractdescription, new internalbinding(), new endpointaddress(clienturl, endpointidentity.createx509certificateidentity(servicecertificate)))); host.open();

some bits omitted etc. took long time figure out , lot of gray hairs.

c# wcf azure azure-worker-roles

No comments:

Post a Comment