Using JSON and HTTP Request in C# - c#

I'm currently developing an Android app and I'm using Connect Android to MS SQL Server Tutorial to link my MSSQL server to the code.
And the first part is good though the second part is using a third party program to code which I don't want to. I want to write the whole code in C# (I'm using Xamarin).
I found out Json.NET / Json.NET for Xamarin website.
Though how am I supposed to use the HTTPUtils and requests in C# ? An example would be great.
Also, I have kind of a newbie question, I'm trying to get to the root of the code I sent, the .aspx file, and I don't quite understand where the web method is, I am used to a seperate .asmx file containing [Web Method]s that define them and then I can use them freely by creating a web reference on an .aspx file, so, where is the web method in the code I sent ?

public static String getJsonData(String webServiceName,String parameter)
{
try
{
String urlFinal=SERVICE_URI+"/"+webServiceName+"?parameter=";
HttpPost postMethod = new HttpPost(urlFinal.trim()+""+URLEncoder.encode(parameter,"UTF-8"));
postMethod.setHeader("Accept", "application/json");
postMethod.setHeader("Content-type", "application/json");
HttpClient hc = new DefaultHttpClient();
HttpResponse response = hc.execute(postMethod);
Log.i("response", ""+response.toString());
HttpEntity entity = response.getEntity();
String responseText = EntityUtils.toString(entity);
string=responseText;
Log.i("Output", ""+responseText);
}
catch (Exception e) {
// TODO: handle exception
}
return string;
}

Related

Verify application for Loader.Io testing

I am trying to do some load testing with
https://loader.io/
I am currently stuck at the stage of "verifying" my localHost application to make sure I am the one controlling it.
I have added this end point:
[HttpGet("/loaderio-a65421134i3ia3d110vcv0120d1ac14b/")]
[Authorize()]
public StreamReader GetLoaderIO()
{
var file = System.IO.File.OpenText(#"C:\Users\User\Downloads\loaderio-a65421134i3ia3d110vcv0120d1ac14b.txt");
return file;
}
When I run a GET request to this URL
http://localhost:5012/loaderio-a65421134i3ia3d110vcv0120d1ac14b/
I successfully step in my end point, what do I need to return in order for the LoaderIO to be happy? Do I have to return the stream so it can be downloaded?
I can see three potential issues with your code.
First, you are targeting a localhost address instead of a deployment address (i.e. http://yourapi.com or 159.254.102.69). To fix that issue you will need to either deploy your code somewhere or open http ports from your machine.
Second the file you are trying to retrieve my not be at the same location or might not even be accessible so a simpler way would be to write the string directly (done multiple time to verify on loader.io works like a charm) like below:
[HttpGet]
[Route("loaderio-a65421134i3ia3d110vcv0120d1ac14b")]
public HttpResponseMessage GetLoaderIoVerification()
{
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("loaderio-a65421134i3ia3d110vcv0120d1ac14b", Encoding.UTF8, "text/plain");
return response;
}
Finally, there is that Authorize attribute that will try to authenticate the loader.io request that needs to be a resource as accessible as this one: https://media4.giphy.com/media/LXONhtCmN32YU/giphy.gif In order to do so you will need to remove it.
Once those three points are corrected you will be able to verify your api for loader.io. Hope it helps.

Why does WebClient.UploadValues overwrites my html web page?

I'm familiar with Winform and WPF, but new to web developing. One day saw WebClient.UploadValues and decided to try it.
static void Main(string[] args)
{
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["thing1"] = "hello";
values["thing2"] = "world";
//A single file that contains plain html
var response = client.UploadValues("D:\\page.html", values);
var responseString = Encoding.Default.GetString(response);
Console.WriteLine(responseString);
}
Console.ReadLine();
}
After run, nothing printed, and the html file content becomes like this:
thing1=hello&thing2=world
Could anyone explain it, thanks!
The UploadValues method is intended to be used with the HTTP protocol. This means that you need to host your html on a web server and make the request like that:
var response = client.UploadValues("http://some_server/page.html", values);
In this case the method will send the values to the server by using application/x-www-form-urlencoded encoding and it will return the response from the HTTP request.
I have never used the UploadValues with a local file and the documentation doesn't seem to mention anything about it. They only mention HTTP or FTP protocols. So I suppose that this is some side effect when using it with a local file -> it simply overwrites the contents of this file with the payload that is being sent.
You are using WebClient not as it was intended.
The purpose of WebClient.UploadValues is to upload the specified name/value collection to the resource identified by the specified URI.
But it should not be some local file on your disk, but instead it should be some web-service listening for requests and issuing responces.

ASP .NET Web API reading inputstream twice

I am using ASP .NET Web API and I have a Controller that have code similar to this:
[Route("UpdateData")]
[HttpPost]
public HttpResponseMessage UpdateData([FromBody]RequestClasses.UpdataData data)
{
string json;
if (HttpContext.Current.Request.InputStream.Length > 0)
{
HttpContext.Current.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(HttpContext.Current.Request.InputStream))
{
json = inputStream.ReadToEnd();
}
}
// Dencrypt json
return Request.CreateResponse(HttpStatusCode.OK);
}
As input parameter I have "[FromBody]RequestClasses.UpdataData data". I have this in order to be able to show a Help page (using Microsoft.AspNet.WebApi.HelpPage).
The data object received in this method is encrypted and I need to decrypt it.
My problem is that I cannot call HttpContext.Current.Request.InputStream because the "[FromBody]RequestClasses.UpdataData data" has disposed my InputStream.
Any good ideas to solve this? As I still need the help page to show which parameters to call the method with.
By design ASP.NET Web API can only read the payload input stream once. So, if the parameter binder reads it, you don't have it available. That's way people is telling you in the comments to use parameterless methods, and read the payload yourself.
However, you want to have parameters to see them in the help page. There is a solution for that: do the decryption of the request in previous steps. To do that you can use Message handlers. Please, see this: Encrypt Request/Reponse in MVC4 WebApi

Why does my API return {}

I've created a .NET API, but when I try to use it I'm getting strange results.
If I go to the URL of an API call in Chrome I get the result I would expect, in XML format, but if I try it in IE it downloads a file and when I open it it just says {} or sometimes [{},{},{},{}] if I try a call that returns an array.
I've also tried using a webclient.
WebClient web = new WebClient();
var data = web.DownloadString("http://myAPI.example.com/api/MyAPI/APIMethod?parameter1=hiImAParameter");
This also returns empty {}.
I've tried searching online, but I don't see any mentions of this problem anywhere. I'm sure I must be missing something somewhere, but I've tried looking over how I set up my API, and it all looks fine to me.
Edit:
Here's the response I get in Chrome.
<ArrayOfRoute xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/TimePointModel">
<Route>
<RouteId>11235</RouteId>
<RouteName>Fibonacci</RouteName>
<Status i:nil="true"/>
<Width>0</Width>
</Route>
</ArrayOfRoute>
It returns XML on Chrome because of Chrome's accept headers. It's supposed to return JSON on IE, but for some reason the JSON is empty.
This is in my api controller:
[AcceptVerbs("GET")]
public IEnumerable<Route> APIMethod(double parameter)
{
return new Manager(parameter).GetRoutes();
}
This is in my Global.asax.cs:
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute(
name: "APIMethod",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "APIMethod", id = System.Web.Http.RouteParameter.Optional }
);
}
Edit:
This works great when I do an API call which doesn't require parameters.
WebClient web = new WebClient();
var data = web.DownloadString("http://myAPI.example.com/api/MyAPI/SimpleAPIMethod");
I've been doing research, and I tried adding parameters like this:
NameValueCollection myQueryStringCollection = new NameValueCollection();
string myParameter = "hiImAParameter";
myQueryStringCollection.Add("parameter1", myParameter);
web.QueryString = myQueryStringCollection;
var data = web.DownloadString("http://myAPI.example.com/api/MyAPI/APIMethod");
I've noticed that the number of empty {} in my array matches the number of items in the array if I put the full url with the querystring into chrome. It just empties them out for my webclient.
I also tried adding
web.Headers[HttpRequestHeader.ContentType] = "application/json";
before making the call, but there's still no change in the result.
And I tried to follow that tutorial, but it's written for a console application and they're using HttpClient. I can't do that because I can't do Asynchronous calls. This is to be used by a website. That's why I'm using WebClient. I also tried using StreamReader with HttpWebRequest and HttpWebResponse, but it had the same problem as I've been encountered with WebClient.
Without more information, it's a bit hard to diagnose your issue. However, I would say that it is likely your web API is interpreting the expected response type and providing an empty result as it does not support responses of that type, such as happens with ASP .NET Web API websites.
In that sense, the DownloadString is indicating it is expecting a text/html response. You should probably download the Microsoft ASP .NET Web API Client Libraries with NuGet. This library will give you HttpClient which has support for making the queries you want to make with responses such as application/json and application/xml.
You can view a tutorial on how to do the calls right here.
If you want it to work from your web browser, you need to ensure the Accept header field is correct, as you mentioned. Ensure it is being communicated with IE by using something like Fiddler.
I figured out what the problem was. I needed to add [DataMember] attributes to the attributes of the items in the list. I didn't realize it was left out of the return type of that call.

How to create an otrs ticket using a soap request

The lack of documentation on this subject coupled with the fact that I'm struggling with a learning curve on all fronts and making me really confused about where to start. I need to get this done using C# if possible. I apologize for the vagueness of this question, but I'm really lost. I would love links to comprehensive guides/references.
In my efforts to get this done, I've run into the following problems/questions:
I've created a web service using the otrs gui, with the operation CreateTicket, but requests via C# to my chosen namespace are returning 404 (not found). When I try to add a service reference or web reference with that namespace, I get the same error. However, when I plug that namespace into my browser as the url, it displays "customer.pl".
Can I send a soap request without adding the web service as a service reference in visual studio? Given the previous problem I'm having I can't do it that way. Would I just build the soap request string and write it to the web request's data stream with http://domain/rpc.pl as the uri?
If the answer to the previous question is yes... When trying the below code segment I get an internal server error (500) on the last line. However the header looks like a SOAP header which confuses me because I wouldn't have thought it got that far.
var document = new StringBuilder();
document.Append("<UserLogin>some user login</UserLogin>");
document.Append("<Password>some password</Password> ");
document.Append("<Ticket>");
document.Append("<Title>some title</Title> ");
document.Append("<CustomerUser>some customer user login</CustomerUser>");
document.Append("<Queue>some queue</Queue>");
document.Append("<State>some state</State>");
document.Append("<Priority>some priority</Priority>");
document.Append("</Ticket>");
document.Append("<Article>");
document.Append("<Subject>some subject</Subject>");
document.Append("<Body>some body</Body>");
document.Append("<ContentType>text/plain; charset=utf8</ContentType>");
document.Append("</Article>");
//var uri = new Uri("http://domain/injest");
var uri = new Uri("http://domain/rpc.pl");
var httpWebReq = (HttpWebRequest)WebRequest.Create(uri);
var bytePostData = Encoding.UTF8.GetBytes(document.ToString());
httpWebReq.Timeout = 5 * 1000;
httpWebReq.Method = "POST";
httpWebReq.ContentLength = bytePostData.Length;
httpWebReq.ContentType = "text/xml;charset=utf-8";
//httpWebReq.TransferEncoding=
//httpWebReq.ContentType = "application/xml";
//httpWebReq.Accept = "application/xml";
var dataStream = httpWebReq.GetRequestStream();
dataStream.Write(bytePostData, 0, bytePostData.Length);
dataStream.Close();
var httpWebResponse = (HttpWebResponse)httpWebReq.GetResponse();
Even if all you can offer is where to start, it would help me to know how to proceed, as I'm stumped.
You're using the rpc.pl endpoint which is part of the 'old' RPC-style interface.
You mention you added the web service via the GUI which means you're using the 'new' Generic Interface, which is indeed much easier from .Net.
The address of the endpoint is /otrs/nph-genericinterface.pl/Webservice/GenericTicketConnector or whatever you have called the web service in the admin section.

Categories