What's the best way to call a REST API from MVC4 - asp.net-mvc

MVC4 provides a very simple way to return serialized objects from HTTP requests. What's the best way to call a REST or other JSON/XML API from an MVC4 application? I could construct an HTTP request, send it, then deserialize the result, but I was hoping for something simpler. My application runs on multiple servers and one server needs to talk to the other via the web API. So, both servers have the same class definitions. I'm hoping there is some fairly transparent way to get MVC to deserialize as cleanly as it serializes content.

This is an example of how I call an MVC4 WebAPI from a WPF application. You should be able to adjust according to your needs. Hope this helps...
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://192.200.1.3:9594/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("EmployeeTest/TestApi");
if (response.IsSuccessStatusCode) {
var employee = response.Content.ReadAsAsync<Employee>().Result;
tbName.Text = employee.Name;
tbPhone.Text = employee.Phone;
}

Related

Alternative to using Webclient to get HTML output

A product I've inherited is using WebClient to read HTML from a MVC based site. Each page is a different type of e-mail, so in order to compose and send an e-mail they use WebClient to request a URL and download the string.
var outputHtml = string.Empty;
using (WebClient client = new WebClient())
{
client.Encoding = Encoding.UTF8;
outputHtml = client.DownloadString(emailURL);
}
return outputHtml;
Is there a way to remove the need to host this email based site but retain most of this code. I guess what I need to do is pass my request to the controller and retrieve the output after the razor engine has passed the view model through the cshtml page.
Is that possible?
There are many ways you could render a Razor view to a string. One possibility is to use RazorEngine. Another possibility is to use some specifically designed framework for this purpose such as Postal.

How to get the raw binary content in Grails controller

after many days of search and many unsuccessful tries, I hope that the community knows a way to achieve my task:
I want to use grails as a kind of a proxy to my solr backend. By this, I want to ensure that only authorized requests are handled by solr. Grails checks the provided collection and the requested action and validated the request with predefined user based rules. Therefore, I extended my grails URL mapping to
"/documents/$collection/$query" {
controller = "documents"
action = action = [GET: "proxy_get", POST: "proxy_post"]
}
The proxy_get method works fine even when the client is using solrJ. All I have to to is to forward the URL request to solr and to reply with the solr response.
However, in the proxy_post method, I need to get the raw body data of the request to forward it to solr. SolrJ is using javabin for that and I was not able so far to get the raw binary request. The most promising approach was this:
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(solrUrl);
InputStream requestStream = request.getInputStream();
ContentType contentType = ContentType.create(request.getContentType());
httpPost.setEntity(new ByteArrayEntity(IOUtils.toByteArray(requestStream), contentType));
httpPost.setHeader("Content-Type", request.getContentType())
HttpResponse solrResponse = httpClient.execute(httpPost);
However, the transferred content is empty in case of javabin (e.g. when I add a document using solrJ).
So my question is, whether there is any possibility to get to the raw binary post content so that I can forward the request to solr.
Mathias
try using Groovy HttpBuilder. It has a powerful low-level API, while providing groovyness

How to extend (System.Net.Http)HttpClient Http Verbs?

Is it possible to add a new arbitrary HTTP Verb to System.Net.Http HttpClient?
Case in question:
I developed a WebAPI for an MVC-based document managment system.
The API supports:
GET - fetch a document, POST - create a new document, PUT - update a document, DELETE - delete a document.
I also need to support: PRINT - print a document, EMAIL - email a document.
It is easy to add the VERBs on the MVC side. Add the [AcceptVerbs("PRINT")] decoration and you are done.
BUT I need to instruct the developers using my API how to access it. Since they are using HttpClient my problem is: How will these VERBs be consumed using the HttpClient?
Dror
Those are not standard HTTP verbs. I would not recommend you using them. If you insist on using them you could use the SendAsync method which allows you to specify the HTTP verb you want to use:
using (var client = new HttpClient())
{
var request = new HttpRequestMessage(new HttpMethod("PRINT"), "http://example.com");
var result = client.SendAsync(request);
}

HMAC with ASP.NET WebAPI using Cuong's Solution

I spent a some time today looking through various HMAC implementations in C# for an upcoming WebAPI project. I wanted to start out with some existing code just to see it all work and understand it better before I either wrote it from scratch or modified it for my needs.
There are a bunch of great articles and posts both here and on the web. However, I have gotten to the point that I need some pointers and would greatly appreciate some insight.
I started with Cuong's post here: How to secure an ASP.NET Web API.
I knew I would have to expand upon it since I wanted to support both json and formencoded data. My test client is also written in C# using HttpClient and I spun up an empty WebAPI project and am using the ValuesController.
Below are my observations and questions:
POSTing: In order to get Cuong's code to work (validate successfully), my POST needs to include the parameters in the URL, however in order to get the values to my controller, I need to include them in the body. Is this normal for this type of authentication? In this particular instance, the message I am hashing is http://:10300/api/values?param1=value1&param2=value2. Now I can parse the query string manually to get them, however in order to get the value to my controller through binding, I must also:
var dict = new Dictionary<string, string>
{
{"param1", "value1"},
{"param2", "value2"}
};
var content = new FormUrlEncodedContent(dict);
var response = await httpClient.PostAsync(httpClient.BaseAddress, content);
Otherwise my parameter is always null in the post action of the ValuesController.
I am planning on expanding the code to include a nonce. Between the combination of a nonce, a timestamp and the verb, is that enough for a secure hash? Is there really a need to also hash the message?
I tried (very unsuccessfully) to extend the code to support json as well as form encoded data and I must be missing something obvious.
Cuong is using the Authentication and Timestamp headers instead of putting the signature and timestamp in the query string. Is there a benefit to one method over the other? The majority of articles I have read have them in the query string itself.
The code looks great and I am a little out of my element here. I might be safer (saner?) just writing it from scratch to appreciate the nuances of it. That said, if anyone can lend some insight into what I am seeing that would be great.
At the end of the day, I want to be able to use the built in authorization mechinism of the WebAPI framework to simply attribute the methods/controllers, be able to accept form encoded and json data and reasonably model bind for complex types.
* Update *
I have done some more work today and below is the code from my nUnit PostTest. I figured out how to get the values through without both including them in the body and the query string (code below).
[Test]
public async void PostTest()
{
using (var httpClient = new HttpClient())
{
var payload = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"key1", "value1"},
{"key2", "value2"}
});
var now = DateTime.UtcNow.ToString("U");
httpClient.BaseAddress = new Uri(string.Format("http://ipv4.fiddler:10300/api/values"));
httpClient.DefaultRequestHeaders.Add("Timestamp", now);
httpClient.DefaultRequestHeaders.Add("Authentication", string.Format("test:{0}", BuildPostMessage(now, httpClient.BaseAddress, await payload.ReadAsStringAsync())));
var response = await httpClient.PostAsync(httpClient.BaseAddress, payload);
await response.Content.ReadAsStringAsync();
Assert.AreEqual(true, response.IsSuccessStatusCode);
}
}
I also figured out the model binding portion of it. There is a great article here: http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data that explains how POST works and I was able to get it to work with both a model of my own design as well as with the FormDataCollection object.
Now I am left wondering whether or not it is worth adding json encoded messages or if standardizing on FormUrlEncoding is the way to go. Also, are client nounce's enough or should I implement a server side nounce? Does a server side nounce double all of the calls to the service (first one throws a 401, second one includes the payload with the nounce?

Silverlight, Grids, MVC, HTTP Post

I'm trying to create an editable grid using Asp.Net MVC 2 and Silverlight (specifically a grid that displays info from a db and allows users to update that info).
So far I've managed to put a silverlight grid on an a view, using this technique
However I have no way of getting the updated data from the silver light grid. Is there anyway to get these values posted back to my controller?
I'm pretty new to Asp.Net MVC and I'm really only getting started using silverlight.
Thanks for any help!
The first thing you need to do is serialize back to JSON:-
(Assumption you use ToArray() on a ObservableCollection of MyItem objects)
public string SerialiseToJSON(MyItem[] myItems)
{
//Create a stream to serialize the object to.
MemoryStream ms = new MemoryStream();
// Serializer the User object to the stream.
DataContractJsonSerializer ser = new DataContractJsonSerializer(MyItem[]);
ser.WriteObject(ms, myItemsArray);
byte[] json = ms.ToArray();
ms.Close();
return Encoding.UTF8.GetString(json, 0, json.Length);
}
Now you can use the WebClient class to send the JSON string back.
WebClient web = new WebClient();
web.UploadStringAsync(new Uri("/yourcontroller/jsonReceiver", UriKind.Relative));
Now I don't know MVC all that well but I believe you can annotate a controller action method so that it can accept a http POST of JSON data and it'll do the deserialisation for you.

Resources