Asp.net webservice always recieving null values from soap ui - c#

I'm posting below message from soap UI and i always receiving null value in webservice. Whatever message I'm posting from soap UI it is taking as null only.
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
Test
</env:Body>
</env:Envelope>
Below is my simple WebService
[WebService(Namespace = "http://test.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class TestService : System.Web.Services.WebService {
[WebMethod]
public int TestMethod(string message)
{
try
{
File.WriteAllText("D:\\abc.xml", message);
return 0;
}
catch (Exception ex)
{
return 1;
}
}
}

You're not specifying which method to call or the parameters of that method in your body. You'll need something like this:
<env:Body>
<m:TestMethod xmlns:m="http://tempuri.org">
<message>Test</message>
</m:TestMethod>
</env:Body>

Related

SOAP Request format

I am trying to create a SOAP web service to use with a client.
According to the documentation, we have to create a web service with two methods that return certain information. I have created them without a problem, but I can not get them to fit the example format.
I have to say that for years I did not create any SOAP services (since Net 2.0) because I have been doing REST services for a long, so if you see any nonsense, forgive me.
The example request that there is in the documentation (the good one) is this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pag="http://pagorecibos.pagosrecibos.com/">
<soapenv:Header/>
<soapenv:Body>
<pag:obtenerImporte>
<referencia>040</referencia>
</pag:obtenerImporte>
</soapenv:Body>
</soapenv:Envelope>
That's the format that my service want to recieve:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<obtenerImporte xmlns="http://tempuri.org/">
<referencia>string</referencia>
</obtenerImporte>
</soap:Body>
</soap:Envelope>
The code of my service is this:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service: System.Web.Services.WebService
{
[WebMethod]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
public string ObtenerImporte(ObtenerImporte obtenerImporte)
{
return "Hola a todos";
}
[WebMethod]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
public string RealizarPago(RealizarPago realizarPago)
{
return "Hola a todos";
}
}
Class (the other class is similar):
public class ObtenerImporte
{
[XmlElement("referencia")]
public string Referencia { get; set; }
}
The difference is in the namespace and the prefix in node "obtenerImporte" but I can't resolve it.
I'm using VS2017 Community Edition y created the project using "ASP.NET Web Service" template.
Problem solved!!!. Adding and removing code.... suddenly it works :D. The right way to define the service is this (thanks #zaitsman for your clue):
[WebService(Namespace = "http://pagorecibos.pagosrecibos.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
[WebMethod]
[SoapDocumentMethod(Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Bare)]
public string ObtenerImporte(ObtenerImporte obtenerImporte)
{
return "Obtener Importe";
}
[WebMethod]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
public string RealizarPago(RealizarPago realizarPago)
{
return "Realizar Pago";
}
}
I hope that this solution could help other one.

WCF accessing FaultException details from IErrorHandler.ProvideFault in the client

I am trying to attach additional information to a FaultException for a WCF service, and then access it in the client. I am using the IErrorHandler ProvideFault method as my service has many methods that it exposes and I want to define the error handling logic in one place.
I have defined a data class CoreFault:
[DataContract]
public class CoreFault
{
[DataMember]
public string Foo { get; set; }
}
And implemented the IErrorHandler interface to return a strongly typed FaultException:
public class ErrorHandler : IErrorHandler
{
public void ProvideFault(Exception error, MessageVersion version, ref Message message)
{
var faultException = new FaultException<CoreFault>(
new CoreFault
{
Foo = "Bar"
},
"An error occurred",
null);
var fault = faultException.CreateMessageFault();
message = Message.CreateMessage(
version,
fault,
faultException.Action);
}
}
My service is configured in code:
public static void Configure(ServiceConfiguration config)
{
(config.Description.Behaviors[0] as ServiceBehaviorAttribute).IncludeExceptionDetailInFaults = true;
config.Description.Behaviors.Add(new ErrorHandlingBehaviour());
}
I have breakpointed the code after creating the message, and it shows the following XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header/>
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-GB">An error occurred</faultstring>
<detail>
<CoreFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/EmployerPortal.Models.Faults">
<Foo>Bar</Foo>
</CoreFault>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
But in my client, the error that is thrown is FaultException and not FaultException<CoreFault>, and the extra information is lost.
try
{
// Call service here
...
}
catch (FaultException<CoreFault> e)
{
throw;
}
catch (FaultException e)
{
// This line is hit
throw;
}
How can I pass Foo to the client, so that it can access it when it handles the exception?

Remove xml header from C# webservice

I need to build an API using C# webservice, which needs to return values in json format.
Currently I have the following lines of code
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return new JavaScriptSerializer().Serialize(new { errMsg = "test" });
}
}
}
The output of this when the post method is invoked is
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">{"errMsg":"test"}</string>
But this isn't a valid json how do I make the webservice return the json object only and not the xml headers?
Calling this webservice with header Content-Type: application/json will automatically transform the response to json and your xml will be gone.

Invoke a SOAP method with namespace prefixes

My C# web service client sends following soap message to Java-based web service:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<getData>
<request>
<requestParameters xmlns="http://b...">
<equals>
...
</equals>
</requestParameters>
</request>
</getData>
</soap:Body>
</soap:Envelope>
and Java-based web service returns error:
500 Internal Server Error
...
Cannot find dispatch method for {}getData
...
Client written in Java, which works, sends the following message:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ns2:getData xmlns:ns2="http://a...">
<ns2:request>
<ns3:requestParameters xmlns:ns3="http://b...">
<ns3:equals>
...
</ns3:equals>
</ns3:requestParameters>
</ns2:request>
</ns2:getData>
</soap:Body>
</soap:Envelope>
Is there an easy way in C# to send SOAP messages the same way Java client sends: with namespace prefixes?
Following is C# code that sends message:
// class MyService is auto-generated using wsdl.exe tool
MyService service = new MyService();
RequestMessage request = new RequestMessage();
...
ResponseMessage response = service.getData(request);
...
UPDATE:
Here is RequestMessage class:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://uri.etsi.org/02657/v1.5.1#/RetainedData")]
public partial class RequestMessage
{
private byte[] requestPriorityField;
private RequestConstraints requestParametersField;
private string deliveryPointHIBField;
private string maxHitsField;
private NationalRequestParameters nationalRequestParametersField;
private System.Xml.XmlElement anyField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType="hexBinary", Order=0)]
public byte[] requestPriority
{
get
{
return this.requestPriorityField;
}
set
{
this.requestPriorityField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=1)]
public RequestConstraints requestParameters
{
get
{
return this.requestParametersField;
}
set
{
this.requestParametersField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=2)]
public string deliveryPointHIB
{
get
{
return this.deliveryPointHIBField;
}
set
{
this.deliveryPointHIBField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=3)]
public string maxHits
{
get
{
return this.maxHitsField;
}
set
{
this.maxHitsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=4)]
public NationalRequestParameters nationalRequestParameters
{
get
{
return this.nationalRequestParametersField;
}
set
{
this.nationalRequestParametersField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute(Order=5)]
public System.Xml.XmlElement Any
{
get
{
return this.anyField;
}
set
{
this.anyField = value;
}
}
}
UPDATE #2:
The reason why Java-based web service didn't like my C# client produced SOAP message is not omission of namespace prefixes, but only because of omission of xmlns in getData element, so if my message looks like this:
...
<getData xmlns="http://a...">
...
</getData>
...
it works!
I managed to put xmlns inside getData by manually editing SoapRpcMethodAttribute in wsdl.exe-produced source code. Here is excerpt:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(
Name="AxxxPortTypeBinding", Namespace="http://a...")]
public partial class AxxxService
: System.Web.Services.Protocols.SoapHttpClientProtocol {
...
/// <remarks/>
[System.Web.Services.Protocols.SoapRpcMethodAttribute(
"http://a.../getData",
RequestNamespace = "http://a...",
ResponseNamespace = "http://a...",
Use = System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlElementAttribute("response")]
public ResponseMessage getData(RequestMessage request) {
object[] results = this.Invoke("getData", new object[] {
request});
return ((ResponseMessage)(results[0]));
}
...
}
Before my change, SoapRpcMethodAttribute had following constructor:
[System.Web.Services.Protocols.SoapRpcMethodAttribute(
"", RequestNamespace = "", ResponseNamespace = "",
Use = System.Web.Services.Description.SoapBindingUse.Literal)]
Now, the question is: what to put in WSDL file so that SoapRpcMethodAttribute have those strings in constructor (filled by the wsdl.exe tool) in the first place?
I've seen this problem before where the WSDL.exe tool did not properly pull in the namespace when generating the service code. Check the request object definition in your generated code. My guess is that there is no XmlRootAttribute attribute defined on the class definition for the request object.
Adding the attribute [XmlRootAttribute(Namespace "http://a...")] to the class definition for the request object should fix this issue.
As a side note, I recommend adding this additional attribute in a separate code file using a partial class definition. Defining the attribute in a separate file will allow you to regenerate the web service code using WSDL.exe whenever neccessary without overwriting the fix to set the root element's namespace properly.
The generated proxy class should have had the correct namespace in it. I recommend two things:
1) Run WSDL.EXE from the command line and note whether there are any errors or warnings. If so, please edit your question to include them.
2) Unless you are stuck using .NET 2.0, you should try to create your proxy classes using either "Add Service Reference" or the equivalent "SVCUTIL.EXE" these will use the modern, WCF infrastructure on the client side, which is much more likely to have been fixed to resolve this problem.
I had the same issue and solved it changing the value of the property Use in System.Web.Services.Protocols.SoapDocumentMethodAttribute attribute corrisponding to each web service method.
The System.Web.Services.Description.SoapBindingUse.Literal default value was replaced with System.Web.Services.Description.SoapBindingUse.Encoded.

Why is my web service giving me an Error 500?

I have this web service:
using System.Web.Services;
namespace Contracts
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Second : System.Web.Services.WebService
{
[WebMethod]
public string GetContract()
{
return "Contract 1";
}
}
}
The following WPF application can display the HTML fine:
using System.Windows;
using System.Net;
using System;
namespace TestConsume2343
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
WebClient proxy = new WebClient();
proxy.DownloadStringCompleted += new DownloadStringCompletedEventHandler(proxy_DownloadStringCompleted);
proxy.DownloadStringAsync(new Uri("http://localhost:57379/Second.asmx?op=GetContract"));
Message.Text = "loading...";
}
void proxy_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Message.Text = e.Result.ToString();
}
}
}
but when I replace the above line with the actual web service:
proxy.DownloadStringAsync(new Uri("http://localhost:57379/Second.asmx/GetContract"));
it gives me the error message:
The remote server returned the error (500) Internal Server Error.
Although when I look at the same URL in my browser, I see the XML text fine:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Contract 1</string>
Why is it giving me the 500 error?
Turn on tracing and logging on your WCF service to see what the exception is (MSDN link) or attach the debugger with break on every exception as already suggested. .
The service returning HTTP code 500 usually means that there was an exception during request processing. If you have debugger attached to the web server and configured properly it will break on exception and you will be able to see it. Also usually the text of the exception should be included in the body of the HTTP response

Categories