WebApi read exsisting JSON file - C# - javascript

I am trying to create a webapi that reads an exsisting JSON file and then returns it as json object so i can use Javascript to populate the data as HTML to this site. http://pptlbhweb.azurewebsites.net/
The JSON file gets updated as i have a temperaturelogger that logs the events to an eventhub - Streamanalytics - saves as JSON in blob storage (Azure)
Here is the JSON file: https://pptlbhstorage.blob.core.windows.net/temperature/0_7622a22009224c78a46c0b2bc0a3fd82_1.json
If you look on the JSON file it needs to append "]" at the end (This is what i think) in this way i can get a valid JSON object that the WebApi returns.
I have already created a WebApi so i can use URL to get data. http://pptlbhwebapi.azurewebsites.net/api/test
Something similar for getting temperature would be for example:
http://pptlbhwebapi.azurewebsites.net/api/temperature
The fix:
Add this to your api controller:
[System.Web.Http.Route("api/readandreturnjson")]
[System.Web.Http.HttpGet]
public async Task<IHttpActionResult> ReadAndReturnJsonAsync()
{
// object to return through the API (it'll be serialized by WebAPI)
object obj = null;
// WebClient used to download the JSON file
using (var wc = new WebClient())
{
var url =
"https://pptlbhstorage.blob.core.windows.net/temperature/0_7622a22009224c78a46c0b2bc0a3fd82_1.json";
// Used to hold and add a ']' to the downloaded JSON
StringBuilder builder = new StringBuilder();
builder.Append(await wc.DownloadStringTaskAsync(url));
builder.Append("]");
// Deserialize the now valid JSON into obj
obj = JsonConvert.DeserializeObject(builder.ToString());
}
// return the json with 200 Http status.
return Ok(obj);
}
In Global.assax:
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configu‌​ration.Formatters.XmlFormatter);

You could do this:
[System.Web.Http.Route("api/readandreturnjson")]
[System.Web.Http.HttpGet]
public async Task<IHttpActionResult> ReadAndReturnJsonAsync()
{
// object to return through the API (it'll be serialized by WebAPI)
object obj = null;
// WebClient used to download the JSON file
using (var wc = new WebClient())
{
var url =
"https://pptlbhstorage.blob.core.windows.net/temperature/0_7622a22009224c78a46c0b2bc0a3fd82_1.json";
// Used to hold and add a ']' to the downloaded JSON
StringBuilder builder = new StringBuilder();
builder.Append(await wc.DownloadStringTaskAsync(url));
builder.Append("]");
// Deserialize the now valid JSON into obj
obj = JsonConvert.DeserializeObject(builder.ToString());
}
// return the json with 200 Http status.
return Ok(obj);
}

Related

How to use array string in jQuery ajax call?

By using jQuery, I am trying to save my string array in backend and following is my approach.
1.Using jQuery ajax sending array.
var tagTexts = $(ul li.select2-selection__choice")
.toArray()
.map(function(i){
return i.innerText;
});
tagTexts = tagTexts.join(',');
$.ajax({
type: 'POST' ,
url: '/tag/tagList',
dataType: 'json',
data: {
tagTexts: tagTexts
},
error: function(err) {
console.log(err);
},
success: function(response) {
//Process Response
}
});
2.In backend it is retrieved as follows:
#ResponseBody
#RequestMapping(value = "/tag/tagList", method = RequestMethod.POST)
public String saveTagList(HttpServletRequest request,
#RequestParam(value = "tagTexts", required = false)List<String>tagTexts) {
System.out.println(tagTexts);
String response = tagService.saveTags(tagTexts);
return response;
}
a) Using array join method
Following is the string array captured:
["Drone", "Richard Feynman, PHD", "Yatch"]
After using array join method this gets changed as follows:
Drone,Richard Feynman, PHD,Yatch
In java execution (backend) this gets displayed as follows:
[Drone, Richard Feynman, PHD, Yatch]
b) Using JSON.stringify method
After using JSON.stringify method, the captured array gets displayed as follows:
["Drone", "Richard feynman, PHD", "Yatch"]
This looks fine at js level but this entire line is considered as a string and it is displayed at the backend as follows:
[["Drone", "Richard feynman, PHD", "Yatch"]].
I am expecting my code to work as follows:
Comma character in raw data element captured should not split.
The entire array should not appear as a string in the backend.
Is there any better way to achieve this??
You can create a custom request object like this:
public class TagListRequest {
private List<String> tagTexts;
// getter and setter
}
You now can use this with #RequestBody in your request mapping:
#ResponseBody
#RequestMapping(value = "/tag/tagList", method = RequestMethod.POST)
public String saveTagList(#RequestBody TagListRequest request) {
System.out.println(request.getTagTexts());
String response = tagService.saveTags(request.getTagTexts());
return response;
}
Spring internally maps the JSON body of your request to the TagListRequest object using Jackson.
With this solution you do not need to parse the data manually using a separator.
Your javascript with JSON.stringify is correct solution. You just need to parse the JSON in java backend. For example,
import org.json.simple.JSONObject;
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(tagTexts);
See How to convert jsonString to JSONObject in Java for alternative ways how to parse JSON in java.

Pass JSON from SQL Server to D3 Javascript

I'm building an ASP.NET using C#, Visual Studio, SQL Server, D3.JS.
I have values in a SQL Server that I'm getting from the database and the results are:
[
{"AMOUNT":1.000000000000000e+002},{"AMOUNT":1.000000000000000e+003},
{"AMOUNT":1.000000000000000e+004},{"AMOUNT":5.000000000000000e+003}, {"AMOUNT":2.000000000000000e+003},{"AMOUNT":1.000000000000000e+003},
{"AMOUNT":5.000000000000000e+003},{"AMOUNT":3.000000000000000e+003},{"AMOUNT":8.000000000000000e+003},{"AMOUNT":1.200000000000000e+004},
{"AMOUNT":5.000000000000000e+003},{"AMOUNT":1.300000000000000e+004},
{"AMOUNT":1.500000000000000e+004}
]
Okay so my Json output is correct, below is code I'm using to get the json output above:
public string jsonString = "";
public string JasonGet()
{
var queryWithForJson = "SELECT AMOUNT FROM PeopleTable WHERE Bal = 'Acc' FOR JSON AUTO";
var conn = new SqlConnection(#"MyConnectSource!");
var cmd = new SqlCommand(queryWithForJson, conn);
conn.Open();
var jsonResult = new StringBuilder();
var reader = cmd.ExecuteReader();
if (!reader.HasRows)
{
jsonResult.Append("[]");
}
else
{
while (reader.Read())
{
jsonResult.Append(reader.GetValue(0).ToString());
}
}
Label1.Text = jsonResult.ToString();
// jsonString = (new JavaScriptSerializer()).Serialize(jsonResult);
return (new JavaScriptSerializer()).Serialize(jsonResult);
}
And this works fine above I believe since I am putting the results on a label1.Text from a jsonString to see it for myself but the last return line is where I'm part confused because now I wish to pass the JSON result to my D3.JS. Let me show what I'm doing in D3...
<script>
d3.json('<%= JasonGet() %>').then(function (data) {
console.log("Json string: " + data);
});
</script>
Okay so I believe in my C# function that I have the correct results but I think the error is when I'm passing the values to my Javascript. Below is the error code I'm getting:
Uncaught SyntaxError: Unexpected end of JSON input
and
Failed to load resource: the server responded with a status of 400 (Bad Request)
I appreciate any suggestions, sorry if it's not explained properly but to sum it up, we are getting json values from the database from a C# function and then want to pass it into Javascript.

Merge two lists of objects in Java to create a Json with Jackson

I´d like to pass two List of objects retrieved from DB to my view via Ajax request. How could I wrap them in one object to serialize with Jackson and deserialize in view?
ObjectMapper mapper = new ObjectMapper();
jsonTutorias = mapper.writeValueAsString(tutorias);
jsonProfesores = mapper.writeValueAsString(profesores);
How could I manage json object in Ajax request?
... success: function (json) {
data = JSON.parse(json);
data.jsonTutorias[].item??
data.jsonProfesores[].item??
}
You can merge them using Map class:
Map response = new HashMap<>();
response.put("tutorias", tutorias);
response.put("profesores", profesores);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(map);
In JavaScript:
success: function (json) {
console.log(json.tutorias);
console.log(json.profesores)
}

File Upload with Form data in asp.net core

I am trying to upload files with form data from angular 1.5x to .net core web api controller.
My controller looks like this
[HttpPost]public async Task<ObjectResult> Create(TutorModel model)
{
}
My post method is
return $http.post("/api/Tutor/createTutor/",
data,
{
withCredentials: false,
headers: { 'Content-Type': undefined },
transformRequest: angular.identity,
responseType: "arryabuffer"
});
Where data is
for (var i = 0; i < vm.uploadedFiles.length ; i++) { //vm.upload contains list of file
data.append(vm.uploadedFiles[i].name, vm.uploadedFiles[i]);
}
data.append("tutor", tutor); //tutor is json object
Now when it posts to controller, model contains no property value. I get uploaded files in controller if I watch Request.Form.Files. What is the best method of sending model to post method above. Any pointer? Thanks
Asp.net core documentation cover this topic briefly.
Your controller action would be like this.
[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
long size = files.Sum(f => f.Length);
// full path to file in temp location
var filePath = Path.GetTempFileName();
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
// process uploaded files
return Ok(new { count = files.Count, size, filePath});
}
Where IFormFile have these properties
public interface IFormFile
{
string ContentType { get; }
string ContentDisposition { get; }
IHeaderDictionary Headers { get; }
long Length { get; }
string Name { get; }
string FileName { get; }
Stream OpenReadStream();
void CopyTo(Stream target);
Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
}
Note: Use caution when storing binary data in relational databases, as it can adversely impact performance.
Read detail article here
File Uploads
One method to upload the Tutor would be to use JSON.stringify like this:
data.append("tutor", JSON.stringify(tutor));
Then in your action, parse the JSON string:
[HttpPost]
public async Task<IActionResult> Create([FromForm] string tutor)
{
var tutorObj = JsonConvert.DeserializeObject<TutorModel>(tutor);
}
You can upload the file in the same request if you convert your js to this:
data.append("files", vm.uploadedFiles[i]);
Then add this to your action:
[FromForm] IEnumerable<IFormFile> files
You can try using formdata like so
const data = new FormData();
Then append your files and the json object
for (var i = 0; i < vm.uploadedFiles.length ; i++) { //vm.upload contains list of file
data.append(vm.uploadedFiles[i].name, vm.uploadedFiles[i]);
}
data.append("tutor", tutor);
Then post data.
On the server-side, create a method without any parameters, like
public async Task<ActionResult> Create() {
// You can access the posted form object from Request.Form
var vm = Request.Form;
// your files
var files = Request.Form.Files;
}
Request.Form is key value collection you can get anything you appended using the name.
Name is the first argument in the append method of FormData.

MobileFirst POST javascript array to java array

I have an array in javascript that I am trying to pass to my mobilefirst java adapter. I call my adapter like so,
myArr = [1,2,3];
var sendPost = new WLResourceRequest(
"/adapters/MyAdpater/path",
WLResourceRequest.POST
);
var formParam = {"arr":myArr};
sendTicketPost.sendFormParameters(formParams);
Then in my adapter I can have my method and get the param
public JSONObject postAdapterFx(#FormParam("arr") List<Integer> myArray) {}
Currently when I send this I just get a 400 error and it is because the adapter doesnt like the form param as that type, so what else could I set myArray to in the adapter? I can send it as a string and then convert the string to a List<Integer> in the java but that is really messy and I would like to avoid doing that.
So how can I pass this array?
Thanks for the help
you can do it in body with request.send(yourArray). Then you can read it in Java with buffer.
Example from knowledge center
var request = WLResourceRequest(url, method, timeout);
request.send(json).then(
function(response) {
// success flow
},
function(error) {
// fail flow
}
);
You will need to take an extra step before sending the form data to the adapter. sendFormParameters only accepts objects with simple values i.e., string, integer, and boolean; in your case arr is an array.
Create a utility function that will encode the form data, you can use the following:
function encodeFormData(data) {
var encoded = '';
for(var key in data) {
var value = data[key];
if(value instanceof Array) {
encoded += encodeURI(key+'='+value.join('&'+key+'='));
} else {
encoded += encodeURI(key+'='+value);
}
encoded += '&';
}
return encoded.slice(0, -1);
}
Then you will need to update your code as follows:
var myArr = [9,2,3];
var sendPost = new WLResourceRequest("/adapters/Cool/users/cool", WLResourceRequest.POST);
var formParam = {"arr" : myArr};
sendPost.sendFormParameters(encodeFormData(formParam));

Categories