Can anyone tell me what SoapDocumentMethodAttribute does? - c#

Can anybody explain to me what the following code does? Specifically, the attribute on the GetStatus method. I know it has something to do with SOAP requests, but I tried googling "SoapDocumentMethodAttribute" and didn't find much that explains things. Can anybody dumb it down for me please?
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://dummyurl.com/", RequestNamespace = "http://dummyurl.com/", ResponseNamespace = "http://dummyurl.com/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string GetStatus(string Username, string Password, string EndSystemUser) {
object[] results = this.Invoke("GetStatus", new object[] {
Username,
Password,
EndSystemUser});
return ((string)(results[0]));
}

Soap services expose WSDL to the consumers which contain information about how SOAP messages would be written.
This WSDL can be written either in RPC style or in Document Style.
Document style is perfered over RPC style as it means less coupling and provides better way to validate the message.
This attribute instructs WSDL generator to use Document Style.
From the MSDN Documentation:
Web Services Description Language (WSDL) defines two styles for how an
XML Web service method, which it calls an operation, can be formatted
in a SOAP message: RPC and Document. Document refers to formatting the
XML Web service method according to an XSD schema. The Document style
refers to formatting the Body element as a series of one or more
message parts following the Body element.
Refer this link for examples of RPC / Document style.

Related

How to provide a C# .Net Web Service without an ‘elementformdefault = “qualified”’ attribute in the WSDL?

I’ll provide a web service for a client with a given WSDL.
Unfortunately I’m not able to tell the serializer to accept unqualified elementForm.
I seek for the way to set the elementFormDefault to either "unqualified" or even "None" to hide it complete
I’ll receive something like
<NS:Request>
<some stuff>…</some stuff>
</NS:Request>
But I see no content in my request
Only if I Change the prefix or remove the prefix and change the NS scope by adding a new NS to the request
<NS:Request>
< NS:some stuff>…</ NS:some stuff>
</NS:Request>
or
< Request xmlns:myNamespace>
< some stuff>…</some stuff>
</Request>
The web service works fine.
Thanks for your support
Although this is a dead question from 2 years ago, I would still like to answer it as this is my first related search result when I encounter the exact same problem.
The WSDL file generated via .asmx?wsdl has an attribute
elementFormDefault=qualified
within it's schema tag, which forces the clients to add a namespace prefix to all input element if they were to successfully pass their input to server. (If the client ignore the namespace prefix regardless, the server will receive empty request with no input).
Since in my case my client could not generate a qualified soap request no matter what, I have to change on server side.
The way you do it is to add
[XmlElement(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
in front of every input parameter for every web method:
[WebMethod]
public string TestMethod(
[XmlElement(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]string input1,
[XmlElement(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]int input2)
{
/***code here****/
}

Set namespace prefix on FaultCode c#.net

I am expecting following response for faultCode to be send to client if any fault occurs in FaultException. From custom certificate validator put on BizTalk receive location
<faultcode xmlns:ssek="http://myschemas.testns.org/testns/2006-05-10/">ssek:InvalidCertificate</faultcode>
But when i have written following code.
FaultCode code = new FaultCode("InvalidCertificate", "http://myschemas.testns.org/testns/2006-05-10/");
throw new FaultException("Received Invalid Client Certificate", code);
FaultCode coming as
<faultcode xmlns:a="http://myschemas.testns.org/testns/2006-05-10/">a:InvalidCertificate</faultcode>
I want to modify prefix "a" with "ssek".
Please can somebody help me with this.
Regards
Kundan
Related to this MSDN article, this the default behavior when the FaultCode is serialized.
to override this generation, you can create a custom MessageFormatter. there is a good article explaining how to do it with an attribute on contract operations.
hope that helpe you.

web service error: operation with parameters cannot be found

I am trying to consume the .net webservice from cold fusion. Methods having simple types working fine. But i am having problems with one particular method which accepts byte[] array as input.
Below the sample webmethod declaration
[WebMethod]
public AVStatus ScanStream(byte[] fileObject)
{
// code
}
and the cold fusion code consuming this service is
<cffile action="readBinary" file="#FileName#" variable="filedata">
<cfset b64file = #toBase64(filedata)#>
<cfinvoke webservice = "http://xxx/scanservice.asmx?wsdl"
method = "ScanStream"
returnVariable = "result">
<cfinvokeargument name="fileObject" value="#b64file#" />
</cfinvoke>
This always leads to this error Web service operation ScanStream with parameters cannot be found.
can someone help me out this?
It seems that the binary data has been exposed as bas64 string in the coldfusion while byte[] is exposed by the service as an XML array (of bytes).
Change the ScanStream (if you can) to accept a string, if web service is not yours you could convince owners to provide another method which accepts string and uses Convert.FromBase64String to change to byte array.
Webservices are remote, not public. Public allows access by other CF classes and pages. Change public to remote, and you should be able to "see" your webservice.

Call a webservice without proxy

I have to call a webservice from withing a C# programm. The webservice has most probably not a standard format. The interface description (wsdl and xsd) are very complicated, and using a proxy generating mechanismus results in hundreds of classes. The generated classes ar of little help since they are very generic, having mostly simple Object types as members.The best option is to build the SOAP message manually. That is also the way the webservice provider suggested to chose: Take the soap/xml messages that has to be sent and build the message according to the template. Now the question is how to build the message most efficiently. Of course hard coding the message string is an option, however I wonder if better options exists. If I have the complete message in a string, how do I best send the messages. Should I use a simple HttpRequest or can I use mechanisms of the wcf stack?
My current approach to build the message looks like this:
string msg = envelopeBegin;
RouteType rootType = new RouteType();
XmlSerializer serializer = new XmlSerializer(typeof(RouteType));
StringWriter stringWriter = new StringWriter();
serializer.Serialize(stringWriter, rootType , customNamespace);
msg += stringWriter.ToString();
msg += envelopeEnd;
// Send the message over the wire
The Soap/xml message I have to generate looks like this
<env:Envelope>xmlns:env=http://schemas.xmlsoap.org/soap/envelope/ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://www.skanska.se/oagis/9/ws/faults">
<env:Body>
<ska:ShowSalesOrder xmlns:ska="http://www.skanska.se/oagis/9" systemEnvironmentCode="UTV" versionID="1.0" releaseID="9.0">
<!--plsql=.74s-->
<ApplicationArea xmlns="http://www.openapplications.org/oagis/9">
<!--user_name=SEBA_RAPPE-->
<ska:Sender>
<LogicalID>OEBS_SE</LogicalID>
<ComponentID>SKAIS017I</ComponentID>
<AuthorizationID>SEBA_RAPPE</AuthorizationID>
<ska:ResponsibilityID>XXOM_INTEGRATION_SVT</ska:ResponsibilityID>
</ska:Sender>
<CreationDateTime>2010-02-26T15:03:27+01:00</CreationDateTime>
<BODID>xxxxxxxxxxxxxxxxx</BODID>
</ApplicationArea>
<ska:DataArea>
<Show xmlns="http://www.openapplications.org/oagis/9">
<ResponseCriteria>
<ResponseExpression actionCode="Never" expressionLanguage="xPath">*</ResponseExpression>
</ResponseCriteria>
</Show>
<ska:SalesOrder>
<SalesOrderHeader xmlns="http://www.openapplications.org/oagis/9">
<DocumentID>
<ID>141779</ID>
</DocumentID>
<RequestedShipDateTime>2009-11-04T07:00:54+01:00</RequestedShipDateTime>
</SalesOrderHeader>
</ska:SalesOrder>
</ska:DataArea>
</ska:ShowSalesOrder>
</env:Body>
</env:Envelope>
You can definitely still use the WCF infrastructure without requiring type definitions for all of the various messages. WCF specifically supports this through the Message class. Using it is not all that difficult. Here's some more information about them but the idea is basically you would use XML readers and writers to read and write messages.
Using the Message Class
One way to do it is to create an XML skeleton template containing placeholders for the values. Read the XML and replace the values with those from your object. Post the resulting XML to the web service using HttpWebRequest.
Even that this approach might work I would strongly recommend you creating a WCF proxy class and using this instead even if the web service contains hundreds of methods and objects that are not used. As long as it is a valid WSDL, WCF will handle it. Also if there are any changes to the web service all you have to do is regenerate the proxy. To avoid the ugliness of this web service create your own infrastructure that exposes only the useful methods and classes and hides the real call.

How do I get a value from an XML web service in C#?

In C#, if I need to open an HTTP connection, download XML and get one value from the result, how would I do that?
For consistency, imagine the webservice is at www.webservice.com and that if you pass it the POST argument fXML=1 it gives you back
<xml><somekey>somevalue</somekey></xml>
I'd like it to spit out "somevalue".
I think it will be useful to read this first:
Creating and Consuming a Web Service (in .NET)
This is a series of tutorials of how web services are used in .NET, including how XML input is used (deserialization).
I use this code and it works great:
System.Xml.XmlDocument xd = new System.Xml.XmlDocument;
xd.Load("http://www.webservice.com/webservice?fXML=1");
string xPath = "/xml/somekey";
// this node's inner text contains "somevalue"
return xd.SelectSingleNode(xPath).InnerText;
EDIT: I just realized you're talking about a webservice and not just plain XML. In your Visual Studio Solution, try right clicking on References in Solution Explorer and choose "Add a Web Reference". A dialog will appear asking for a URL, you can just paste it in: "http://www.webservice.com/webservice.asmx". VS will autogenerate all the helpers you need. Then you can just call:
com.webservice.www.WebService ws = new com.webservice.www.WebService();
// this assumes your web method takes in the fXML as an integer attribute
return ws.SomeWebMethod(1);
You can use something like that:
var client = new WebClient();
var response = client.UploadValues("www.webservice.com", "POST", new NameValueCollection {{"fXML", "1"}});
using (var reader = new StringReader(Encoding.UTF8.GetString(response)))
{
var xml = XElement.Load(reader);
var value = xml.Element("somekey").Value;
Console.WriteLine("Some value: " + value);
}
Note I didn't have a chance to test this code, but it should work :)
It may also be worth adding that if you need to specifically use POST rather than SOAP then you can configure the web service to receive POST calls:
Check out the page on MSDN:
Configuration Options for XML Web Services Created Using ASP.NET

Categories

Resources