stream writer is not writing to JSON file in webapi - json

Im trying to write data in a JSON file using webapi but stream writer is not writing data to the file.
JSON File :
{
"Students": [
{
"id": 1,
"name": "Ravi",
"department": "IT"
},
{
"id": 2,
"name": "Raj",
"department": "hr"
},
{
"id": 3,
"name": "avi",
"department": "it"
},
{
"id": 4,
"name": "rome",
"department": "HR"
},
{
"id":5,
"name": "virat",
"department": "HR"
},
{
"id":6 ,
"name": "Tushar",
"department": "RM"
}
]
}
Class
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Department { get; set; }
}
public class Students
{
public List<Student> students { get; set; }
}
Api controller: [HttpPost] method for writing data to the json file.
[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
[HttpPost]
public IActionResult Add(Students _Student)
{
using (var fs = new FileStream("C:/Users/tanmay_pawar/source/repos/CRUDAPI/CRUDAPI/people.json", FileMode.Append))
using (var sw = new StreamWriter(fs))
{
sw.WriteLine(_Student);
}
}
The data recieved in by _Student is not getting added to the json file.

try this
public IActionResult Add(Students _Student)
{
if(_Student==null || _Student.students==null) return null;
var filePath = #"C:\Users\....\..json";
var json = File.ReadAllText(filePath);
Students students = JsonConvert.DeserializeObject<Students>(json);
students.students.AddRange(_Student.students);
json=JsonConvert.SerializeObject(students);
File.WriteAllText(filePath, json);
}

Try the code like below:
[HttpPost]
public IActionResult Add(Students _Student)
{
string jsonresult = JsonConvert.SerializeObject(_Student);
string path = #"C:\c\people.json";
using(var tw=new StreamWriter(path,true))
{
tw.WriteLine(jsonresult.ToString());
tw.Close();
}
return Ok();
}
result:
Update more picture, add data inside the existing JSON file.

Related

How to extract only part of the JSON and de-serialize it in .netcore

I have .net core application , where an API is called through HTTPClient.
The response for that API in JSON format is as follows:
{
"ID": 25,
"Customer": "CustomerName",
"total": 100,
"details": [
{
"ItemId": "Item1",
"ItemName": "Name1",
"Price": "10"
},
{
"ItemId": "Item2",
"ItemName": "Name2",
"Price": "50"
},
{
"ItemId": "Item3",
"ItemName": "Name3",
"Price": "40"
}
]
}
I get this response from -- > var response = client.GetAsync(ApiPath).Result;
Now from the response variable I need details only for details like :
{
{
"ItemId": "Item1",
"Price": "10"
},
{
"ItemId": "Item2",
"Price": "50"
},
{
"ItemId": "Item3",
"Price": "40"
}
}
I have a DTO class like this :
public class ItemDetails
{
public string ItemId { get; set; }
public string Price { get; set; }
}
Can anyone help in extracting the details according to the DTO class from the main variable "response".
Many thanks!
Try this if you are using newtonsoft
var token = JObject.Parse(response);//load
var detailsToken = token.SelectToken("details");//select
var itemDetails = detailsToken.ToObject<ItemDetails[]>(); //cast to array
Only the properties that exist on ItemDetails will be mapped
You can deserialize the response into an object and take whatever you like from it.
Use the built-in JSON library in .net-core as following
using System.Text.Json;
using System.Text.Json.Serialization;
then make a Response classes to contain the Response values
public class ResponseObject
{
public int ID { get; set; }
public string Customer { get; set; }
[JsonPropertyName("total")]
public int Total { get; set; }
[JsonPropertyName("details")]
public ItemDetails[] Details { get; set; }
}
public class ItemDetails
{
public string ItemId { get; set; }
public string ItemName { get; set; }
public string Price { get; set; }
}
finally, deserialize and extract whatever you like as following
var o = JsonSerializer.Deserialize<ResponseObject>(response);
ItemDetails[] itemDetails= o.Details;

Processing a POST with a list of JSON in .NET Core API

I am trying to capture user response from a form
My Model for the response looks like this:
{
public int UserId { get; set; }
public int QId { get; set; }
public int OptionId { get; set; }
public string Response { get; set; }
public SurveyCreatorOptions SurveyCreatorOptions { get; set; }
public SurveyUserMasters User { get; set; }
}
The above model and the DbContext was created was created on scaffolding the existing database using efcore database first approach.
The POST method in the controller looks like this:
// POST: api/SurveyUserResponses
[HttpPost]
public async Task<IActionResult> PostSurveyUserResponse([FromBody] SurveyUserResponse surveyUserResponse)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.SurveyUserResponse.Add(surveyUserResponse);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (SurveyUserResponseExists(surveyUserResponse.UserId))
{
return new StatusCodeResult(StatusCodes.Status409Conflict);
}
else
{
throw;
}
}
return CreatedAtAction("GetSurveyUserResponse", new { id = surveyUserResponse.UserId }, surveyUserResponse);
}
Using this method in my controller I can send a post request in the following format:
{
"userId": 1,
"qId": 2,
"optionId": 1,
"response": "Male",
"surveyCreatorOptions": null,
"user": null
}
The above mentioned method will capture only one field of the form but my form contains multiple fields.
So I want to send a JSON of this format
[
{
"userId": 1,
"qId": 1,
"optionId": 1,
"response": "XYZ",
"surveyCreatorOptions": null,
"user": null
},
{
"userId": 1,
"qId": 2,
"optionId": 1,
"response": "Male",
"surveyCreatorOptions": null,
"user": null
},
{
"userId": 1,
"qId": 3,
"optionId": 4,
"response": "Samsung",
"surveyCreatorOptions": null,
"user": null
}
]
I am new to .NET I am confused about how to write the POST method and bind every element of the above list to my database.
I have made the Ajax post method which can send a json of above format so that is not a problem
The above mentioned method will capture only one field of the form but my form contains multiple fields
The builtin ModeBinders will take care that if you change your action to accpet a List<>:
public async Task<IActionResult> PostSurveyUserResponse([FromBody] SurveyUserResponse surveyUserResponse)
public async Task<IActionResult> PostSurveyUserResponse([FromBody] List<SurveyUserResponse> surveyUserResponses)
{
....
}

Json.net append json file

I have the following code which uses Json.net:
class HistorianRecord
{
public string tagname { get; set; }
public string engunits { get; set; }
public string value { get; set; }
public string quality { get; set; }
public DateTime timestamp { get; set; }
}
private static void createJSONFile(DataTable dt)
{
var HistorianData = new List<HistorianRecord>();
foreach(DataRow row in dt.Rows)
{
HistorianData.Add(new HistorianRecord()
{
tagname = row["tagname"].ToString(),
engunits = row["engunits"].ToString(),
value = row["value"].ToString(),
quality = row["quality"].ToString(),
timestamp = DateTime.Parse(row["timestamp"].ToString())
});
}
var serializer = new JavaScriptSerializer();
var serializedResult = serializer.Serialize(HistorianData);
var deserializedResult = serializer.Deserialize<List<HistorianRecord>>(serializedResult);
File.WriteAllText(folderPath + fileName, JsonConvert.SerializeObject(deserializedResult));
}
Which produces the following JSON file, which I have shortened for this post as the are > 1000 rows in the datatable:
[
{
"tagname": "mytag1",
"engunits": "",
"value": "2",
"quality": "Good NonSpecific",
"timestamp": "2018-12-13T10:45:05Z"
},
{
"tagname": "myTag2",
"engunits": "",
"value": "0",
"quality": "Good NonSpecific",
"timestamp": "2018-12-13T10:45:00Z"
}
]
I would like to amend my code to so I can add some items at the beginning of the JSON file so it looks more like this:
[
{
"name": "ARandomName",
"content": [
{
"tagname": "mytag1",
"engunits": "",
"value": "2",
"quality": "Good NonSpecific",
"timestamp": "2018-12-13T10:45:05Z"
},
{
"tagname": "myTag2",
"engunits": "",
"value": "0",
"quality": "Good NonSpecific",
"timestamp": "2018-12-13T10:45:00Z"
}
]
}
]
This is so I can create some documents for a test MongoDB installation that I am investigating so all help is appreciated.
You simply can wrap your deserialized list of HistorianRecords in an anonymous object and reserialize it:
var anon = new
{
name = "ARandomName",
content = deserializedResult
};
string newJson = JsonConvert.SerializeObject(anon, Formatting.Indented);
Fiddle: https://dotnetfiddle.net/6kSvxS

how to send complex type from client side to server side

i have a page that needs to send complex data from client side into webmethod in asp.net mvc.
my data is :
{"tbl":[{"row":{"items":[{"name":"madrak1","val":"fdsfds"},{"name":"mahaleTahsil1","val":"fdsfds"},{"name":"reshte1","val":""},{"name":"start1","val":""},{"name":"end1","val":""}]}}]}
i need to have a class named table that put all the variables inside it.
my webmethod is :
public ActionResult SaveDetailedInfo(List<rrow> tbl)
{
return Json(new { status = "Success", message = "Success" });
}
Your C# classes should look something like:
public class Item
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("val")]
public string Val { get; set; }
}
public class Row
{
[JsonProperty("items")]
public IList<Item> Items { get; set; }
}
public class Tbl
{
[JsonProperty("row")]
public Row Row { get; set; }
}
public class Table
{
[JsonProperty("tbl")]
public IList<Tbl> Tbl { get; set; }
}
And your MVC method:
public ActionResult SaveDetailedInfo(Table table)
{
return Json(new { status = "Success", message = "Success" });
}
So sending data from your front end...
var table = {
"tbl": [{
"row": {
"items": [{
"name": "madrak1",
"val": "fdsfds"
}, {
"name": "mahaleTahsil1",
"val": "fdsfds"
}, {
"name": "reshte1",
"val": ""
}, {
"name": "start1",
"val": ""
}, {
"name": "end1",
"val": ""
}]
}
}]
};
var xhr = new XMLHttpRequest();
xhr.open('POST', '/Home/SaveDetailedInfo', true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
// send the collected data as JSON
xhr.send(JSON.stringify(table));
Should result in...
PS. There is an easy way to convert your json objects into C# classes

Creating json object in mvc and returning from controller

I need to create the following in a loop, my has "name" and "id" where name will be used for the value property of the json object and id will be used for the "data" and query will be some string I can set.
I tried using keypair but could not figure out how to do this property. Any help would be appreciated.
{
"query": "Unit",
"suggestions": [
{ "value": "United Arab Emirates", "data": "AE" },
{ "value": "United Kingdom", "data": "UK" },
{ "value": "United States", "data": "US" }
]
}
I am trying to return results for this autocomplete widget
https://www.devbridge.com/sourcery/components/jquery-autocomplete/
You can just create an anonymous object. To return the JSON as indicated in your question, it would be
public JsonResult GetCities(string query)
{
var data = new
{
query = "Unit",
suggestions = new[]
{
new { value = "United Arab Emirates", data = "AE" },
new { value = "United Kingdom", data = "UK" },
new { value = "United States", data = "US" }
}
};
return Json(data, JsonRequestBehavior.AllowGet);
}
Side note: Unsure of the purpose of the method parameter?
I hate to go full blown on this, but maybe create your own classes?
public class DataValuePair
{
public string Data {get;set;}
public string Value {get;set;}
}
public class SearchResult
{
public string Query {get;set;}
public List<DataValuePair> Suggestions {get;set;}
}
And now you can return a JSON Result
return Json(mySearchResult);
Answer from OP:
Figured it out, below is the code
public ActionResult GetCities(string query)
{
var obj = new CitySuggestion();
obj.suggestions.Add(new Suggestion { value = "test1", data = "test1" });
obj.suggestions.Add(new Suggestion { value = "test2", data = "test2" });
obj.suggestions.Add(new Suggestion { value = "test3", data = "test3" });
return Content(JsonConvert.SerializeObject(obj), "application/json");
}
public class CitySuggestion
{
public CitySuggestion()
{
suggestions = new List<Suggestion>();
}
public List<Suggestion> suggestions
{
get;
set;
}
}
public class Suggestion
{
public string value { get; set; }
public string data { get; set; }
}