ASP.NET Json Cannot deserialize the current JSON arrray - asp.net

I can't list a json on the razor page, it gives me this problem:
JsonSerializationException: Cannot deserialize the current JSON array
(e.g. [1,2,3]) into type 'JsonDisplayASP.Models.ListRates' because the
type requires a JSON object (e.g. {"name":"value"}) to deserialize
correctly.
Json:
[{"from":"USD","to":"AUD","rate":"0.93"},{"from":"AUD","to":"USD","rate":"1.08"}]
ratesControtller:
public class rates
{
public rates(string from, string to, double rate)
{
this.from = from;
this.to = to;
this.rate = rate;
}
[JsonPropertyName("from")]
public string from { get; set; }
[JsonPropertyName("to")]
public string to { get; set; }
[JsonPropertyName("rate")]
public double rate { get; set; }
public class ListRates
{
public List<rates> LRates { get; set; }
}
index.cshtml:
#model JsonDisplayASP.Models.ListRates
#foreach (var item in Model.LRates)
{
var from = item.from;
var to = item.to;
var rate = item.rate;
How can I do it? She won't let me show her a view

Sorry, I can get values.
public class HomeController : Microsoft.AspNetCore.Mvc.Controller
public IActionResult Index()
{
List<rates> lrates = new List<rates>();
var wc = new WebClient();
var json = wc.DownloadString(#"C:\Users\hugo\source\repos\JsonDisplayASP\JsonDisplayASP\wwwroot\lib\rates.json");
List<rates> model=JsonConvert.DeserializeObject<List<rates>>(json);
//var model = JsonConvert.DeserializeObject<rates>(json);
//return Json(model);
return View(model);
}

Related

Pass the model data into Controller to tabulate/calculate each of the values

I have a User.cs class model. I would like to get the data in my model and bring it to Controller to do some calculation.
How to pass the model data into Controller to tabulate/calculate each of the values. Example to for loop all the available data and do some calculation.
However, i find that most of the tutorial available are sending Model -> Controller -> View for example.
public ActionResult Index()
{
if (User.IsInRole(RoleName))
{
var users = _context.Users.ToList();
var patients = _context.Patients.ToList();
var patientAllocations = _context.PatientAllocations.ToList();
var albums = _context.Albums.ToList();
var viewModel = new ManagePatientsViewModel()
{
Users = users,
Patients = patients,
PatientAllocations = patientAllocations,
Albums = albums
};
return View(viewModel);
}
User Model
public class User
{
[Required]
public int userID { get; set; }
[StringLength(255)]
public string email { get; set; }
[StringLength(255)]
public string password { get; set; }
[StringLength(255)]
public string firstName { get; set; }
}
You can simply get model object in controller actions by defining it as a parameter of your action method:
[HttpPost]
public ActionResult MyAction(ManagePatientsViewModel model)
{
//you can access model properties...
for(int i=0; i<model.Users.Count; i++)
{
System.Diagnostics.Debug.WriteLine(model.Users[i].email);
}
return View(model);
}

asp.net web api list of list pass into json ajax

I have web api controller where I try to do something like this:
public IHttpActionResult Get()
{
var Rooms = db.Rooms.Select(r => new {
Id = r.Id,
Name = r.Name,
ChairNum = r.СhairNum,
Requests = r.Requests.ToList()
}).ToList();
return Ok(new { results = Rooms });
}
In Model I have this:
public partial class Room
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Room()
{
this.Requests = new HashSet<Request>();
}
public int Id { get; set; }
public string Name { get; set; }
public int СhairNum { get; set; }
public bool IsProjector { get; set; }
public bool IsBoard { get; set; }
public string Description { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Request> Requests { get; set; }
}
I tried to pass this data in service. But I have serialization error, when I call http://localhost:99999/api/Rest.
<ExceptionMessage>
The "ObjectContent`1" type could not serialize the response text for the content type "application / json; charset = utf-8".
</ ExceptionMessage>
What is the best way to pass the data like in model into json?
It helped to put in WebApiConfig:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

ASP.NET Cannot get FULL list of ALL countries in the world

There are 196 countries in the world.
I'm trying to show a dropdown list that show all of them.
I see many developer suggest using CultureInfo of ASP.NET but it's missing some countries because Culture & Country are different things.
So how can I get a list of all countries for my purpose please ?. I really appreciate your help.
In ASP.NET a DropDown
<asp:DropDownList ID="selCountries" runat="server"></asp:DropDownList>
is equivalent to
<select id="selCountries"></select>
Alternatively, you could use a Web service to fill a select tag with countries through JavaScript XMLHttpRequest object.
Example: https://restcountries.eu/
Something like this:
(function() {
var newXHR;
function sendXHR(options) { // Helper function.
newXHR = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
if (options.sendJSON === true) {
options.contentType = "application/json; charset=utf-8";
options.data = JSON.stringify(options.data);
} else {
options.contentType = "application/x-www-form-urlencoded";
}
newXHR.open(options.type, options.url, options.async || true);
newXHR.setRequestHeader("Content-Type", options.contentType);
newXHR.send((options.type == "POST") ? options.data : null);
newXHR.onreadystatechange = options.callback;
return newXHR;
}
sendXHR({
type: "GET",
url: "https://restcountries.eu/rest/v1/all",
callback: function() {
if (newXHR.readyState === 4 && newXHR.status === 200) {
var data = JSON.parse(newXHR.response);
var selCountries = document.getElementById("selCountries"); // Get the select tag.
// You can get the selected country.
selCountries.onchange = function() {
alert(this.value);
};
var option;
for (var i = 0; i < data.length; i++) { // For every country make an option tag.
option = document.createElement("option");
selCountries.options.add(option, 0);
selCountries.options[0].value = data[i].name; // Country name from the index «i» of the data array.
selCountries.options[0].innerText = data[i].name;
selCountries.appendChild(option); // Append the option tag to the select tag.
}
}
}
});
})();
<select id="selCountries"></select>
In ASP.NET MVC5 NET 4.5, you can bind an object to #Html.DropDownList by using ViewBag.
You need to create a model according to https://restcountries.eu/rest/v1/all json response.
Model: CountryModel.cs
using System.Collections.Generic;
namespace RestCountries.Models
{
public class Translations
{
public string de { get; set; }
public string es { get; set; }
public string fr { get; set; }
public string ja { get; set; }
public string it { get; set; }
}
public class CountryModel
{
public string name { get; set; }
public string capital { get; set; }
public List<string> altSpellings { get; set; }
public string relevance { get; set; }
public string region { get; set; }
public string subregion { get; set; }
public Translations translations { get; set; }
public int population { get; set; }
public List<object> latlng { get; set; }
public string demonym { get; set; }
public double? area { get; set; }
public double? gini { get; set; }
public List<string> timezones { get; set; }
public List<object> borders { get; set; }
public string nativeName { get; set; }
public List<string> callingCodes { get; set; }
public List<string> topLevelDomain { get; set; }
public string alpha2Code { get; set; }
public string alpha3Code { get; set; }
public List<string> currencies { get; set; }
public List<object> languages { get; set; }
}
}
Controller: DefaultController.cs
using RestCountries.Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web.Mvc;
namespace RestCountries.Controllers
{
public class DefaultController : Controller
{
// GET: Default
public ActionResult Index()
{
string url = "https://restcountries.eu/rest/v1/all";
// Web Request with the given url.
WebRequest request = WebRequest.Create(url);
request.Credentials = CredentialCache.DefaultCredentials;
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string jsonResponse = null;
// Store the json response into jsonResponse variable.
jsonResponse = reader.ReadLine();
if (jsonResponse != null)
{
// Deserialize the jsonRespose object to the CountryModel. You're getting a JSON array [].
List<CountryModel> countryModel = Newtonsoft.Json.JsonConvert.DeserializeObject<List<CountryModel>>(jsonResponse);
// Set the List Item with the countries.
IEnumerable<SelectListItem> countries = countryModel.Select(x => new SelectListItem() { Value = x.name, Text = x.name });
// Create a ViewBag property with the final content.
ViewBag.Countries = countries;
}
return View();
}
}
}
View: Index.cshtml
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.DropDownList("Countries")
Result:

Populating list view using a JSON subarray

I have the following JSON url. I am trying to populate my list view using the subarrays hair[] and math[] after getting them from the JSON url.
Here is the url http://pastebin.com/raw.php?i=2fzqLYXj
Inside the array "Students" there is a subarray called "Properties" and another sub array inside "Properties" called "Grades". "hair" is inside "Properties" and "math" is inside "Grades".
Here is my WebService class
public class WebService
{
public WebService ()
{
}
public async Task<Rootobject> GetStudentInfoAsync (string apiurl) {
var client = new HttpClient ();
var response = await client.GetStringAsync(string.Format(apiurl));
return JsonConvert.DeserializeObject<Rootobject>(response.ToString());
}
}
And here is my View Model
public class Property
{
public int iq { get; set; }
public string hair { get; set; }
public string glasses { get; set; }
public Grade[] Grades { get; set; }
}
public class StudentInfo
{
public string name { get; set; }
public string lastname { get; set; }
public Property[] Properties { get; set; }
public string StudentName {
get{ return String.Format ("{0}", name); }
}
//I am accessing the JSON sub arrays with the following to get the "hair" and "math" properties.
public string[] HairColors
{
get
{
return (Properties ?? Enumerable.Empty<Property>()).Select(p => p.hair).ToArray();
}
}
public string[] MathGrades
{
get
{
return (Properties ?? Enumerable.Empty<Property>()).SelectMany(p => p.Grades ?? Enumerable.Empty<Grade>()).Select(g => g.Math).ToArray();
}
}
}
public class Rootobject
{
public StudentInfo[] students { get; set; }
}
}
And here is how I populate my list view with student names which works. Notice "StudentName" was not in a subarray.
var sv = new WebService();
var es = await sv.GetStudentInfoAsync(apiurl);
Xamarin.Forms.Device.BeginInvokeOnMainThread( () => {
listView.ItemsSource = es.students;
});
var cell = new DataTemplate (typeof(TextCell));
listView.ItemTemplate = cell;
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "StudentName");
But I need to populate my list view with HairColors and MathGrades as follows but the following code does not work.
var sv = new WebService();
var es = await sv.GetStudentInfoAsync(apiurl);
Xamarin.Forms.Device.BeginInvokeOnMainThread( () => {
listView.ItemsSource = es.students;
});
var cell = new DataTemplate (typeof(TextCell));
listView.ItemTemplate = cell;
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "HairColors");
listView.ItemTemplate.SetBinding (TextCell.DetailProperty, "MathGrades");
What doesn't this code work? How do I make it work?
You could make a custom converter for this:
public class HairColorsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var hairColors = (string[])value;
return string.Join(", ", hairColors);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then bind this like:
SetBinding(TextCell.TextProperty, "HairColors", BindingMode.Default, new HairColorsConverter());

Problem with Object Data Type serialization in wcf using DataContract Attribute

I have created a WCF Rest API Service using wcf rest starter kit preview 2 which automatically return JSON or XML data depending on the requested content type. everything is working fine but as my service methods return multiple data type some methods returns a object of a class or collection of class, bool, int or collection type. so I planed to return a same Response in all methods for this I Create a new class as following:
[DataContract(Namespace = "")]
public class ServiceResponse
{
[DataMember]
public bool IsError
{ get; set; }
[DataMember]
public string ResponseMessage
{ get; set; }
[DataMember]
public Object ResponseData
{ get; set; }
}
and User class as following:
[DataContract(Namespace = "")]
public class User
{
[DataMember]
public string UserName
{ get; set; }
[DataMember]
public int UserID
{ get; set; }
}
In ServiceResponse Class I have declared an Object Type property ResponseData and my all method has return type of ServiceResponse. My problem is that when I set any string,bool,int type as ResponseData it is serialized but when I set collection type or an object of another class which also has DataContarct attribute this class is not serialized see below code :
public ServiceResponse GetUser(int userID)
{
User user = getUser(userID); get user data from database
ServiceResponse response=new ServiceResponse();
var response = new ServiceResponse
{
IsError = false,
ResponseMessage = string.Empty,
ResponseData = user; // Setting Result Data here
};
return response;
}
when I called above method(GetUser) I got Null response due to serialization problem, but following code works fine
public ServiceResponse TestMethod(string testMessage)
{
ServiceResponse response=new ServiceResponse();
var response = new ServiceResponse
{
IsError = false,
ResponseMessage = string.Empty,
ResponseData = testMessage; // Setting Result Data here
};
return response;
}
can anyone help me?
The problem that you're having is due to the fact that in your DataContract, you are declaring the ResponseData as an Object, but not telling WCF what types are valid known types. You need to explicitly tell WCF what known types are valid for your service, and you can do this by using the ServiceKnownType attribute. I've taken your code and made a few modifications to demonstrate this:
DataContracts
[DataContract(Name="ServiceResponse")]
public class ServiceResponse
{
[DataMember(Name="IsError", Order=1)]
public bool IsError
{ get; set; }
[DataMember(Name="ResponseMessage", Order=2)]
public string ResponseMessage
{ get; set; }
[DataMember(Name="ResponseData", Order=3)]
public Object ResponseData
{ get; set; }
}
[DataContract(Name="User")]
public class User
{
[DataMember(Name="UserName", Order=1, IsRequired=true)]
public string UserName
{ get; set; }
[DataMember(Name="UserID", Order=2, IsRequired=true)]
public int UserID
{ get; set; }
}
[DataContract(Name = "User2")]
public class User2
{
[DataMember(Name = "UserName", Order = 1, IsRequired = true)]
public string UserName
{ get; set; }
[DataMember(Name = "UserID", Order = 2, IsRequired = true)]
public int UserID
{ get; set; }
}
ServiceCode
[ServiceContract(Namespace = "WebApplication1")]
[ServiceKnownType(typeof(User))]
[ServiceKnownType(typeof(User2))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
[OperationContract(Name="GetUser")]
[WebGet(UriTemplate = "GetUser/{userID}", ResponseFormat = WebMessageFormat.Json)]
public ServiceResponse GetUser(String userID)
{
User theUser = new User()
{
UserID=Convert.ToInt32(userID),
UserName="bob"
};
ServiceResponse sr = new ServiceResponse()
{
IsError = false,
ResponseMessage = "",
ResponseData = theUser
};
return sr;
}
[OperationContract(Name = "GetUser2")]
[WebGet(UriTemplate = "GetUser2/{userID}", ResponseFormat = WebMessageFormat.Json)]
public ServiceResponse GetUser2(String userID)
{
User2 theUser = new User2()
{
UserID = Convert.ToInt32(userID),
UserName = "bob"
};
ServiceResponse sr = new ServiceResponse()
{
IsError = false,
ResponseMessage = "",
ResponseData = theUser
};
return sr;
}
}
What I did:
Not really necessary, but I added some additional attributes to the DataContract and members. I usually like to do that anyway, so I'm just being OCD there. :)
I created a second DataContract to demonstrate the use of ServiceKnownType.
In the service, I added the ServiceKnownType attributes on my service class, stating what types can be returned from my service methods.
That's pretty much it. Using the ServiceKnownType attributes is kind of ugly - there are some solutions out there to get around it (here).
Let me know if you have additional questions. Hope this helps!

Resources