SpringWS - Logging SoapRequest and SoapResponse in a table - soap

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.

Related

Get SOAP Reply in ASP.NET Webservice

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;
}

SendGrid incoming mail webhook - how to save the JSON format email data into my application folder in C#

This is regarding Sendgrid incoming mail webhook, I have referred this URL SendGrid incoming mail webhook - how do I secure my endpoint, and got some idea how to go about this, but, as I am new to MVC / WebAPI, could anyone give me the controller method code snippet to catch the JSON format HTTP post and save to my application folder.
This is the solution I found after googling and with slight modifications:
[HttpPost, HttpGet]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public async Task Post()
{
if (Request.Content.IsMimeMultipartContent("form-data"))
try
{
//To get complete post in a string use the below line, not used here
string strCompletePost = await Request.Content.ReadAsStringAsync();
HttpContext context = HttpContext.Current;
string strFrom = context.Request.Form.GetValues("from")[0];
string strEmailText = context.Request.Form.GetValues("email")[0];
string strSubject = context.Request.Form.GetValues("subject")[0];
//Not useful I guess, because it always return sendgrid IP
string strSenderIP = context.Request.Form.GetValues("sender_ip")[0];
}
catch (Exception ex)
{
}
}
I tried, retrieving the values as
String to = context.Request.Params["to"];
but, the value returned is not consistent, i.e. most of the times it is returning null and occasionally returns actual value stored in it.
If anyone have a better solution, please let me know.
Thank you
If for some reason ["to"] doesn't work for you, try to get ["envelope"] value,
context.Request.Form.GetValues("envelope")[0]
which looks like
{"to":["emailto#example.com"],"from":"emailfrom#example.com"}

Google sites API, IllegalArgumentException("Trying to set foreign cookie") after RedirectRequiredException

I am using the gdata-media-1.0-1.47.1.jar functionality to fetch media data using the com.google.gdata.client.media.MediaService.getMedia(IMediaContent mediaContent) method. For some requests I get a RedirectRequiredException. When I redo the getMedia request, using the url i get from RedirectRequiredException.getRedirectLocation(), I get an IllegalArgumentException("Trying to set foreign cookie") exception.
From what I can see, the reason for this is that the domain in the response header for the cookie doesn't match the domain of the redirect location. In com.google.gdata.client.http.GoogleGDataRequest.matchDomain() the first argument is ".docs.google.com" and the second is "docs.google.com" which makes the domain matching fail.
Is this a correct behaviour? Why is this happening? Is there something I can do about this? Am I doing anything wrong here? Is is possible to avoid this problem?
SitesService sitesService = new SitesService("SomeAppName");
try {
MediaContent mc = new MediaContent();
mc.setUri(aURI);
return sitesService.getMedia(mc);
} catch (RedirectRequiredException e) {
MediaContent mc = new MediaContent();
mc.setUri(e.getRedirectLocation());
return sitesService.getMedia(mc);
}

How can I read SOAP-Headers and add FaultHeaders to a response sent by an AXIS 2 Web Service

I have a WSDL that defines a custom SOAP-header that the client needs to send and a SOAP-Fault header that the server could send as a response.
Now I have a problem. I cannot for the life of me fathom how to set SOAP-Fault-headers on a response generated with AXIS 2 (Version 1.6.1) or read SOAP-Headers that come with a request.
Can anyone point me in the right direction?
Thank you very much in advance.
If is security related you should look to Rampart.
If not, try looking into
ClientSide:
From your stub, retrieve the ServiceClient via _getServiceClient().
enter link description here
ServerSide:
If I recall correctly is done via MessageContext, so from axiscontext opbtain current message context.
Add custom fault to soap response. This can be done in one of two ways.
1) Simply throwing a Java exception with a message will generate a simple Axis2 fault
Example:
throw new java.lang.UnsupportedOperationException("Please implement " +
this.getClass().getName() + "#SomeOperationName");
Also please note: If you generated your service using the Axis2 WSDL2JAVA utility, the line above will be added to the MyServiceName_Skeleton source for each defined WSDL Operation.
Once the .aar is deployed, connectivity to each operation can be verified using a web browser, e.g. https://server:port/axis2/services/MyServiceName?SomeOperationName.
2) Ensure that the WSDL defines an optional (occurs:0) custom Fault structure. This can be sent to client with any other required (and empty) elements.
Example:
com.some.service.operation.SomeOperationNameResponse_Type OPRT = new com.some.service.operation.SomeOperationNameResponse_Type();
com.some.service.SomeOperationNameResponse OPR = new com.some.service.SomeOperationNameResponse();
.
.
.
if ((rcStatusString.equals("Succeeded")) || (rcStatusString.equals("Warning"))) {
<build happy path response>
} else if (rcStatusString.equals("Failed")) {
final MYFault fault = new MYFault();
final MYFault_Type faultType = new MYFault_Type();
final MYFaultList faultList = new MYFaultList();
final MYFaultList_Type faultListType = new MYFaultList_Type();
faultType.setFaultCode("10100");
faultType.setFaultSubcode("9999");
faultType.setFaultType(FaultType_Enum.SYSTEM);
faultType.setFaultReasonText("Some Operation Failed");
faultType.setSeverity(FaultSeverity_Enum.CRITICAL_ERROR);
//fault.setMYFault(faultType);
faultListType.addMYFault(faultType);
OTHRTYPE.setAValue("");
OPRT.setAValueType(OTHRTYPE);
OPRT.setMYFaultList(faultListType);
} else {
throw new java.lang.UnsupportedOperationException(
"MYSERVICE: [Some Operation] Session: "+sessVal+" Request ID: "+rcRequestId+" Unrecognized Completion Status ["+rcStatusString+"]");
}
OPR.setSomeOperationResponse(OPRT);
return OPR;
}

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