I am creating a WCF service from a given WSDL file. Here as per the WSDL, I want to set urn address in EndpointReference address as shown below
Example of WSDL:
<wsdl:service name="MyCustomService">
<wsdl:port name="SecurePort" binding="tns:Secure">
<soap12:address location="https://localhost:8453/MyService/Service.svc" />
<wsa10:EndpointReference>
**<wsa10:Address>urn:aaa.cc:abc:names:pqr:ddd</wsa10:Address>**
</wsa10:EndpointReference>
</wsdl:port>
<wsdl:port name="UnSecurePort" binding="tns:Unsecure">
<soap12:address location="http://localhost:8080/MyService/Service.svc" />
<wsa10:EndpointReference>
**<wsa10:Address>urn:aaa.cc:abc:names:pqr:ddd</wsa10:Address>**
</wsa10:EndpointReference>
</wsdl:port>
I have seen something called IWsdlExportExtension. But still checking how to access endpoint metadata and set the urn address.
Any help would be appropriated...
Thank You
Here is the solution:
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context){
EndpointAddress address = context.Endpoint.Address;
var newAbsoluteUri = new Uri("urn:aaa.cc:abc:names:pqr:ddd");
context.Endpoint.Address = new EndpointAddress(newAbsoluteUri,
address.Identity, address.Headers, address.GetReaderAtMetadata(),
address.GetReaderAtExtensions());}
Using IWsdlExportExtension interface, we can update the Endpoint address.
Thank You
Related
I am new to WCF. I'm trying to create a webservice from a client provided wsdl;
I'm having trouble changing some wcf generated wsdl entries to match the provided wsdl.
Here is my wsdl port name :
<wsdl:service name="MyService">
<wsdl:port name="BasicHttpBinding_IService" binding="i0:BasicHttpBinding_IService">
<soap:address location="http://localhost:53336/MyServiceApi.svc"/>
</wsdl:port>
</wsdl:service>
But I need change to
<wsdl:service name="MyServiceSoap">
<wsdl:port name="MyServiceSoap" binding="m:MyServiceSoap">
<soap:address location="http://localhost:53336/MyServiceApi.svc"/>
</wsdl:port>
</wsdl:service>
How do I that? Can someone please show me a simple solution?
I found a solution to setting port name.
like this:
<services>
<service name="MyServiceSoap">
<endpoint name="MyServiceSoap" address="" binding="basicHttpBinding" contract="IService" bindingNamespace="MyServiceSoap" bindingName="MyServiceSoap" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
then the wsdl port name will be that I want.
I added this attribute to my service implementation and that solved my problem:
[ServiceBehavior(Name = "MyServiceName")]
public class MyServiceClass : IServiceContract
{
// implementation code
}
Resulting WSDL:
<wsdl:service name="MyServiceName">
<wsdl:port name="MyServiceClass" binding="tns:MyServiceClass">
<soap:address location="http://localhost:52233/MyService.svc"/>
</wsdl:port>
</wsdl:service>
When coding a SOAP service in C#, running it and then retrieving the WSDL from the service with ?singlewsdl option, the generated WSDL has an empty namespace attribute in the element, spoiling WSI compliance (checked with SoapUI) and resulting in error code BP2019, indicating an illegal namespace in the soap fault.
The service method is in a base interface, from which the services derive their own interfaces.
Definition is in a service interface:
[OperationContract(
Action = "http://mynamespace.com/services/2014/06/23/MyBaseContract/GetInterfaceVersionRequest",
ReplyAction = "http://mynamespace.com/services/2014/06/23/MyBaseContract/GetInterfaceVersionResponse" )]
[FaultContract(typeof(string), Name="NonsenseFault")]
string GetInterfaceVersion();
The WSDL generated by the service with ?singlewsdl contains an empty namespace attribute:
<wsdl:operation name="GetInterfaceVersion">
<soap:operation soapAction="http://mynamespace.com/services/2014/06/23/MyBaseContract/GetInterfaceVersionRequest" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="NonsenseFault">
<soap:fault use="literal" name="NonsenseFault" namespace=""/> <!-- spoils WS-I compliance! -->
</wsdl:fault>
</wsdl:operation>
According to WS-I rules, the soap:fault element must not have a namespace attribute at all.
Can I do anything about this?
You may be able to solve the issue by setting the FaultContract attribute Namespace property.
[FaultContract(typeof(string), Name="NonsenseFault", Namespace="http://my.nonsense.fault")]
http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute(v=vs.110).aspx
I have strange problem with WCF service. I use pollingDuplexBinding and Silverlight client.
Binding was registred by this code in web.config
<bindingElementExtensions>
<add name="pollingDuplex" type="System.ServiceModel.Configuration.PollingDuplexElement, System.ServiceModel.PollingDuplex" />
</bindingElementExtensions>
On first call everything is ok - service returns data fast. But second call executes more than 5 mitutes. If I set big timeouts, result will be returned to client, else it throws TimeoutException. WCF method I'm calling does nothing - just returns short string.
WCF tracing says, that second service call just coming 5 minutes later than client calls this method, and executes quickly.
I use these service attributes:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
It's client code
var binding = new PollingDuplexHttpBinding(PollingDuplexMode.SingleMessagePerPoll);
var address = new EndpointAddress("/SportService.svc");
_proxy = new SportDuplexClient(binding, address);
i hade same problem, i solve it in this way :
just set aspNetCompatibilityEnabled="false" to false in web.config file
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
or set sessionState mode="Off" in web.config
<system.web>
<sessionState mode="Off" />
</system.web>
in both way my problem will solved...
Warning 1 Custom tool warning: Cannot import wsdl:binding
Detail: The given key was not present in the dictionary.
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://wrapper.dao.ccarwebservice.ids.com']/wsdl:binding[#name='CCaRWebServiceHttpBinding'] C:\Users\me\Documents\Visual Studio 2008 \Projects\CcarsWcfTest\CcarsWcfTest\Service References\ServiceReference1\Reference.svcmap 1 1 CcarsWcfTest
what can I do to resolve this issue?
I've tried running the service utility from the command prompt and adding a service reference to my project. I've also gone into the advanced setting in the Add Service Reference dialog and deselected 'Reuse types in all referenced assemblies'.
EDIT
Here is the part of the wsdl I think it's referring to..
<wsdl:binding name="CCaRWebServiceHttpBinding" type="ns:CCaRWebServicePortType">
<http:binding verb="POST"/>
<wsdl:operation name="fnGetccarprogramsummaryarray">
<http:operation location="CCaRWebService/fnGetccarprogramsummaryarray"/>
<wsdl:input>
<mime:content type="text/xml" part="fnGetccarprogramsummaryarray"/>
</wsdl:input>
<wsdl:output>
<mime:content type="text/xml" part="fnGetccarprogramsummaryarray"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="fnGetccarprogramsummary">
<http:operation location="CCaRWebService/fnGetccarprogramsummary"/>
<wsdl:input>
<mime:content type="text/xml" part="fnGetccarprogramsummary"/>
</wsdl:input>
<wsdl:output>
<mime:content type="text/xml" part="fnGetccarprogramsummary"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
public partial class fnGetccarprogramsummaryarrayRequest
{
public fnGetccarprogramsummaryarrayRequest()
{
}
}
the others are like this...
public partial class fnGetccarprogramsummaryRequest
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://wrapper.com", Order=0)]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string programAcronym;
public fnGetccarprogramsummaryRequest()
{
}
public fnGetccarprogramsummaryRequest(string programAcronym)
{
this.programAcronym = programAcronym;
}
}
Where did the WSDL come from? How was it generated?
It could be the the definition of the input and return types are missing.
fnGetccarprogramsummaryarray
fnGetccarprogramsummary.
It could be that it is trying to look for the definition in an array of types and not finding it.
EDIT
I think that I found it you have a POST binding and the tool only supports a SOAP binding
http://social.msdn.microsoft.com/Forums/en/wcf/thread/859a2c87-02db-469d-ab65-c558ff091e61
The key that is not present is then the SOAP binding.
After searching.. the only solution I've come across is to ignore this error.
"It is internal implementation detail of svcutil.
The error is probably since the wsdl contains a POST binding and the utlity only works on SOAP bindings. But if there is another SOAP binding in the wsdl it works."
Anyone know why this wsdl is not liked by the mono wsdl tool? Microsoft parses it. XMethods online wsdl validator parses it. Mono just doesn't seem to like it and I do not know enough to understand why.
# the error
mmcaughan#mmcaughan-dsktop:~/Projects/sftest$ wsdl enterprise.wsdl
Web Services Description Language Utility
Mono Framework v2.0.50727.1433
There where some warnings while generating the code:
enterprise.wsdl
- This web reference does not conform to WS-I Basic Profile v1.1
R2718: A wsdl:binding in a DESCRIPTION MUST have the same set of
wsdl:operations as the wsdl:portType to which it refers.
* Binding 'SoapBinding', in Service Description
'urn:enterprise.soap.sforce.com'
Writing file 'SforceService.cs'
relevant WSDL parts (I think)
<!-- Soap PortType -->
<portType name="Soap">
<operation name="login">
<documentation>Login to the Salesforce.com SOAP Api</documentation>
<input message="tns:loginRequest"/>
<output message="tns:loginResponse"/>
<fault message="tns:LoginFault" name="LoginFault"/>
<fault message="tns:UnexpectedErrorFault" name="UnexpectedErrorFault"/>
<fault message="tns:InvalidIdFault" name="InvalidIdFault"/>
</operation>
<!-- Soap Binding -->
<binding name="SoapBinding" type="tns:Soap">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="login">
<soap:operation soapAction=""/>
<input>
<soap:header use="literal" message="tns:Header" part="LoginScopeHeader"/>
<soap:body parts="parameters" use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="LoginFault">
<soap:fault name="LoginFault" use="literal"/>
</fault>
<fault name="UnexpectedErrorFault">
<soap:fault name="UnexpectedErrorFault" use="literal"/>
</fault>
<fault name="InvalidIdFault">
<soap:fault name="InvalidIdFault" use="literal"/>
</fault>
</operation>
Older and more wiser now...
generate the C# from the wsdl
wsdl enterprise.wsdl -n:Sforce -o:SforceService.cs
the XmlAnyElement cannot have an empty namspace, so pop open SforceService.cs and remove it
this...
[System.Xml.Serialization.XmlAnyElement(Namespace="")]
public System.Xml.XmlElement[] Any {
get {
return this.anyField;
}
set {
this.anyField = value;
}
}
becomes...
public System.Xml.XmlElement[] Any {
get {
return this.anyField;
}
set {
this.anyField = value;
}
}
wsdl generates xml serialization against private members which doesn't work and has to be fixed
Unhandled Exception: System.InvalidOperationException: Member LoginScopeHeaderValueField not found in class Sforce.SforceService.
this...
[System.Web.Services.Protocols.SoapHeaderAttribute("LoginScopeHeaderValueField")]
becomes...
[System.Web.Services.Protocols.SoapHeaderAttribute("LoginScopeHeaderValue")]
search and replace ValueField" for ValueField"
then you might get this, which is a failure because mono does not install any root certificates in the trust store so https fails
Unhandled Exception: System.Net.WebException: Error writing request: The authentication or decryption has failed.
at System.Net.WebConnectionStream.WriteHeaders () [0x00000]
at System.Net.WebConnectionStream.SetHeaders (System.Byte[] buffer) [0x00000]
at (wrapper remoting-invoke-with-check) System.Net.WebConnectionStream:SetHeaders (byte[])
at System.Net.HttpWebRequest.SendRequestHeaders (Boolean propagate_error) [0x00000]
it is fixed with mozroots which will get all the certs mozilla ships with...
mozroots --import --sync
then everything works as describe
Sforce.SforceService binding = new Sforce.SforceService();
Sforce.LoginResult loginResult = binding.login("someuser", "somepass");
etc...