How to Handle POST web request on server side? - c#

I am using Soap API (asmx) as web service for my project and I need to send a POST request with JSON data. I saw a code snippet that shows how to send the POST request using HttpWebRequest. This is the code.
string url = "http://myserver.rocket.com.my/WebService1.asmx/AddCompany";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(company);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
My problem is, I am not very sure how to handle the request on server side. Can get any example or guide on how to obtain the json content from the stream?

Well, this is a very big topic but to keep things simple, you could take shelter with one of the existing server-side frameworks.
This also means that you need to select the right kind of programming language. My favourite language is Python but you could very well go with Java, Scala, Ruby, Pearl, PHP, GoLang ... the list is quite big.
If you speak Python then I strongly suggest you start with a simple web framework/library like Python Flask.
Just to answer some other things which will follow, I would strongly recommend you to catch up on MVC/MVP (Model View Controller/Presenter) which is a design pattern used for creating and consuming views.

Related

Adding service reference for Asp.Net webservice

EDIT:
I'm based on some comments that have been deleted, I guess I need to add a service reference and create a instance of the webservice object in the client application to pass the dataset. I haven't been able to add the service reference. When the service runs, it gives a 403 forbidden error, and has done so since I first created the project. I thought this was fine because the apicontroller methods can still be accessed with an HTTP GET, but I have no way of actually sending objects to the service, and can't create the service reference. The service and the client are in separate projects. At this point even a link to a decent tutorial would help. I've found a ton of stuff for creating a full site with a few functions accessed in jquery, and plenty of stuff that includes how to send a post in C#, but nothing that combines both sides.
I saw this question asking a how to do a similar thing. Is there any difference in the client side code I have in c# and the javascript in the question?
EDIT2:
I tried using a memory stream to look at the request content to see if the entire dataset was being transferred. Its only picking up 4000 or so bytes out of 350000 being transferred. I assume this is why the dataset isn't availalbe in teh webservice parameter. but I'm not sure how to continue.
Original:
I'm building a webservice to handle the database calls for my client application. This isn't publicly facing, so I'm fine with passing a dataset instead of a custom model. Heres the client code:
public static void TestSendToDatabase(DataSet Products)
{
string xml = ToXML(Products);
byte[] bytes;
bytes = System.Text.Encoding.ASCII.GetBytes(xml);
StringBuilder urlBuilder = new StringBuilder(string.Format("{0}{1}", BaseUrl, "WalmartProducts/Update"));
string url = urlBuilder.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Accept = "application/xml";
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = bytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes,0,bytes.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
And the service code:
public class WalmartProductsController : ApiController
{
[HttpPost]
[ActionName("Update")]
public object UpdateWalmartProducts([FromBody] byte[] bytes)
{
string xml = System.Text.Encoding.ASCII.GetString(bytes);
DataSet productsFromClient = LoadFromXMLString(xml);
DataUpdater.UpdateWalmartData(productsFromClient.Tables[0]);
return DataUpdater.GetProducts();
}
The byte array is empty in the web service. I'm sure that I'm mixing methods that shouldn't be mixed, but I've gone through at least thirty articles trying to resolve this, and it feels like each one has a completely different method. The webservice is currently returning the dataset in an xml format, so I would prefer to stick with xml over json.
This is not a complete answer, but perhaps it is a starting point. .NET supports two main techniques for writing Web Services. The first is an older technique using .asmx files. This approach is generally called the SOAP approach, and Visual Studio generates signatures of your methods in a .wsdl file. Because the signatures are exposed, you can then ask Visual Studio to create a Web Reference file for you. This web reference exposes all the Web Services as simple classes and methods, hiding all the complexity of the communication across the web service. Any object that can be serialized, including the DataSet object, can be included as a parameter to these web methods, and .NET will take care of serializing and deserializing these objects as they pass across the HTTP boundary. I believe that MS then encapsulated a number of different communication technologies inside of a product they called WCF, which was supposed to allow you to use configuration to choose whether you wanted to use HTTP for communication or TCP/IP.
The downside to this approach is that if you use any MS class in your API's, you have effectively tied your product to MS, and it is then very difficult for any non-MS client to communicate with your web service. The DataSet object is an extremely complicated one, and I'm under the opinion that it would be quite impractical to attempt to write your own serialization/deserialization methods to send a DataSet.
The other Web Service approach that is gaining popularity is using REST API's. Recently, MS added support for these, and the ApiController is one of the starting points. If you google "ASP.NET REST API Tutorial" you should find all kinds of examples. However, with this approach I would discourage you from using the DataSet class. I've had some success with classes such as a Dictionary, provided the object classes you put into the dictionary all resolve down to fairly simple components. Attempting to use a complex MS class like DataSet is likely to lead to a lot of frustration, and will yield a Web Service that very few clients can use.

How to call a microservice in .NET

I've created a very simple REST microservice that receives information about an email and sends it. The microservice send method looks something like this:
//EmailController
[HttpPost]
public IHttpActionResult Send(Email email)
{
// send email via exchange
}
Now in my application, I call it using RestSharp like this:
var client = new RestClient("http://localhost:51467/api/");
var request = new RestRequest("email/send", Method.POST);
request.RequestFormat = DataFormat.Json;
dynamic obj = new ExpandoObject();
obj.FromAddress = from;
obj.ToAddress = to;
obj.Subject = subject;
obj.Body = body;
request.AddBody(obj);
client.Execute(request);
Questions I have:
Is this the best way to do the call? Obviously i'll later have to add error handling etc, but I'm talking more the way I'm using RestSharp to do the call.
I'm finding it a bit uncomfortable that my app needs to kind of know what object the microservice expects to receive - there's no sort of definition/interface/contract that it uses to know for sure. Is this generally accepted as being ok for REST or should I implement some sort of interface that my app has so it can call my microservice in a bit more of a defined way. Is that even something possible with REST?
Thanks for any help!
REST services do not have a schema or WSDL type of function to define the format of the service. This is what makes them more light weight compared to traditional web services.
There is something called WADL, or Web Application Description Language, but this is not really a standard, and isn't widely supported. It's also quite controversial as there are many that feel it's not needed.
http://en.wikipedia.org/wiki/Web_Application_Description_Language
Also see this discussion on Programmers
https://softwareengineering.stackexchange.com/a/133693/4368
I know this is super old but I couldnt help but answer for the sake of currency.
There are two ways of communicating an API contract with other .net services which I find particularly useful.
Ship a nuget package with the contracts (Interfaces describing responses) and possibly some call logic to methodise your api calls
Use swagger to describe your api (seems to have come out as the API description winner, Swashbuckle makes it seamless in .net) and then either hand code the bits you need at the caller or use a codegen
I quite often do both, swagger is also nice for documentation and other language compatibility, and its good practice to be formal about your contracts and backward compatibility.
I would use ASP.NET Web API client libraries. It works with any REST API, whether its coded using .NET or some other framework.
Look here for details: http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client
Nuget package: Microsoft.AspNet.WebApi.Client
I typically don't bother with extra client Libraries like RestSharp. I feel that the purpose of REST is to stay as close to gold old HTTP as possible, negating the need for anything other than HttpWebRequest/Response. Working with the request/responses directly gives great control and encourages you to think about what's actually going on instead of abstracting everything away like you would with a traditional WCF or ASMX service.
For microservices I've built in the past I've kept the request and response objects within separate libraries and I've the distributed the source to other Developers within my organisation to give them a leg up in calling the service but it probably wouldn't be practical for external consumers; again I guess the point of going for a microservice over a full scale WCF service is that by their nature the request/responses being passed around are small and simple. I also felt a little uncomfortable with this practice at the start; however when I started getting really responsive web apps calling microservices with javascript (usually jquery) just as easily as traditional .NET ones I started seeing the potential for some really good integration of our internal systems. Eventually our intranets were providing actions and views into business applications that weren't possible previously.
HttpWebRequest webRequest = WebRequest.Create("http://localhost:51467/api/email/send") as HttpWebRequest;
webRequest.Method = "POST";
webRequest.Credentials = CredentialCache.DefaultCredentials; //or account you wish to connect as
webRequest.PreAuthenticate = true;
webRequest.ContentType = "application/json"; // or xml if it's your preference
string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(requestObject);
using (StreamWriter streamWriter = new StreamWriter(webRequest.GetRequestStream()))
{
streamWriter.Write(jsonData);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse webResponse = webRequest.GetResponse() as HttpWebResponse;
if (webResponse.StatusCode != HttpStatusCode.Accepted)
throw new ApplicationException("Unexpected Response Code. - " + webResponse.StatusCode);
string response;
using (System.IO.StreamReader readResponse = new System.IO.StreamReader(webResponse.GetResponseStream()))
{
response = readResponse.ReadToEnd();
}
//swap out for regular xml serializer if you've used xml
dynamic responseObject = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(response);
Also another tip, if you're working with web api, I'd really suggest adding in the web api help pages and test client. You won't have the automatically generated wsdl you get with WCF and ASMX but you can get some really nice documentation about your microservice for other developers (even better in my opinion that auto generated proxy classes) and a test harness that lets to exercise the service from your browser
https://github.com/wuchang/WebApiTestClient
https://www.nuget.org/packages/Microsoft.AspNet.WebApi.HelpPage/

REST API Put large data

I have a REST API implemented in microsoft Web API.
In my client i use HttpRequestMessage and HttpResponseMessage.
When i am sending a small class, I serialize it to JSON and then send it.
Soon, my class becomes bigger, and I need to JSON the class, zip it (in memory) and send to server. I can no longer use the same technique, I need to send the zip in chunks.
What is the proper way to achieve it ? I have read this post Posting a File and Associated Data to a RESTful WebService preferably as JSON
Need some good articles, I dont know where to start.
On the client side this should work pretty much out of the box...
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
var content = new CompressedContent(new StreamContent(new FileStream("c:\\big-json-file.json",FileMode.Open)),"UTF8");
var response = httpClient.PostAsync("http://example.org/", content).Result;
You can find an implementation of CompressedContent in WebApiContrib. If you are using earlier than .net 4.5 the request will be buffered client side before sending. Unfortunately the underlying HttpWebRequest doesn't support buffered streaming until .net 4.5

Easy alternative to HttpWebRequest for POST requests?

I need to trigger an action on a remote server using an http POST request. The server sends a response, either Y or N, to inform me if the action suceeded or not.
I am looking at using HttpWebRequest to do this, but this seems too complex. To use this class you have to set all the headers, such as content type and content length.
Is there a quicker way to send a POST request that doesn't require setting lower level properties such as this?
Try this WebClient
// Create a new WebClient instance.
WebClient myWebClient = new WebClient();
byte[] responseArray = myWebClient.UploadData("YOUR URI","POST","DATA to be Posted");
You can try with WebClient class. It's much more simpler and it's basically a wrapper for HttpWebRequest. It encapsulate all this complex logic you're trying to avoid.
I think the easiest built in class in the framework is WebClient. Scott Hanselman has an example on how to perform gets and posts using it. This SO answer also has a good overview on how to post data.
If you have control over the server you're posting to, you might want to consider making it respond with HTTP status codes instead of some custom method.
the wcf web api project has an http client. It's super easy to use. http://wcf.codeplex.com/

Integrate a C# client into a node.js + socket.io chat app

As part of learning node.js, I just created a very basic chat server with node.js and socket.io. The server basically adds everyone who visits the chat.html wep page into a real time chat and everything seems to be working!
Now, I'd like to have a C# desktop application take part in the chat (without using a web browser control :)).
What's the best way to go about this?
I created a socket server in nodejs, and connected to it using TcpClient.
using (var client = new TcpClient())
{
client.Connect(serverIp, port));
using (var w = new StreamWriter(client.GetStream()))
w.Write("Here comes the message");
}
Try using the HttpWebRequest class. It is pretty easy to use and doesn't have any dependencies on things like System.Web or any specific web browser. I use it simulating browser requests and analyzing responses in testing applications. It is flexible enough to allow you to set your own per request headers (in case you are working with a restful service, or some other service with expectations of specific headers). Additionally, it will follow redirects for you by default, but this behavior easy to turn off.
Creating a new request is simple:
HttpWebRequest my_request = (HttpWebRequest)WebRequest.Create("http://some.url/and/resource");
To submit the request:
HttpWebResponse my_response = my_request.GetResponse();
Now you can make sure you got the right status code, look at response headers, and you have access to the response body through a stream object. In order to do things like add post data (like HTML form data) to the request, you just write a UTF8 encoded string to the request object's stream.
This library should be pretty easy to include into any WinForms or WPF application. The docs on MSDN are pretty good.
One gotcha though, if the response isn't in the 200-402 range, HttpWebRequest throws an exception that you have to catch. Fortunately you can still access the response object, but it is kind of annoying that you have to handle it as an exception (especially since the exception is on the server side and not in your client code).

Categories

Resources