I am developing a website along with an API to serve it data and have noticed that my current process involves repeated serialization and deserialization of the same data when an API call is made. I was wondering if there is a better way to go about things. Both the website and API are written in C# using ASP.Net Core 2.0.
My current process is as follows:
1) End user loads website page
2) AJAX call is made from client side JavaScript, calling a C# function in the website.
3) The C# website function calls the API (using a Swagger generated client).
4) The API serializes data and returns it to website as JSON.
5) The Swagger client in the web site deserializes the data back to a POCO class.
6) The Website C# function serializes the data back to JSON to return it to AJAX function.
7) Something is done with the JSON data in the client - inevitably after first parsing the JSON.
Example Code:
AJAX call:
var xhr = new XMLHttpRequest();
xhr.open('get', "/GetData", true);
xhr.onload = function () {
var data = JSON.parse(xhr.responseText);
doSomething(data);
}.bind(this);
xhr.send();
Website method:
[Route("/GetData")]
public async Task<IActionResult> GetData()
{
var data = await ApiClient.ApiDataGetAsync();
return Json(data);
}
API Method:
[HttpGet]
public Dictionary<int, string> GetData()
{
return _logic.GetData();
}
As the above shows the data is serialized to JSON by the API before being deserialized to a POCO by the Swagger client, then serialized back to JSON in the website to be processed client side.
I realize I could simplify this by calling the API directly from the AJAX rather than going through the website but I would rather avoid this for a number of reasons:
1) It would tightly couple the API to the front end of the website, at the moment I have the option of implementing an interface layer in the site to simplify things if the API needs to be replaced in the future.
2) It would reduce my control over who can access the API - at the moment it is locked down by IP address.
Is there a way I can improve this process so the data doesn't have to be serialized twice whilst retaining the Swagger client?
What problem are you actually trying to solve? The time taken to serialize/deserialize the json is tiny compared to the time taken for networked i/o.
At this point I would say you are trying to optimise something without knowing whether it will improve application performance or reduce cost, which is generally considered a waste of time.
Well, you can forgo the client and simply make your action a proxy using HttpClient to fetch from the API.
The client is intended to actually give you C# objects to work with, so it serializes/deserializes the request/response to make it easier for you to work with the API. That's sort of the whole point. What you're saying is that you don't actually want this, so simply drop the client.
Instead, you can make the request directly to your API from the action, using HttpClient, and then simply return the the response from the HttpClient call. Since the API returns JSON and you need JSON, no further processing needs to be done.
Related
Thanks for your time , I have a simple question, in an asp.net MVC application, inside controllers is it possible that along with some methods returning View (ActionMethods) other could act as (or return) Json as a Web API (could be called from external apps).
Just trying to do a proper separations, hence trying to understand.
Thanks much.
You can make an action function like an API. Try something like the this.
// Controller/Action
[HttpGet]
public ActionResult IAmSpecial()
{
if (Request.IsAjaxRequest())
{
string[] objects = new string[] { "Foo", "Bar" };
return Json(objects);
}
return View();
}
This will return the IAmSpecial view if you browse to {domain}/{Controller}/IAmSpecial while it will return a JSON result if you use an AJAX Http Get request on the same url.
while it is possible to have controller methods which return Json data only, there are a number of considerations when you want to expose that data outside of the UI app.
Since you have an MVC app, I expect you have users and a way to login. Your controllers would more than likely be secured in some way, which works for the internal users of the application. Now you want to add one method which effectively becomes an API, available outside of the application and calls to it will have to be authenticated somehow.
What I would suggest is to split this up. You can create a separate project, which is a WebAPI one, in the same solution. The code which prepares the data can live in a class library you can then reference in both your MVC and WebAPI projects.
Your MVC app can call it and then return a view with that data, the WebAPI calls it and simply returns the data. You can now decide on a way of securing your API, maybe using Identity Server or some other way and you can keep adding things to it, without affecting the UI layer.
Your second option is to make the MVC app use the API when it needs to retrieve data, so both your public clients and UI use the same thing.
Whichever option you use, the idea is to not duplicate anything and at the same time provide the security layers you need.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I need to retrieve the content of a JSON feed. I want to use HttpClient for downloading the content. For this purpose I've created a WEB API controller with a Get method which consumes the external API with HttpClient and then returns a List of deserialized content:
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("externalAPI");
MediaTypeWithQualityHeaderValue contentType =
new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
HttpResponseMessage response = await client.GetAsync(client.BaseAddress);
string content = await response.Content.ReadAsStringAsync();
List<MyClass> data = JsonConvert.DeserializeObject<List<MyClass>>(content);
return data;
}
Now I'm going to show this list in client side using Angular and I know how should I do these steps but my question is why should I use a WEB API to consume another external API since I can simply use Angular HttpClient to consume that external API? Is using this WEB API to consume an external API and then return a List to Angular considered as best practices? If no, what is the best way, if I have to use MVC for this purpose?
In my project I consumed external API (which retuns json data), via webapi.
I did it because than my Angular project only have to maintain reference to webapi only i.e. just one url only. and another case in my project is external api url change in Dev,UAT and prod evironment, so i dont want to maintain in my angular project.
So I did it for two reason
Dont want to maintain reference of external api (i.e. URL of external api), and I get only one contact for getting data in my project which is my webapi
URL of external API change in Dev, UAT and PRod so I dont want to maintain that information in my Angular project.
That makes my code of angular more maintainable as if someone else look my code he/she get info that webapi is only location where they should look for ,from where data is coming
Imagine scenario where you are geting data from more then one external API, in that case you have to maintain reference to all API in your Angualr project. So Better to Follow FACADE design pattern, and keep only one point (which WebAPI in this case) which connect with all external api and returns data.
For getting data every 10 min you need to make use of RxJs
var timer$ = Rx.Observable.interval(1000) // 1000 = 1 second
timer$
.subscribe((v)=> this.Service.CalltoExtnerlAPIToGetdata()
.subscribe(data=> this.values = data));
please do unsubscribe from Rxjs Timer when you are not going to consume it to avoid memory leak.. http://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables
Let's say this external API is in the domain abc.com and your app is in the yourapp.com. If abc.com doesn't allow CORS (cross origin request), you won't be able to retrieve data from your angular app that is running in yourapp.com, so buildind a "middleware" in a server might solve this problem.
Anyway, it's not mandatory to build this middleware. If the target API allows CORS, there is no need to do this, and you can write the layer that requests data in your angular app.
The main reason lies within the same origin policy where a given origin, e.g. script executed by your browser, is only allowed to perform requests to an origin which is in the same domain (schema, host and port).
Reasons are mainly security related and have been extensively discussed in this StackExchange question.
A typical approach in MVC implementations to comply to this policy is to perform the HTTP request to your WebAPI using server side code, i.e. from the Controller using HttpClient. Then the Javascript from your View would simply call your Controller's method to retrieve the result.
As a side note, this approach has also the benefit of let you handle any serialization work in your Controller before presenting the data back to the View.
I've searched some time, looking for easy way to connect with some other sites WebAPI. There are some solutions, but they are made in very complicated way.
What I want to do:
Connect with server using URL adress
Provide login and password to get some data
Get data as JSON/XML
Save this data in an "easy-to-read" way. I mean: save it to C# variable which could be easy to modify.
Currently, API that I want to work with is Bing Search, but I'm looking for some universal way. I found an example, but it doesn't work for me and in my app I can't use this class: "DataServiceQuery" because it doesn't exsist.
How do you usually do it? Do you have your favourite solutions? Are there some universal ways or it depends on type of API that you work with?
I'm currently working on .NET MVC app (in case it could make any difference)
From server side
You can use that like below.
// Create an HttpClient instance
HttpClient client = new HttpClient();
// Send a request asynchronously continue when complete
client.GetAsync(_address).ContinueWith(
(requestTask) =>
{
// Get HTTP response from completed task.
HttpResponseMessage response = requestTask.Result;
// Check that response was successful or throw exception
response.EnsureSuccessStatusCode();
// Read response asynchronously as JsonValue
response.Content.ReadAsAsync<JsonArray>().ContinueWith(
(readTask) =>
{
var result = readTask.Result
//Do something with the result
});
});
You can see example on following link.
https://code.msdn.microsoft.com/Introduction-to-HttpClient-4a2d9cee
For JavaScirpt:
You could use jQuery and WebAPI both together to do your stuff.
There are few steps to it.
Call web api with Ajax jquery call.
Get reponse in JSON
Write javascript code to manipulate that response and do your stuff.
This is the easiest way.
See following link for reference:
http://www.codeproject.com/Articles/424461/Implementing-Consuming-ASP-NET-WEB-API-from-JQuery
It entirely depends on the type of API you want to use. From a .Net point of view, there could be .Net 2 Web Services, WCF Services and Web API Services.
Web APIs today are following the REST standard and RMM. Some APIs need API Keys provided as url parameters, others require you to put in request's header. Even some more robust APIs, use authentication schemes such as OAuth 2. And some companies have devised their own standards and conventions.
So, the short answer is that there is no universal way. The long answer comes from documentation of each API and differs from one to another.
I have recently returned to .net programming after a 7 year break.
I need to learn how to write a project within an existing open source asp.net mvc 5 ecommerce solution to receive posted json strings from a remote server running php with cURL, send acknowledgement responses, create my own json strings to post back to the remote server and receive acknowledgement responses. This must all be done with server side code, with no client side component whatsoever.
Serializing and deserializing json is not the issue, its using the correct kind of pages or services to send and receive json on the server without any client component, and using http objects directly. I have no experience or knowledge of creating this kind of project.
This is my question: I have had a look at a couple of tutorials about using .ashx and httpClient and httpContext but found them a little confusing. I would like to find a comprehensive guide about how to use json to communicate server to server with realistic examples. Is there one available?
Sounds like a perfect use case for WebApi. It is made specifically to work with JSON (or XML) requests and should work fine with requests issued by other scripts (not browsers).
There are plenty of tutorials available. Here is the official introduction tutorial.
What I often do to create JSON in C# is make an object/class which I serialize to JSON.
My controller has an function:
public JsonResult FunctionName()
{
var json = new { x1 = 10, y1 = "Hello" };
return Json(json);
}
You can call that function with PHP.
I've built a simple C# app (.Net 4.0 + WPF) which can send and receive JSON messages via TCP sockets.
As a next step, it should be possible that JavaScript apps on websites and PHP scripts can send and receive JSON messages to/from my app. Is that possible?
Since JS/PHP will use stateless HTTP connections, how should a request to my app work, for example, should the JS/PHP apps send a JSON message to my app and my app response (HTTP response) with a JSON message? Is that even possible? And should I use GET or POST method to send the JSON messages to/from my app?
Hope my questions do not cause too much confusion ;-) I but I appreciate every tip, clarification or feedback you can give me.
Mike
You can accomplish this via a .NET web service using special JSON directives on the web method, e.g.
[ScriptMethod(UseHttpGet = true, ResponseFormat=ResponseFormat.Json)]
public string DoSomething(string param1, int param2)
{
// Do Something
}
When the ResponseFormat.Json property is specified, the data returned will be serialized into the appropriate JSON format. Also note, in order to recieve a true JSON response, you'll need to set your content-type to "application/json" from the requesting application. Otherwise, the method will attempt to wrap the response in XML.
Also, I am enabling a HttpGet on this method so that you can post via a query string to the method, e.g.
http://www.example.com/service.asmx?param1='Hello'¶m2=1;