Microsoft.Net.Http vs Microsoft.AspNet.WebApi.Client - json

I need to access REST service from .NET application and it seems it can be done with any of those two packages. It's not clear to me which package is supposed to be used in which scenarios. Can anyone bring more light into this?

The short answer is yes, use Microsoft.AspNet.WebApi.Client.
https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Client/
This package adds support for formatting and content negotiation to
System.Net.Http. It includes support for JSON, XML, and form URL
encoded data.
Microsoft.AspNet.WebApi.Client actually depends on Microsoft.Net.Http, and extends the HttpClient with some more features that you would likely need to talk to a RESTful service such as ASP.NET Web API (e.g. JSON and XML support).
Both packages operate in the System.Net.Http namespace and revolve around the key HttpClient class.
The Microsoft.AspNet.WebApi.Client package contains the System.Net.Http.Formatting.dll assembly, which adds some handy extension methods to HttpClient and HttpContent (and others).
So for example:
using (var client = new HttpClient())
{
var response = await client.GetAsync("http://localhost/foo/api/products/1");
response.EnsureSuccessStatusCode();
var product = await response.Content.ReadAsAsync<ProductInfo>();
}
The ReadAsAsync method is an extension method that Microsoft.AspNet.WebApi.Client adds onto the HttpContent object. This automatically figures out if the response is JSON, XML or form URL encoded (the aforementioned content negotiation), and then uses the corresponding formatter to de-serialize it into your strongly typed model (in this case, ProductInfo).
If you tried to just use Microsoft.Net.Http, the ReadAsAsync method wouldn't be available to you, and you'd only be able to read the content as raw data such as bytes or string, and have to do the serializing / de-serializing yourself.
You also get extension methods to PUT / POST back to the service in JSON or XML without having to do that yourself:
// Save the ProductInfo model back to the API service
await client.PutAsJsonAsync("http://localhost/foo/api/products/1", product);
Key Microsoft.AspNet.WebApi.Client extensions:
https://msdn.microsoft.com/en-US/library/system.net.http.httpclientextensions.aspx
https://msdn.microsoft.com/en-US/library/system.net.http.httpcontentextensions.aspx

Related

Yii2 HttpClient: Access Request instance from Response instance

Using yii2-httpclient, what is the correct way to access the corresponding yii\httpclient\Request instance from the resulting yii\httpclient\Response object?
I am trying to write a custom XML parser which needs to know what URL it is parsing. It does not seem to be possible to access the original Request (through which I could get the URL) from a parser instance (only the Response).
I have considered utilizing yii\httpclient\Client::EVENT_AFTER_SEND to copy the request into a variable, but that would not be thread-safe, so I need a better solution.
If your parser needs to know URL of request to parse response, it is probably not a parser and you're overusing parser API and ParserInterface. I suggest to create some component which will wrap and hide all request-response-parser logic. Then you will be able to implement custom parser and call it manually:
public function get($url) {
$client = new Client();
$response = $client->createRequest()
->setUrl($url)
->send();
return (new MyParser($url, $response))->getContent();
}

Spring RESTful service returning JSON from another service

I have been creating Spring RESTful services for a while and typically I am building my own services so I create domain objects and populate them and the framework takes care of the conversion to JSON.
I have a situation now where I simply need my service to act as a pass through to another system's service that is already RESTful and returns JSON.
URL https://:/service/serviceInfo
Method GET
HTTP Content Type Produces: application/json
I simply want to wrap this call (I will apply some security checks on the service) and pass that JSON returned straight back to my service without mapping it back to Java objects, only to return as JSON to the client. Is there a simple way to do this, with minimal code?
Thanks in advance.
Can you see if this works for you?
#RequestMapping("/child")
public String testMethod(#RequestParam String param) {
return new RestTemplate().exchange("https://api.twitter.com/1/statuses/user_timeline.json", HttpMethod.GET, null, String.class).getBody();
}
You just replace the url for your own. I can also guide you to using the RestTemplate with POST or DELETE requests etc. if you need. Also adding parameters or headers if you need. I've used it extensively in some projects.

Swift Generic Function Returning New Object

I am trying to make a generic function that returns objects obtained via a REST API JSON response. I want to provide the type with a generic, have it submit the request/parse the JSON, and return a list of objects of the provided type (such as Item). I have the part of getting the JSON response, but using generics is new for me. Here's a pseudocode of the situation holding me up:
class Model {
func setPropertiesFromJSON(data: NSData) {
// Lookup property names of object and set from JSON fields.
}
}
class Item : Model {
var a
var b
}
class RestEndpoint {
func getModels<T>() -> [T] {
let data: NSData = ... // Submit GET request and receive JSON data.
var models = [T]()
for objectData in data {
// How to create newobj as T (subtype of Model), set its properties,
// and add it to models array?
// let newobj: T as? TrackminiModel = T()
// newobj.setPropertiesFromJSON(objectData)
// models.append(newobj)
}
return models
}
}
let restEndpoint = RestEndPoint()
var items: [Item] = restEndpoint.getModels<Item>()
The commented out code is very incorrect but that is the goal. Any thoughts on how to do this?
From your question it sound like what your are interested in is something that is a fairly common need. The ability to communicate with a backend server using a Restful API. You can continue down the path you seem to be heading an create a lot of code to accomplish this, and this answer will not provide much help in that direction.
However I would like to point you to two open source libraries, ObjectMapper, which I think addresses your question. Here is a brief description of ObjectMapper (from its github page).
ObjectMapper is a framework written in Swift that makes it easy for
you to convert your Model objects (Classes and Structs) to and from
JSON.
The second project is AlamofireObjectMapper which I think in the end might be exactly what you are looking for. Here is a brief description from that projects githup page.
An extension to Alamofire which automatically converts JSON response
data into swift objects using ObjectMapper.
All of this is built on top of Alamofire which handle all the details of communicating with Restful API's.
Again here is a brief description of Alamofire.
Alamofire is an HTTP networking library written in Swift.
Chainable Request / Response methods
URL / JSON / plist Parameter Encoding
Upload File / Data / Stream
Download using Request or Resume data
Authentication with NSURLCredential
HTTP Response Validation
Progress Closure & NSProgress
cURL Debug Output
Comprehensive Unit Test Coverage
Complete Documentation
You might feel like picking up other libraries to accomplish some task is "cheating" you out of an opportunity to learn how to do something yourself, but there are still plenty of challenges in making an app. Some would say not taking advantage of these open source libraries is "undifferentiated heavy lifting"

Other technologies that can perform DTO request response like WCF

I have a WCF service that allows me make a request using an DTO and replies with a DTO for a WPF application. For example I pass a filter object for products which has a few properties for things I want to filter on and a couple of extras for paging, (the server will take care processing the filter object and getting the data) an example is like this.
public async Task<ObservableCollection<ProductListItem>> GetProductList(ProductFilter filter, int startIndex, int pageSize, string sortBy)
I am wondering if there exists any other technologies beside WCF that allow such an operation, From my preliminary research which may be quite off is that WebAPI uses the GET, POST, PUT verbs and routing rules which is quite different.
ServiceStack looks like it might be able to do this I can see on slide 37 at https://servicestack.net/features
it says.
List<Product> productOver2Bucks = client.Get(new FindProducts{PriceGreaterThan = 2})
Which seems pretty close but might still require Rest verbs as it uses a Get().
I don't know it it is FUD or not but I have been reading that soap over WCF is believed by some to be a legacy technology and JSON is the way of the future. So is there a replacement technology that will work with a method signature to the one I have above? That i could call from platforms such as Windows universal applications.
In ServiceStack if you design your Service with the Any method name, e.g
public object Any(Request request)
{
return new Response { ... };
}
This will allow calling this Service from Any HTTP Verb on any Format or endpoint (e.g. JSON, XML, MsgPack, Protocol Buffers, SOAP, Message Queue's, etc).
Also you don't need to define any [Route] for your Request DTO's since it will automatically fallback into using the pre-defined Routes when none are available.
public class Request : IReturn<Response> { ... }
public class Response { }
So with the above Service you can use ServiceStack .NET ServiceClients to call the API's using any verb, e.g:
var client = new JsonServiceClient(baseUrl);
Response response = client.Get(new Request { ... });
Response response = client.Post(new Request { ... });
When preferred you can also use the async API's, e.g:
var response = await client.GetAsync(new Request { ... });
var response = await client.PostAsync(new Request { ... });
Which if you don't care for using verbs you can use the generic Send API, e.g:
Response response = client.Send(new Request { ... });
Which just uses POST underneath, although it's highly recommended to use Get for "read only" queries as it will allow the Services HTTP responses to be cached by any intermediate HTTP Middleware or proxies.
Add ServiceStack Reference
Also if you're coming from WCF you'll also enjoy ServiceStack's, Add ServiceStack Reference which provides a number of advantages over WCF's Add Service Reference feature but still provides the same utility in being able to generate a typed API from a remote url for:
C# Add Reference
F# Add Reference
VB.NET Add Reference
TypeScript Add Reference
With more languages to follow.
Advantages over SOAP
Whilst ServiceStack still enables WSDL's, XSD's for your Services so they can be called from SOAP 1.1/1.2 endpoints for legacy compatible reasons - there are a number of reasons why using clean HTTP and JSON/XML API's are preferred.

WCF service to return iCal

How do I get my service written with WCF to return an iCal? The examples I see use either xml or json as the way to format the response. What is the best way to return other types of response bodies?
Something like this:
[WebGet(UriTemplate="{id}.ics")]
[OperationContract]
Stream GetCalendar(int id)
{
WebOperationContext.Current.OutgoingResponse.ContentType="text/calendar";
//Now just return the appropriate data in iCal format in the Stream...
}
So now you can do an HTTP GET to e.g. yourService.svc/123.ics and get an iCal back.
The reason this works is that "Stream" is special-cased in WCF REST (used for non-XML, non-JSON responses).
Remember that you have to use both the WebHttpBinding and WebHttp behavior for this to work.
The simplest solution would be to return the iCal representation in XML or JSON format (your pick) as a simple string from your WCF call:
[ServiceContract]
interface IMyCalService
{
[OperationContract]
string GetiCal(.......);
}
and then go on and handle it further on the client, once you've received the string containing the iCal XML (or JSON). This can be done with standard WCF using SOAP.
Other ways to do it might be to use a WCF REST service which returns a response in iCal format when you hit a particular URL - this would require installing the WCF Rest Starter Kit for the time being (in .NET 3.0/3.5). I'm not intimately familiar with the iCal format, but I'm sure one way or another, you'll be able to construct the necessary XML format to satisfy the iCal requirements.
Marc