How to modify webservice proxy to get Raw XML - c#

Here's the proxy method that was created for the web service I'm trying to access. How would I go about modifying it to get the raw XML from the web service call?
/// <remarks/>
[System.Web.Services.Protocols.SoapHeaderAttribute("CallOptionsValue")]
[System.Web.Services.Protocols.SoapHeaderAttribute("MruHeaderValue")]
[System.Web.Services.Protocols.SoapHeaderAttribute("SessionHeaderValue")]
[System.Web.Services.Protocols.SoapHeaderAttribute("QueryOptionsValue")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace = "urn:partner.soap.sforce.com", ResponseNamespace = "urn:partner.soap.sforce.com", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("result")]
public QueryResult query(string queryString)
{
object[] results = this.Invoke("query", new object[] {
queryString});
return ((QueryResult)(results[0]));
}
Thanks for your help!

Fortunately there is a nice way to do it, just modify the generated proxy class so it inherits from different base. The alternative implementation comes from Web Services Enhancements 3.0 pack:
Microsoft.Web.Services3.WebServicesClientProtocol
in the class you'll have RequestSoapContext.Envelope.InnerXml and ResponseSoapContext.Envelope.InnerXml in the scope - that's exactly what you need.

If you want just make a dump using the Fiddler Web Debugging tools.
If you want to really retrive/process raw XML then proxy method will not help you. Create System.Net.HttpWebRequest for the web service, call it, and retrive pure XML response. Format/structure can be found at .ASPX page or web service documentation.

Well, as far as I remember, a buddy of mine that this once with regular ASMX webservices, and it was quite a hack....
How about just serializing the result you get back into XML? That might do the trick...
Something along the lines of (totally untested and from memory):
MemoryStream stm = new MemoryStream();
XmlSerializer xmlSer = new XmlSerializer(typeof(QueryResult));
xmlSer.Serialize(stm, queryResult);
Would that work?
Marc

Related

How to read data from WebClient.UploadData

First time posting! I've been breaking my head on this particular case. I've got a Web application that needs to upload a file towards a web-api and receive an SVG file (in a string) back.
The web-app uploads the file as follows:
using (var client = new WebClient())
{
var response = client.UploadFile(apiUrl, FileIGotEarlierInMyCode);
ViewBag.MessageTest = response.ToString();
}
Above works, but then we get to the API Part:
How do I access the uploaded file? Pseudocode:
public string Post([FromBody]File f)
{
File uploadedFile = f;
String svgString = ConvertDataToSVG(uploadedFile);
return s;
}
In other words: How do I upload/send an XML-file to my Web-api, use/manipulate it there and send other data back?
Thanks in advance!
Nick
PS: I tried this answer:
Accessing the exact data sent using WebClient.UploadData on the server
But my code did not compile on Request.InputStream.
The reason Request.InputStream didn't work for you is that the Request property can refer to different types of Request objects, depending on what kind of ASP.NET solution you are developing. There is:
HttpRequest, as available in Web Forms,
HttpRequestBase, as available in MVC Controllers
HttpRequestMessage, as available in Web API Controllers.
You are using Web API, so HttpRequestMessage it is. Here is how you read the raw request bytes using this class:
var data = Request.Content.ReadAsByteArrayAsync().Result;

Webservice in GAE, call from a C# client

I have created a webapplication on Google App Engine that gets and sets data in datastore, using Python API and it's working fine.
Now I want to access to that data from a client application, written in C# so I was thinking of creating a webservice in GAE to provide access to the data to my app.
I have started to play a bit with ProtoRPC, and built a "hello" webservice as in the tutorial and now I want to call that webservice from my C# client application.
I have found Jayrock lib which seems to do the job; unfortunately I can't find how to make it work.
Here is my code, based on JayrockRPCClient sample :
JsonRpcClient client = new JsonRpcClient();
client.Url = "http://localhost:8081/hello";
JsonObject p = new JsonObject { { "my_name", "Joe" } };
Console.WriteLine(client.Invoke("hello.hello", p));
I always get Missing value error.
Can anybody point me to what do I do wrong ?
And as another question, what do you think of that architecture, as there a simplier way to build a webservice in GAE and call it from C#?
Note that while ProtoRPC communicates via JSON, it is not a JSON-RPC service. By using a JSON-RPC client, you are most likely sending messages in the wrong format.
You should be doing a POST to http://localhost:8081/hello.hello with a request body of {"my_name": "Joe"}. Check to make sure your client is sending requests in this format.
Using WebClient:
var uri = new Uri("http://localhost:8081/hello.hello");
var data = "{\"my_name\":\"Joe\"}";
var wc = new WebClient();
wc.Headers["Content-type"] = "application/json";
wc.Encoding = Encoding.UTF8;
var response = wc.UploadString(uri, data);
For serializing objects, you can use DataContractJsonSerializer.

.Net - Consuming webservice without WSDL

We have a new accounting system that provides webservice interface to external clients. I want to access one of the interfaces but there's no WSDL so i created the request through the use of HttpWebRequest and it works fine.
However to ease the creation of the requests and parsing of the response i would like to create some kind of automapping function. I have the request and response structure in an XSD file. Any ideas?
Request creation:
public void SendRequest()
{
HttpWebRequest request = CreateWebRequest();
XmlDocument soapEnvelopeXml = new XmlDocument();
soapEnvelopeXml.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
++ structure type inserted here ++
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
}
Well, if you really have no way of getting hold of a proper WSDL file but have XSD:s you could probably use the xsd.exe tool to create classes that map to your request and response types.
Something like this (run this in a Visual Studio Command Prompt)
xsd.exe TheRequest.xsd /c /n:Your.Namespace
xsd.exe TheResponse.xsd /c /n:Your.Namespace
But really, try your best to find that WSDL, it will make your life a lot easier..
I recommend that you Create a WSDL - reverse engineer it, and then produce your webservices client stubs from it.
The way to do it:
Get a wire trace of the exact request and response the webservice uses. Use Fiddler or something similar.
Build a WCF service, that approximates the request and response.
Get the trace of that
Compare (3) to (1). Remember you want XML infoset equivalence. Your namespace prefixes need not be the same, for example. Your namespaces need not be declared in the same location. But, the element names need to be exactly the same, and the xmlns strings need to be exactly the same. Modify the WCF service to more closely match the original. Restart it, go to step 3. Iterate as many times as it takes.
point your WCF client to the real web service
sit back and relax.
I've done this and it works. It can be tricky if you don't have insight into how DataContract attributes affect the XML on the wire. But as you play with it, you will gain the insight pretty quickly.
But how is it possible that it is a SOAP service and there is no WSDL on the service side? It might save you a ton of work to re-double your efforts to locate the real WSDL.

json with C# in a WCF service?

I am looking at adding SMS abilities to my WCF service. I found a cheap SMS service called Penny SMS.
Their interface supports json. But I have no idea how to call it in my WCF service.
Here is the interface/example:
Sample JSON-RPC Request
{ "method": "send",
"params": [
"YOUR_API_KEY",
"msg#mycompany.com",
"5551231234",
"Test Message from PENNY SMS"
]
}
How would I call that with C# from a WCF service? What I am looking for is a way to wrap this into a method call. Something like:
StaticSMSClass.SendSMS("1234567890", "My Message to send");
Note they also support an XML-RPC API if that is more doable from C#.
UPDATE: I made a stab at creating a call myself, but it did not work. I am going to post my attempt in a separate question and see if anyone has a way to do it.
You need to send a HTTP POST with the JSON message to the remote server. You can do this with HttpWebRequest. You either build the JSON manually (the messages seem simple), or define types for it and use a JSON serializer.
MSDN has an example, for your case it would look something like (untested):
string json = // Your JSON message
WebRequest request = WebRequest.Create ("http://api.pennysms.com/jsonrpc");
request.Method = "POST";
var postData = Encoding.UTF8.GetBytes(json);
request.ContentLength = postData.Length;
request.ContentType = "text/json";
using(var reqStream = request.GetRequestStream())
{
reqStream.Write(postData);
}
using(var response = request.GetResponse())
{
// Response status is in response.StatusCode
// Or you can read the response content using response.GetResponseStream();
}
See my answer to the question "Client configuration to consume WCF JSON web service" for how the create a JSON client with WCF.
The answers so far are good, but one additional thing you can take advantage of (since you are within a WCF service) is the use of DataContractJsonSerializer.
In particular, I refer to how you actually populate your JSON in the first line of driis's example.
string json = // Your JSON message
Now, one of the best ways to do this may be to create a new class with these members:
[DataContract]
class SomeType
{
[DataMember]
string method;
[DataMember]
string[] params;
}
Then, just create an instance of SomeType every time and serialize it to JSON using the DataContractJsonSerializer every time you want to send over a piece of data. See http://msdn.microsoft.com/en-us/library/bb412179.aspx for how to use the DataContractJsonSerializer stand-alone.
Hope this helps!
Check the WCF REST API. They serve JSON, maybe they also can send JSON (in intra WCF solution it works). Maybe you have to construct the contract in wsdl to get the service running but maybe it works out.

Is there a .NET ready made method to process response body of a HttpListener HttpListenerRequest body?

I'm using HttpListener to provide a web server to an application written in another technology on localhost. The application is using a simple form submission (application/x-www-form-urlencoded) to make its requests to my software. I want to know if there is already a parser written to convert the body of the html request document into a hash table or equivalent.
I find it hard to believe I need to write this myself, given how much .NET already seems to provide.
Thanks in advance,
You mean something like HttpUtility.ParseQueryString that gives you a NameValueCollection? Here's some sample code. You need more error checking and maybe use the request content type to figure out the encoding:
string input = null;
using (StreamReader reader = new StreamReader (listenerRequest.InputStream)) {
input = reader.ReadToEnd ();
}
NameValueCollection coll = HttpUtility.ParseQueryString (input);
If you're using HTTP GET instead of POST:
string input = listenerRequest.Url.QueryString;
NameValueCollection coll = HttpUtility.ParseQueryString (input);
The magic bits that fill out HttpRequest.Form are in System.Web.HttpRequest, but they're not public (Reflector the method "FillInFormCollection" on that class to see). You have to integrate your pipeline with HttpRuntime (basically write a simple ASP.NET host) to take full advantage.
If you want to avoid the dependency on System.Web that is required to use HttpUtility.ParseQueryString, you could use the Uri extension method ParseQueryString found in System.Net.Http.
Make sure to add a reference (if you haven't already) to System.Net.Http in your project.
Note that you have to convert the response body to a valid Uri so that ParseQueryString (in System.Net.Http)works.
string body = "value1=randomvalue1&value2=randomValue2";
// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();

Categories

Resources