MVC 5 populate a model with Json - json

I have the following ActionResult:
public ActionResult WeatherWidget()
{
string json = string.Empty;
using (var client = new WebClient())
{
json = client.DownloadString("http://api.wunderground.com/api/xxxxxxxxx/geolookup/conditions/forecast/q/Australia/sydney.json");
}
WeatherWidget weatherWidget = new WeatherWidget()
{
//What do I put in here?
};
return View(weatherWidget);
}
And the following model:
public class WeatherWidget
{
public string city { get; set; }
public string lat { get; set; }
public string lon { get; set; }
}
Here is a snippet of the json:
{
"response": {
"version":"0.1",
"termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"geolookup": 1
,
"conditions": 1
,
"forecast": 1
}
}
,"location": {
"type":"INTLCITY",
"country":"AU",
"country_iso3166":"AU",
"country_name":"Australia",
"state":"VC",
"city":"Falls Creek",
"tz_short":"AEST",
"tz_long":"Australia/Melbourne",
"lat":"-36.86999893",
"lon":"147.27000427",
"zip":"00000",
How do I populate the model to display in my view?
e.g.. #Model.city or #Html.Raw(Model.city)
I have no problem displaying the data via Javascript in my view and I can do this with XML and Html using the HtmlAgilityPack, I just can't work out how to do it with Json.

Add Newtonsoft.Json via NuGet, add the following using statements
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
and then use the following code to extract the data out of your JSON response.
JObject parsedJson = (JObject)JsonConvert.DeserializeObject(json);
JObject location = (JObject)parsedJson["location"];
WeatherWidget weatherWidget = new WeatherWidget();
weatherWidget.city = location["city"];
weatherWidget.lat = location["lat"];
weatherWidget.lon = location["lon"];

Related

Multipart/form-data images upload with JSON asp.net core api

How to POST both images and JSON at the same time in a single POST ? (using multipart)
I have a form with some data that i put into JSON and the users can add 0 to 6 photos and submit it to the API.
Can someone explain me how to do it ?
Edit :
Here is my code thanks to your help :
// POST api/<controller>
[HttpPost, Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult Post(ViewModel vm)
{
IActionResult response = Unauthorized();
var data = vm.FamilleProduit;
var reforigine = vm.RefOrigine;
if (vm.Images != null)
{
foreach (var image in vm.Images)
{
byte[] fileData = null;
// read file to byte array
using (var binaryReader = new BinaryReader(image.OpenReadStream()))
{
fileData = binaryReader.ReadBytes((int)image.Length);
}
}
}
return response;
}
public class ViewModel
{
public string FamilleProduit { get; set; }
public string RefOrigine { get; set; }
public List<IFormFile> Images { get; set; }
}
I'm testing with Postman and i POST 2 text (FamilleProduit & RefOrigine) and 2 files (2 images) with "multipart/form-data".
I get the 2 texts perfectly but Images field is null everytime.
Thanks,
Tristan.
You can use built-in class IFormFile to easily work with file upload. To use it together with JSON you may create custom model binder and combine it together in DTO object:
public class ViewModel
{
[ModelBinder(BinderType = typeof(FormDataJsonBinder))]
public DataModel Data { get;set; }
public List<IFormFile> Images { get; set; }
}
public class FormDataJsonBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if(bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
string fieldName = bindingContext.FieldName;
var valueProviderResult = bindingContext.ValueProvider.GetValue(fieldName);
if(valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
else
{
bindingContext.ModelState.SetModelValue(fieldName, valueProviderResult);
}
string value = valueProviderResult.FirstValue;
if(string.IsNullOrEmpty(value))
{
return Task.CompletedTask;
}
try
{
object result = JsonConvert.DeserializeObject(value, bindingContext.ModelType);
bindingContext.Result = ModelBindingResult.Success(result);
}
catch(JsonException)
{
bindingContext.Result = ModelBindingResult.Failed();
}
return Task.CompletedTask;
}
}
Then you can work with it in your controller:
[HttpPost]
public IActionResult Create(ViewModel vm)
{
var data = vm.Data;
if (vm.Images != null)
{
foreach(var image in vm.Images)
{
byte[] fileData = null;
// read file to byte array
using (var binaryReader = new BinaryReader(image.OpenReadStream()))
{
fileData = binaryReader.ReadBytes((int)image.Length);
}
}
}
}

Xamarin store multiple data in Variable

I have my code, where i fetch data from a url and parse that data with json.
public async void GetItems()
{
HttpResponseMessage response = new HttpResponseMessage();
HttpClient httpclient = new HttpClient();
Uri uri = new Uri("URL");
response = await httpclient.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var JsonContent = await response.Content.ReadAsStringAsync();
JArray jArray = JArray.Parse(JsonContent);
foreach (var data in jArray)
{
var latitude = data["latitude"];
Console.WriteLine(latitude);
}
}
}
in this code I get all my data and print them into the console.
I have a class with the variables i want to set
public class FetchedObjects
{
public string name { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
}
How can I store each data from my jArray into these variables? I want to have access to these from my ios or android project.
EDIT
I have some values in json, which are null. How can i handle these, while creating the list? My App crashes, it says :
Error setting value to 'valuename' on 'App.FetchedObjects'
Try it code:
List<FetchedObjects> list = jArray.ToObject<List<FetchedObjects>>();
Edit
in pcl library create class:
public class YourClass
{
public async Task<List<FetchedObjects>> GetItems()
{
....
if(jArray != null)
{
List<FetchedObjects> list = jArray.ToObject<List<FetchedObjects>>();
return list;
}
else
{
return null;
}
...
}
Add reference to pcl library in your ios and android projects and Use class YourClass

Insert JSON formatted string into JSON structure

I have a question about inserting a json formatted string into a json structure and having the final version be a combined JSON formatted string that can be serialized into a JSON structure. I am using the newtonsofts Json.NET
I have the following JSON structure:
public class ResponseJson
{
[JsonProperty(PropertyName = "header")]
public ResponseHeader responseHeader { get; set; }
[JsonProperty(PropertyName = "results")]
public string responseResults { get; set; }
}
public class ResponseHeader
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "version")]
public string version { get; set; }
}
In the code, I do the following:
ResponseJson responseJson = new ResponseJson();
responseJson.responseHeader = new ResponseHeader()
{
name = A_NAME,
version = A_VERSION
};
responseJson.responseResults = resultJson;
return JsonConvert.SerializeObject(responseJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
resultJson is a properly formatted JSON string (in this case, an array of objects, but could be anything JSON formatted). Right now, if i execute the code, I get the following (which is expected, since "results" is declared as a string):
{
"header":
{
"name":"abcd",
"version":"1.0"
},
"results":
"[{\"data\":{\"level\":\"100\"},\"code\":{\"value\":\"JBC\",\"type\":\"ev\"},\"time\":{\"start\":\"20\",\"end\":\"101\"}}]"
}
what I do need as an output is:
{
"header":
{
"name":"abcd",
"version":"1.0"
},
"results":
[
{
"data":
{
"level":"100"
},
"code":
{
"value":"JBC",
"type":"ev"
},
"time":
{
"start":"20",
"end":"101"
}
}
]
}
While you don't explain how you create your resultJson variable, it's implied from your code that you are double-serializing your results: you compute an array of "result" classes, serialize them to a JSON string, store the string in your ResponseJson class, and them serialize that in turn. The embedded JSON string then gets escaped as per the JSON standard, which is what you are seeing.
You need to avoid double-serializing your data, for instance by using the following data model:
public class ResponseJson<T>
{
[JsonProperty(PropertyName = "header")]
public ResponseHeader responseHeader { get; set; }
[JsonProperty(PropertyName = "results")]
public T responseResults { get; set; }
}
public static class ResponseJson
{
public static ResponseJson<T> Create<T>(T responseResults, ResponseHeader responseHeader)
{
return new ResponseJson<T> { responseResults = responseResults, responseHeader = responseHeader };
}
}
public class ResponseHeader
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "version")]
public string version { get; set; }
}
Then you would do:
var results = GetResults(); // Get your result data
var responseJson = ResponseJson.Create(results, new ResponseHeader()
{
name = A_NAME,
version = A_VERSION
});
return JsonConvert.SerializeObject(responseJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
If for whatever reason you must embed a previously serialized JSON string as JSON rather than as a string literal, you'll need to re-parse it back to a JToken:
string resultJson = GetResultJson(); // Get result json string.
var responseJson = ResponseJson.Create(JToken.Parse(resultJson), new ResponseHeader()
{
name = A_NAME,
version = A_VERSION
});
return JsonConvert.SerializeObject(responseJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
Json.NET will include the JToken in your outer JSON as nested JSON rather than as a string literal.

JsonConvert a json with a list<> element WP8

I have a json coming from webservice, which has a List<> element in it.
But when I try to deserialize it using Newtonsoft.Json
Response resp = JsonConvert.DeserializeObject<Response>(responseStr);
then when I fetch the list using resp.ProjectList, it throws a null pointer exception.
So the List<Project> is not getting deserialized.
Any idea what am I missing?
The response is of the form:
public Response
{
public string msg;
public List<Project> ProjectList{get; set;}
}
[DataContract]
public class Project
{
[DataMember]
public string ID {get; set;}
}
Just remove the [DataContract] and [DataMember] attributes, they do not mix well with Json.NET.
Or you can do the deserialization "manually"
var j = JToken.Parse("{ \"Msg\": \"Success\", \"ProjectList\": [ { \"ID\": \"/Date(1400120100000-0700)/\" }, { \"ID\": \"/Date(1404260520000-0700)/\" } ] } ");
var resp = new Response
{
msg = j.SelectToken("Msg").ToString(),
ProjectList = ((JArray) j.SelectToken("ProjectList")).Select(l => new Project {ID = l.SelectToken("ID").ToString()}).ToList()
};

Nested list with JavaScriptSerializer

I'm trying to produce the following JSON structure with JavaScriptSerializer in Net 3.5:
{
"chart": "pie",
"series": [
{
"name": "Browsers",
"data": [
[
"Firefox",
6
],
[
"MSIE",
4
]
],
"size": "43%"
}
]
}
The issue I face is regarding the data section. I cannot seem to create a class that serializes into the above structure in data.
I have read other posts which kind of touch the subject but the solution always seem to be to use JSON.Net. For instance Serializing dictionaries with JavaScriptSerializer. Although, I primaily want to solve it by using the JavaScriptSerializer or other built-in features in the .Net 3.5 framework.
How do I produce the data section?
*EDIT The way to solve it with the JavaScriptSerializer is to create an object array for the data property on the object about to be serialized.
Input parameter data is "Firefox:6\nMSIE:4\nChrome:7".
public object[] GetData(string data)
{
var dataStrArr = data.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
var dataArr = new object[dataStrArr.Length];
for (var index = 0; index < dataStrArr.Length; index++)
{
var component = dataStrArr[index];
var componentArr = component.Split(':');
if (componentArr.Length != 2)
continue;
var key = componentArr[0];
decimal value;
if (decimal.TryParse(componentArr[1], out value))
{
var keyValueArr = new object[2];
keyValueArr[0] = key;
keyValueArr[1] = value;
dataArr[index] = keyValueArr;
}
}
return dataArr;
}
I think you need something like the following class (RootObject) to serialize that:
public class Series
{
public string name { get; set; }
public List<List<object>> data { get; set; }
public string size { get; set; }
}
public class RootObject
{
public string chart { get; set; }
public List<Series> series { get; set; }
}
Let me know if that helps.