Passing a string param to a RESTful service during POST action - wcf

I am having a RESTful service with the following method:
[WebInvoke]
string GetDataFromStringAsString(string xmlString);
My client call to the method is as below:
var client = new RestClient();
client.BaseUrl = serviceBaseUrl;
var request = new RestRequest(method){RequestFormat = DataFormat.Xml};
request.Resource = resourceUrl;
request.AddParameter("text/xml", requestBody,
ParameterType.RequestBody);
var response = client.Execute(request);
Let us take a string to post as "Hello World".
Now the string that i post to the above method gives me a 400 Bad
request. In order to get it working i had to wrap the above string in
a element as shown below:
<string xmlns="http://schemas.microsoft.com/2003/10/
Serialization/">Hello World</string>
Now when i post the above string i get a success response back from
the server.
Why is that i have to manually wrap the string to make it work. Is
there a way that i can achieve to post a string without doing the
above manually.

The only other way that I am aware of is to use stream as your input parameter. e.g.
[WebInvoke]
string GetDataFromStringAsString(stream xmlString);
The problem with .Net 4 WCF REST is that fundamentally WCF only knows how to pass two types of info, either XML or a stream of bytes. Personally, I would use WCF Web API instead of the standard WCF REST library because you are going run into lots more of these kinds of issues.

Related

WinHttpRequest: Send method

I'm trying to pass parameters in the request body, the documentation says :
The request to be sent was defined in a prior call to the Open method. The calling application can provide data to be sent to the server through the Body parameter. If the HTTP verb of the object's Open is "GET", this method sends the request without Body, even if it is provided by the calling application.
So, I need to use POST with body. But when I use use POST with body I have error "Bad Request: message text is empty" and when I use GET with body result is ok. Why?
My code:
WinHttp = NEW COMObject("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("GET", "http://api.telegram.org/botbotname/sendMessage", 0);
WinHttp.setRequestHeader("Content-type", "application/json");
JSONWr = New JSONWriter();
JSONWr.ValidateStructure = False;
JSONParams = New JSONWriterSettings( , Chars.Tab);
JSONWr.SetString(JSONParams);
JSONWr.WriteStartObject();
JSONWr.WritePropertyName("chat_id");
JSONWr.WriteValue(UserId);
JSONWr.WritePropertyName("text");
JSONWr.WriteValue(Text);
JSONWr.WriteEndObject();
JSONString = JSONWr.Close();
WinHttp.Send(JSONString);
work, but how? And why the same with POST doesn`t work?

How to get the raw response as a String in Spring webflux?

return webClient//
.post()//
.uri(whatever.com)
.header("Authorization", "Bearer " + authToken)//
.header("userId", CLIENT_ID)//
.header("clientRequestId", requestId)//
.bodyValue(bodyValue())//
.retrieve()//
.bodyToMono(Responseclass.class)//
.block();
The above is working. But let's say I'm debugging and I just want to dump the raw response json into a String. How would I do that? toString() after retrieve doesn't work, and bodyToMono(String.class) didn't seem to work either. Either way it just printed the default toString value of the address of the pointer.
With Spring Webflux WebClient you can get response as String like this:
WebClient client = WebClient.create("http://someurl.de/something");
String responseBody = client.get().retrieve().toEntity(String.class)
.block().getBody();
In my German blog I wrote an article about using WebClient, there you will find more details around the code snippet above:
https://agile-coding.blogspot.com/2021/01/reactive-webclient.html

Sending JSON data to rest api

I have started to learn about REST API. So far I have been able to call my REST API post data using the form and also to get values from my REST API. Now I am trying to learn to send my data to my REST API using JSON object. I have been searching on the net and reading on StackOverflow on how to implement it but so far there is no luck. I am looking for some basic code examples where I can get an idea of how it's done. If some could help me with some codes on how to send data to my REST API using JSON and also how to retrieve that JSON data in my REST API it will be very helpful to me in learning REST API(Just the basic codes I hope it shouldn't take much of your time to post some codes). Btw I am using Jersey to implement my REST API. Thanks in Advance :) It really will be helpful to me in understanding sending JSON data to my web service Thanks again :)
The language is JAVA(JAX-RS implemented in Jersey)
While sending data in json request, your request should be in the form of a map (key value pair ). Key should be your attribute name and values as the value for the attribute.
For example if you are trying to find a employee using employeeid the your request should be of the form {data:{"employeeid":"1"}}
Be more specif about which platform you are using to call the RESTservice.
Hope this will help you.
var clientCreateOrder = new RestClient("#######################");
var requestCreateOrder = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
//Use below code for creating and sending dynamic json objects to RESTAPI
object[] purchase_units_arr = new object[1];
purchase_units_arr[0] = new
{
amount = new
{
currency_code = "USD",
value = "100.00"
}
};
var body = new
{
intent = "CAPTURE",
purchase_units = purchase_units_arr,
};
//Serialize Json object
request.AddParameter("undefined", new JavaScriptSerializer().Serialize(body).ToString(), ParameterType.RequestBody);
IRestResponse responseCreateOrder = client.Execute(request);

Magento API SOAP v1 and VB.NET

I'm using VB.NET to communicate with Magento via the API SOAP v1. I had it working fine until I got to a call that needed an associative array. I've tried dictionaries, hashtables, custom types, etc. I did read hashtables and dictionaries are not serializable. So I tried the custom type/object/class. Below is the error I received:
The type XXXX was not expected. Use the Xmlinclude or SoapInclude attribute to specify types that are not known statically.
So I've read a lot of posts in regards to the above error and I can't get anything to work. The error seems at least to say what I'm trying is possible if I do it right, but maybe that is not the case. I don't know much about SOAP, but I can see this never working since the web service might not know how to handle the object.
So my question is if it's possible to send a custom object to the Magento API. Or more broadly is it possible to get SOAP v1 to work with VB.NET. I know v2 is an option but I'm pretty familiar with v1 and already having it working in VB.NET other than this scenario.
Answering a question you didn't ask — but have you considered using the XML-RPC adapter for the V1 API? It exposes the same exact methods as the SOAP API, but since XML-RPC doesn't have the same strong concept of types that SOAP does you may be able to get a generic object through from .NET (said without being that familiar with .NET SOAP or XML-RPC libraries)
It took a lot of digging, but I have it all working. To start I used the PHP SoapClient and noted how it formed associative arrays in the soap request. You can trace requests and responses, pretty handy. From there I wrote my own soap client in VB.NET using a WebRequest object. In doing so I have full control over the xml being sent to the API.
Again the reason I went down this road is ultimately V2 was not working for me. For some reason not all parameters were making it to the API. That and the fact I'm pretty comfortable with V1 too. I've written several custom APIs.
I apologize for the brevity, but there is a lot that went into this. Probably most of my time was hitting multiple dead ends. If anyone wants specifics feel free email me.
EDIT:
Here is the php code I used to see how I needed to format the requests:
$client = new SoapClient('http://www.site.com/index.php/api/soap/?wsdl',array('trace' => TRUE));
$session = $client->login('user','api-key');
echo $client->__getLastRequest() ."\n\n";
echo $client->__getLastRequestHeaders() ."\n\n";
echo $client->__getLastResponse() ."\n\n";
echo $client->__getLastResponseHeaders() ."\n\n";
$result = $client->call($session, 'cataloginventory_stock_item.list','393');
echo $client->__getLastRequest() ."\n\n";
echo $client->__getLastRequestHeaders() ."\n\n";
var_dump($result);
$client->endSession($session);
Below is how to send the request using VB.NET. You will need to construct the XML/SOAP body using the php above as a guide. I made a class per API call which output the needed XML. You will need System.Net, System.Xml & System.IO. I used getSoapHeader() because there is some common XML that goes into a request. See next code section for more details:
Private Function makeSoapRequest(ByVal soapBody As String) As String
Dim req As WebRequest = WebRequest.Create(_soap_url)
Dim xml As String
xml = getSoapHeader() & soapBody
Dim buffer() As Byte = System.Text.Encoding.UTF8.GetBytes(xml)
req.ContentType = "text/xml; charset=utf-8"
req.Method = "POST"
req.Headers.Add("SOAPAction", "urn:Mage_Api_Model_Server_HandlerAction")
req.ContentLength = buffer.Length
Dim st As System.IO.Stream = req.GetRequestStream
st.Write(buffer, 0, buffer.Length)
st.Close()
Dim response As WebResponse
Try
response = req.GetResponse
Catch ex As WebException
response = ex.Response
End Try
st = response.GetResponseStream()
Dim reader As New StreamReader(st)
Dim responseFromServer As String = reader.ReadToEnd()
makeSoapRequest = responseFromServer
response.Close()
st.Close()
End Function
Below is the getSoapHeader() function. As noted the ns2 portion is only needed if you are using type="ns2:Map" which is what I needed for associative arrays:
Private Function getSoapHeader() As String
'ns2 is not always needed
getSoapHeader = "<?xml version=""1.0"" encoding=""UTF-8""?><SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:ns1=""urn:Magento"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:SOAP-ENC=""http://schemas.xmlsoap.org/soap/encoding/"" xmlns:ns2=""http://xml.apache.org/xml-soap"" SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/""> " & vbCrLf
End Function

Crawl Wikipedia using ASP.NET HttpWebRequest

I am new to Web Crawling, and I am using HttpWebRequest to crawl data from sites.
As of now I was successfully able to crawl and get data from my wordpress site. This data was a simple user profile data. (like name, email, AIM id etc...)
Now as an exercise I want to crawl wikipedia, where I will search using the value entered into textbox at my end and then crawl wikipedia with the search value and get the appropriate title(s) from the search.
Now I have the following doubts/difficulties.
Firstly, is this even possible ? I have heard that wiki has robot.txt setup to block this. Though I have heard this only from a friend and hence not sure.
I am using the same procedure I used earlier, but I am not getting the required results.
Thanks !
Update :
After some explanation and help from #svick, I tried the below code, but still not able to get any value (see last line of code, there I am expecting an html markup of the search result page)
string searchUrl = "http://en.wikipedia.org/w/index.php?search=Wikipedia&title=Special%3ASearch";
var postData = new StringBuilder();
postData.Append("search=" + model.Query);
postData.Append("&");
postData.Append("title" + "Special:Search");
byte[] data2 = Crawler.GetEncodedData(postData.ToString());
var webRequest = (HttpWebRequest)WebRequest.Create(searchUrl);
webRequest.Method = "POST";
webRequest.UserAgent = "Crawling HW (http://yassershaikh.com/contact-me/)";
webRequest.AllowAutoRedirect = false;
ServicePointManager.Expect100Continue = false;
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(data2, 0, data2.Length);
requestStream.Close();
var responseCsv = (HttpWebResponse)webRequest.GetResponse();
Stream response = responseCsv.GetResponseStream();
// Todo Parsing
var streamReader = new StreamReader(response);
string val = streamReader.ReadToEnd();
// val is empty !! <-- this is my problem !
and here is my GetEncodedData method defination.
public static byte[] GetEncodedData(string postData)
{
var encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
return data;
}
Pls help me on this.
You probably don't need to use HttpWebRequest. Using WebClient (or HttpClient if you're on .Net 4.5) will be much easier for you.
robots.txt doesn't actually block anything. If something doesn't support it (and .Net doesn't support it), it can access anything.
Wikipedia does block requests that don't have their User-Agent header set. And you should use an informative User-Agent string with your contact information.
A better way to access Wikipedia is to use its API, rather than scraping. This way, you will get an answer that's specifically meant to be read by a custom applications, formatted as XML or JSON. There are also dumps containing all information from Wikipedia available for download.
EDIT: The problem with your newly posted code is that your query returns a 302 Moved Temporarily response to the searched article, if it exists. Either remove the line that forbids AllowAutoRedirect, or add &fulltext=Search to your query, which will mean you won't get redirected.