Get SOAP Reply in ASP.NET Webservice - soap

I created a SOAP WebService to receive a request. I want to log the SOAP messages with envelope.
I discovered how get the request message, but I don't discovered how can I get the reply message.
To get the XML Request, I use the code below.
// Create array for holding request in bytes
byte[] inputStream = new byte[HttpContext.Current.Request.ContentLength];
// Read the entire request input stream
HttpContext.Current.Request.InputStream.Read(inputStream, 0, inputStream.Length);
// Set stream position back to beginning
HttpContext.Current.Request.InputStream.Position = 0;
// Get the XML request
string xmlRequestString = Encoding.UTF8.GetString(inputStream);
To get the reply, I tried do this into the Dispose method, but I couldn't make it work.

The InputStream works fine.
The Request SOAP XML I get propertelly. I need a way to get de SOAP XML that my web method replay to the caller. Into the WebMethod the Response is not complet. So I tried use the Dispose Method, but I have the same problem. The dispose method is call before .Net Framework return the reply to caller.
I need a way to log the SOAP XML Request abd the SOAP XML Replay.
The code below get XML Request fine:
[WebMethod]
public ActivityCCPResponseOutput Request(ActivityCCPRequestInput ActivityCCPRequestInput)
{
XmlDocument xmlSoapRequest = new XmlDocument();
Stream receiveStream = HttpContext.Current.Request.InputStream;
receiveStream.Position = 0;
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
xmlSoapRequest.Load(readStream);
string xmlSOAPRequest = xmlSoapRequest.InnerXml;
...
}
In the code below, I couldn't get the reply. Probably, there is a different way to do this.
void IDisposable.Dispose()
{
XmlDocument xmlSoapResponse = new XmlDocument();
// In this point HttpContext.Current.Response.OutputStream is empty
Stream responseStream = HttpContext.Current.Response.OutputStream;
responseStream.Position = 0;
StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8);
xmlSoapResponse.Load(readStream);
string xmlSOAPReply = xmlSoapResponse.InnerXml;
}

Related

GWT: Response not coming back to Form onSubmitCompleteEvent when a servlet sends a file in response to browser

Code on client side :
#UiHandler("form")
void onFormSubmission(SubmitCompleteEvent event) {
hideProcessingPopUp();
if (event.getResults().contains("Exception")) {
// handle exception
}
}
Servlet code in doPost method:
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment;filename="
+ exportType + ".csv");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
response.getOutputStream(), "UTF-8"));
// Adding content
List<CustomObject> list = (List<CustomObject>) anonymousList;
for (CustomObject eachObject : list) {
writer.append(eachObject.getContent());
writer.newLine();
}
writer.flush();
// Gently close streams/writers.
close(writer);
return fileContent;
Servlet code is fine, as am getting expected data and file. Problem is with response not reaching the client side i.e., SubmitCompleteEvent. Please help me out, thanks in advance.
This is how browsers work; and the javadoc for FormPanel actually warns you about it:
The back-end server is expected to respond with a content-type of 'text/html', meaning that the text returned will be treated as HTML. If any other content-type is specified by the server, then the result HTML sent in the onFormSubmit event will be unpredictable across browsers, and the onSubmitComplete event may not fire at all.

SpringWS - Logging SoapRequest and SoapResponse in a table

I have a SpringWS inplementation with below enpoint implementation
#PayloadRoot(namespace="http://college.com/schema/get_XML_Request/v2",localPart="get_XML_Request")
#ResponsePayload
public JAXBElement<GetStudentResponseType> handleStudentXML(#RequestPayload JAXBElement<GetStudentXMLRequestType> SoapRequest)throws Exception
{
String xmlResponse = "";
com.college.get_student_xml_response.v2.ObjectFactory objectFactory = new com.company.schema.get_student_xml_response.v2.ObjectFactory();
com.college.schema.get_student_xml_response.v2.GetResponseType resType = objectFactory.createGetResponseType();
return objectFactory.createGetStudentResponse(resType);
}
Here my objective is to log the request which coming to my webservice and response which the web service sent back in a table. Is it possible to get the SoapRequest/Soapresponse (In Soapformat) from the above method as a String.Here am able to get the payload, but i need to log with entire SoapRequest(with soapenvelope,body) Please anyone advice on this.
Have a look at the SoapEnvelopeLoggingInterceptor which logs the whole SOAP
Envelope including headers. So basically you can extend it to add the saving to the database functionality.

How do I handle/fix "Error getting response stream (ReadDone2): ReceiveFailure" when using MonoTouch?

I am using MonoTouch to build an iPhone app. In the app I am making Web Requests to pull back information from the web services running on our server.
This is my method to build the request:
public static HttpWebRequest CreateRequest(string serviceUrl, string methodName, JsonObject methodArgs)
{
string body = "";
body = methodArgs.ToString();
HttpWebRequest request = WebRequest.Create(serviceUrl) as HttpWebRequest;
request.ContentLength = body.Length; // Set type to POST
request.Method = "POST";
request.ContentType = "text/json";
request.Headers.Add("X-JSON-RPC", methodName);
StreamWriter strm = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
strm.Write(body);
strm.Close();
return request;
}
Then I call it like this:
var request = CreateRequest(URL, METHOD_NAME, args);
request.BeginGetResponse (new AsyncCallback(ProcessResponse), request);
And ProcessResponse looks like this:
private void ProcessResponse(IAsyncResult result)
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result)) // this is where the exception gets thrown
{
using (StreamReader strm = new System.IO.StreamReader(response.GetResponseStream()))
{
JsonValue value = JsonObject.Load(strm);
// do stuff...
strm.Close();
} // using
response.Close();
} // using
Busy = false;
}
catch(Exception e)
{
Console.Error.WriteLine (e.Message);
}
}
There is another question about this issue for Monodroid and the answer there suggested explicitly closing the output stream. I tried this but it doesn't solve the problem. I am still getting a lot of ReadDone2 errors occurring.
My workaround at the moment involves just re-submitting the Web Request if an error occurs and the second attempt seems to work in most cases. These errors only happen when I am testing on the phone itself and never occur when using the Simulator.
Whenever possible try to use WebClient since it will deal automatically with a lot of details (including streams). It also makes it easier to make your request async which is often helpful for not blocking the UI.
E.g. WebClient.UploadDataAsync looks like a good replacement for the above. You will get the data, when received from the UploadDataCompleted event (sample here).
Also are you sure your request is always and only using System.Text.Encoding.ASCII ? using System.Text.Encoding.UTF8 is often usedm, by default, since it will represent more characters.
UPDATE: If you send or receive large amount to byte[] (or string) then you should look at using OpenWriteAsync method and OpenWriteCompleted event.
This is a bug in Mono, please see https://bugzilla.xamarin.com/show_bug.cgi?id=19673

Strange Status Code From Apple Receipt Verification Sandbox

I make a post request of base64 encoded data to the receipt verification address as follows (this is in C#):
var postSerializer = new JavaScriptSerializer();
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Receipt);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
var temp = new Dictionary<string, string>();
temp.Add("receipt-data", returnValue);
string jsonReceipt = postSerializer.Serialize(temp);
request.Method = "POST";
request.ContentType = "application/json";
byte[] postBytes = System.Text.Encoding.ASCII.GetBytes(jsonReceipt);
request.ContentLength = postBytes.Length;
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(postBytes, 0, postBytes.Length);
// Close the Stream object.
dataStream.Close();
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
I'm pretty sure things are in the right format because I'm not getting any exceptions back
from the apple receipt verification endpoint. The entirety of the response I get back is
{status : -42352}
And I can't find out what this error means anywhere. Does anyone know what this means or if there's an error in my code?
Just solved the same problem. Got the solution from here: Verify receipt for in App purchase
The problem was in post encoding. When I encoded post on my server using
$receipt = json_encode(array("receipt-data" => base64_encode($receiptdata)));
I had the same -42352 status. When I used my own function for encoding on iPhone - everything worked! Magic...

Sending protocol buffers via REST

I am trying to implement protocol buffers for client/server using REST.
I am still a bit confused if I need to send protocol buffers request in byte format?
I mean, in my client code, do I need to serialize object to byte array?
For example
protoRequest.build.toByteArray()
And in the server, do I need to c
#POST
#Consumes("application/octet-stream")
public byte[] processProtoRequest(byte[] protoRequest) {
ProtoRequest.Builder request = ProtoRequest.newBuilder();
request.mergeFrom(protoRequest)
}
Is this the right thing to do?
Thanks
David
You can use input stream for this purpose. Server Side Code will be look like the below code
#POST
public Response processProtoRequest(#Context HttpServletRequest req) {
ProtoRequest protoRequestObj = ProtoRequest.parseFrom(req.getInputStream());
///process protoRequestObj and convert into byte arry and send to clinet
return Response.ok(protoRequestObj.toByteArray(),
MediaType.APPLICATION_OCTET_STREAM).status(200).build();
}
client side will look like this:
ProtoRequest protoRequestObj = ProtoRequest.newBuilder(). //protocol buffer object
setSessionId(id).
setName("l070020").
build();
DefaultHttpClinet httpClinet = new DefaultHttpClinet();
HttpPost request = new HttpPost("http://localhost:8080/maven.work/service/mainServices/protoRequest");
request.addHeader("accept","application/octet-stream");
request.setEntity(protoRequestObj.toByteArray());
HttpResponse response = httpClient.execute(request);
I have written a Step by Step tutorial about how to produce/consume a protocol buffer stream in a web service, using Jersey as the client JAX-RS implementation. I hope it will help you. :)
Server side :
#GET
#Path("/{galaxy}")
#Consumes(MediaType.TEXT_HTML)
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getInfo(#PathParam("galaxy") String galaxyName){
if(StringUtils.equalsIgnoreCase("MilkyWay", StringUtils.remove(galaxyName, ' '))){
// The following method would call the DTO Galaxy builders.
Galaxy milkyWay = MilkyWayFactory.createGalaxy();
// This is the important line for you where where the generated toByteArray() method takes responsibility of serializing the instance into a Protobuf format stream
return Response.ok(milkyWay.toByteArray(),MediaType.APPLICATION_OCTET_STREAM).status(200).build();
}
return Response.status(Status.NOT_FOUND).build();
}
Client side :
String serverContext = "learning-protobuf3-ws-service";
String servicePath = "ws/universe/milkyway";
String serviceHost = "localhost";
Integer servicePort = 8080;
javax.ws.rs.client.Client client = javax.ws.rs.client.ClientBuilder.newClient();
javax.ws.rs.client.WebTarget target = client.target("http://"+serviceHost+":"+servicePort+"/"+serverContext)
.path(servicePath);
InputStream galaxyByteString = target.request(MediaType.TEXT_HTML)
.header("accept",MediaType.APPLICATION_OCTET_STREAM)
.get(InputStream.class);
Galaxy galaxy = Galaxy.parseFrom(IOUtils.toByteArray(galaxyByteString));
You could encode the result of SerializeToString using base64.