Data streaming with restsharp and WebAPI - c#

My aim is to GET and POST files to SP Online.
I have written a WEB API with the two methods. These methods use CSOM to interact with SP Online.
The GET returns the response Ok(array of bytes) to the client and the POST gets the entire file to upload in the request body and performs the upload to Sharepoint Online in chunks.
I've been told that i should use streaming techniques, since the context is an enterprise application with many simultaneous requests. So the GET method should return a stream to the client and the client should send the request as a stream to the POST.
In the client side i'm forced to use the RestSharp library.
So:
1) How to use RestSharp to deal with streams?
2) How can the WebAPI return a stream?
3) Along with the file i send a lot of metadata. How can i upload the file in streaming mode and send the metadata only once?
Client side, the get requires an array of bytes and the post sends an array of bytes along with metadata.
Online i've found too many techniques. Is there a standard one?

There a very basic example. It does not covers all of your questions but this is a point to start.
Client with RestSharp:
(I did small ASP.NET Core 2.0 console Application). Add the following code to your Programm.cs)
using System;
using System.IO;
using RestSharp;
namespace RestSharpClient
{
class Program
{
public const string baseUrl = "http://localhost:58610/api/values"; // <-- Change URL to yours!
static void Main(string[] args)
{
Console.ReadKey();
string tempFile = Path.GetTempFileName();
using (var writer = File.OpenWrite(tempFile))
{
var client = new RestClient(baseUrl);
var request = new RestRequest();
request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer);
var response = client.DownloadData(request);
}
Console.ReadKey();
}
}
}
Server
My controlller:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers;
namespace Server.Controllers { [Route("api/[controller]")]
public class ValuesController: Controller {
// GET api/values
[HttpGet]
public FileStreamResult GetTest() {
var stream = new MemoryStream(Encoding.ASCII.GetBytes("Hello World"));
return new FileStreamResult(stream, new MediaTypeHeaderValue("text/plain")) {
FileDownloadName = "test.txt"
};
}
}
}
Important: Enable CORS. For that add the following line to your Startup.cs before services.AddMvc();
services.AddCors();
How to add metadata:
WebAPI method that takes a file upload and additional arguments

Related

Returning XML From C# WebAPI (Formatting Issues)

I'm calling an XML API from my C# Web API.
The response from the XML API should be returned to the end user initiating the request.
Currently the formatting appears to be broken. When you call the XML API directly it returns as expected, however, my C# API returns the response as just one 'lump' string.
Do I need to deserialize this into an object to get it to a better output?
using (WebClient wc = new WebClient())
{
wc.BaseAddress = $"https://{urlBase}";
wc.Headers.Add(AuthorizationHeader, authorization);
result = wc.DownloadString(urlPath);
}
return result;
When I look at the calls that the application makes to the XMLAPI using Fiddler I can see that the response from the XMLAPI has the correct formatting applied to it. However, when this is returned from my C# API the formatting appears to be broken.
In the Application_Start I've forced the application to use XMLMediaTypeFormatter over JSON, this does not appear to have worked:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new System.Net.Http.Formatting.XmlMediaTypeFormatter());
Try following which should return a list of XElement. I can see from the black out code if your results just have innertext or you have attributes as well
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string response = "";
XDocument doc = XDocument.Parse(response);
XElement applist = doc.Root;
XNamespace ns = applist.GetDefaultNamespace();
List<XElement> apps = doc.Descendants(ns + "app").ToList();
}
}
}

Microsoft Linguistic Analysis API example HttpUtility does not exist

I'm trying to check Microsoft Linguistic Analysis API, basic example, so I have subscribed and addad my Key 1 in Ocp-Apim-Subscription-Key and Key 2 into the subscription key here client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");.
Then I add Newtonsoft.Json with Manage NuGet Packages into the References of Application, even it is not listed in using of particular example using Newtonsoft.Json; using bNewtonsoft.Json.Serialization; not sure, I'm new with this tool.
I'm trying to check this example Linguistics API for C# to get some natural language processing results for text analysis mainly of Verb and Noun values according to this example results So I'm not sure if I'm on the right direction with this example, or possible I've missed something to install, maybe I need some additions. I found this Analyze Method not sure how and if I have to use it for this particular goal.
But seems like something is wrong with var queryString = HttpUtility.ParseQueryString(string.Empty); and HttpUtility does not exist.
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;
namespace CSHttpClientSample
{
static class Program
{
static void Main()
{
MakeRequest();
Console.WriteLine("Hit ENTER to exit...");
Console.ReadLine();
}
static async void MakeRequest()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
var uri = "https://westus.api.cognitive.microsoft.com/linguistics/v1.0/analyze?" + queryString;
HttpResponseMessage response;
// Request body
byte[] byteData = Encoding.UTF8.GetBytes("{body}");
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("< your content type, i.e. application/json >");
response = await client.PostAsync(uri, content);
}
}
}
}
You can create a new writeable instance of HttpValueCollection by calling System.Web.HttpUtility.ParseQueryString(string.Empty), and then use it as any NameValueCollection, like this:
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
Try adding a reference to System.Web, and possibly to System.Runtime.Serialization.

How to get data from API request?

I'm pretty new to C# and this is my first time getting data from an api. I was wondering how do I get or call the data collected in this api request (MakeRequest). Preferably assign the data to a public string. The data from the api request is in json format.
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;
namespace CSHttpClientSample
{
public partial class Form1 : Form
{
public async void MakeRequest()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
// Request parameters
queryString["seasonId"] = "{string}";
var uri = "https://www.haloapi.com/stats/{title}/servicerecords/arena?players={players}&" + queryString;
var response = await client.GetAsync(uri);
}
}
}
So if the call succeeded, you should have your JSON string returned in the response variable you assign in the last line.
Use your debugger and inspect that variable. If you look at the MSDN doc for your GetAsync() method (Link), you can easily find out that the variable is of the type HttpResponseMessage. This class has an own page here telling you that there's a property Content.
This is your JSON string, now might come the part where you have to do some deserializing. Have fun.

How to receive the data via HTTP in the web service of ASP.NET?

Our team is developing an application that requires sending data from Android app to ASP.NET server via HTTP protocol and I'm in charge of the server part. I have decided to receive the data in a web service, but I don't know the specific way to do it. How do I write the web method in the asmx file to receive the data?
Since ASMX isn't really supported anymore and you want to keep it simple, write a generic handler (.ashx).
<%# WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
using System.Net;
public class Handler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
//retrieve your data from context.Request. Depending on how you choose to send the data from Android, the data may be in context.Request.QueryString or context.Request.Form or context.Request.Files. Commonly, data is sent back and forth as JSON or XML in the body. See my helper method below for retriving it
//it's a good idea to let the client know we processed their request successfully
context.Resonse.StatusCode = HttpStatusCode.OK;
context.Response.ContentType = "text/plain";
context.Response.Write("Success"); //this line is redundant because of the status code, but I wanted to show you how to write data to the response
}
public bool IsReusable { get { return false; } }
}
If you want to get string data from the request body, this helper method should be handy, borrowed from here.
private string GetDocumentContents(HttpRequestBase Request)
{
string documentContents;
using (Stream receiveStream = Request.InputStream)
{
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
documentContents = readStream.ReadToEnd();
}
}
return documentContents;
}
If you want to get fancier, look into Web API or WCF.

How do I access the content of an API response?

I've tried implementing the simplest case of this with a call to Mandrill's API using the method "ping." The response should be pong. Using a valid key, the response seems to work. However, I am having trouble accessing the content of the response.
The code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
namespace MandrillAPI
{
class Program
{
static void Main(string[] args)
{
string ping = "https://mandrillapp.com/api/1.0/users/ping.json";
string key = "?key=123";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(ping);
HttpResponseMessage response = client.GetAsync(key).Result;
Console.WriteLine(response.ToString());
Console.Read();
}
}
}
How do I unpack the response from the call? Ultimately, I need to harvest emails from the server using the API, so I'll need to somehow preserve the structure of the json objects so I can access the details of the email.
If you just want to read the response as a string:
string content = response.Content.ReadAsStringAsync().Result
If you want to deserialize to some class (in this case the type MyClass):
MyClass myClass = JsonConvert.DeserializeObject<MyClass>(response.Content.ReadAsStringAsync().Result)
I would use something like JSON.Net to serialize it to a C# object that you can then use.

Categories

Resources