How to read data from WebClient.UploadData - c#

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;

Related

Expected X-Hub-Signature via SHA1 not same as what FB is sending (code in C#)

I am having problems getting the X-Hub-Signature sent to me by facebook to match the one I am generating in C#. For a while I thought I was running the function wrong but I have now used multiple code sources on Stack Overflow and a website (http://billatnapier.com/security01.aspx) to confirm I am indeed creating the SHA-1 correctly.
So .... something is clearly wrong with the content. I am using ASP.NET Web API and the "Payload" that I am using to feed into the SHA-1 algorithm is the JSON object I am receiving from facebook, converted to a string. I assume this is what they want me to use when they say "Payload" is that correct?
It is a string that begins with {"entry":[ and ends with "object":"page"}
I feel like I've tried everything and have hit a brick wall so hoping someone can help me. Web API is a bit off - even grabbing the X-Hub-Signature was a challenge as you can't just use Request.Header["X-Hub-Signature"]; I am almost wondering if I should switch back to pure MVC.
OK so I am answering my own question! The problem with the "Payload" is that you can't simply grab the JSON object. You have to find a way to access the Request object from Web API and then read in the payload like this:
var context = Request.Properties["MS_HttpContext"] as HttpContextWrapper;
using (StreamReader reader = new StreamReader(context.Request.InputStream))
{
payload = reader.ReadToEnd();
}
It looks like binning Web API and just doing this in MVC would be easier as you then just do this:
using (StreamReader reader = new StreamReader(HttpContext.Request.InputStream))
{
PayLoad = reader.ReadToEnd();
}

Authenticating requests to external REST service

I'm really new to web development, and I don't really have a good grip on the main concepts of web. However, I've been tasked with writing an asp.net application where users can search documents by querying an external RESTful web service. Requests to this REST service must be authenticated by HTTP Basic Authentication.
So far so good, I've been able to query the service using HttpWebRequest and HttpWebResponse, adding the encoded user:pass to the request's authorization header, deserialize the Json response and produce a list of strings with url's to the pdf documents resulting from the search.
So now I'm programmatically adding HyperLink elements to the page with these urls:
foreach (string url in urls) {
HyperLink link = new HyperLink();
link.Text = url;
link.NavigateUrl = url;
Page.Controls.Add(link);
}
The problem is that requests to these documents has to be authorized with the same basic http authentication and the same user:pass as when querying the REST service, and since I'm just creating links for the user to click, and not creating any HttpWebRequest objects, I don't know how to authenticate such a request resulting from a user clicking a link.
Any pointers to how I can accomplish this is very much appreciated. Thanks in advance!
You probably want to do the request server-side, as I think you're already doing, and then show the results embedded in your own pages, or just stream the result directly back to the users.
It's a bit unclear what it is you need (what are the links, what do you show the users, etc.), so this is the best suggesting I can do based on the info you give.
Update:
I would create a HttpHandler (an .ashx file in an ASP.NET project), and link to that, with arguments so you can make the request to the REST service and get the correct file, then stream the data directly back to the visitor. Here's a simple example:
public class DocumentHandler : IHttpHandler {
public Boolean IsReusable {
get { return true; }
}
public void ProcessRequest(HttpContext context) {
// TODO: Get URL of the document somehow for the REST request
// context.Request
// TODO: Make request to REST service
// Some pseudo-code for you:
context.Response.ContentType = "application/pdf";
Byte[] buffer = new WebClient().DownloadData(url);
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.End();
}
}
I hope you can fill in the blanks yourself.

POSTing to an ASP MVC 4 site from a C# Windows application

I'm writing a Windows application that will communicate with an ASP MVC site.
The site has a controller method for POST requests that passes to it an object from my Model.
I have access to those same classes in my desktop application and was hoping that I would be able to create an object of the same type, then create an HTTP POST request, attach the object and send it to the site.
I found that the POST data is just key-value pairs that match the properties of the class so Property1=value1&Property2=value2 worked, however I'm stumped as to how to represent a list.
Is there some easy way to serialise the object into an HTTP request or would I have to make multiple requests for each item in the list?
You can use WebClient to implement such behavior
string url = "your POST action url here";
NameValueCollection formData = new NameValueCollection();
formData["name"] = "John";
// add more form field / values here
WebClient webClient = new WebClient();
byte[] responseBytes = webClient.UploadValues(url, "POST", formData);
string response = Encoding.UTF8.GetString(responseBytes);
However, this is not good practice. This kind of communication should be implemented with web services - if your application is designes well (for example you have service layer/repository), there is nothing easier than expose simple webservice side by side with MVC frontend.

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.

How to get a variable value in an .asp page inside a .aspx.cs page using Ajax

I have a situation where I'm generating my Connection String in an asp page using a functionality.This functionality I may need to completely do from scratch in .net which is redundancy.To avoid this I want to get the connection string variable from the .asp page to the .net page i.e aspx.cs. Is it possible to do this. A couple of options from google I have been able to get are Server.Execute and sending a Web Request through.net to .asp page and get those values.I wanted to know the latency associated with this methods if it is actually possible.
there is a file getconnstring.asp...classic asp file
in this file I'm constructing connection string like
strACHConnection="Provider=MSDAORA.1;Password=..."
I want to use this variable value in an asp.net website as in a getconnstring.aspx.cs.Is it possible to do using an Ajax request.
Can can get the connection string or any other information from your .asp application by making a WebRequest from your asp.net application to your .asp app.
However, there will be latency issues depending on where the two reside with respect to each other. So I would get the info once and then save it to a file or something and then read it from there the next time.
I'm posting another answer so I can post some code that doesn't get garbled. Below is a Task based version.
var webRequest = WebRequest.Create("http://www.microsoft.com");
webRequest.GetReponseAsync().ContinueWith(t =>
{
if (t.Exception == null)
{
using (var sr = new StreamReader(t.Result.GetResponseStream()))
{
string str = sr.ReadToEnd();
}
}
else
System.Diagnostics.Debug.WriteLine(t.Exception.InnerException.Message);
});
And here is a sync version that's untested but should get you going.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.microsoft.com");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string str = reader.ReadtoEnd();

Categories

Resources