Xamarin Forms reading JSON - json

So I am retrieving JSON data from my site and this is my code:
The model:
class Reservations
{
public string id_reservation { get; set; }
public string spz { get; set; }
public string reservation_day { get; set; }
public string reservation_time { get; set; }
public string ip_address { get; set; }
}
The connection and parsing:
protected async void CheckReservations(string day)
{
if (CrossConnectivity.Current.IsConnected)
{
try
{
private const string Url = "Urltomysite";
private HttpClient _client = new HttpClient();
var content = await _client.GetStringAsync(Url);
List<Reservations> myData = JsonConvert.DeserializeObject<List<Reservations>>(content);
foreach (Reservations res in myData)
{
System.Console.WriteLine("Time:" + res.reservation_time);
}
}
catch (Exception e)
{
Debug.WriteLine("" + e);
}
}
}
And the JSON response from my site:
[
{
id_reservation: "39",
spz: "NRGH67L",
reservation_day: "2019-01-26",
reservation_time: "14:00",
ip_address: "192.168.137.5"
}
]
But when I try to print the reservation_time from List of the Object in the foreach I dont get any results. I am still pretty new to this and got this far from tutorials, so dont know what I am missing.
Thanx for any replies.

I suggest using a crash prone way of this
var response = await client.GetAsync(uri);
if(response.IsSuccessStatusCode)
{
var json = await responseMessage.Content.ReadAsStringAsync(); //using ReadAsStreamAsync() gives you better performance
List<Reservations> myData = JsonConvert.DeserializeObject<List<Reservations>>(json);
//do the rest jobs
}
else
{
//alert the api call failed
}

Related

How to upload image in ASP.Net core code first approach and send image using post man

This is my model class
public class ImageModel
{
[Key]
public int ImageId { get; set; }
[Column(TypeName = "nvarchar(50)")]
public string Title { get; set; }
[Column(TypeName = "nvarchar(100)")]
[DisplayName("Image Name")]
public string ImageName { get; set; }
[NotMapped]
[DisplayName("Upload File")]
public IFormFile ImageFile { get; set; }
}
This is my controller class for post request
And I create a wwwroot folder to save Image
[Route("api/[Controller]")]
[ApiController]
public class ImageController : Controller
{
private readonly Databasecontext _context;
private readonly IWebHostEnvironment _hostEnvironment;
public ImageController(Databasecontext context, IWebHostEnvironment hostEnvironment)
{
_context = context;
this._hostEnvironment = hostEnvironment;
}
// GET: Image
public async Task<IActionResult> Index()
{
return View(await _context.Images.ToListAsync());
}
// GET: Image/Create
public IActionResult Create()
{
return View();
}
// POST: Image/Create
[HttpPost]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")] ImageModel imageModel)
{
if (ModelState.IsValid)
{
//Save image to wwwroot/image
string wwwRootPath = _hostEnvironment.WebRootPath;
string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
string extension = Path.GetExtension(imageModel.ImageFile.FileName);
imageModel.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
string path = Path.Combine(wwwRootPath + "/Image/", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
await imageModel.ImageFile.CopyToAsync(fileStream);
}
//Insert record
_context.Add(imageModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(imageModel);
}
This is my DB context
public DbSet<ImageModel> Images { get; set; }
I just need to test this using postman and combine it with angular. Can someone help me?
when I send an image through postman I get this error The request entity has a media type that doesn't support server or resource does not support.
That is because you use [ApiController] in your controller, it allows data from body by default. So you need specific the source by using [FromForm] attribute like below:
[HttpPost]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")][FromForm] ImageModel imageModel)
{
//..
return View(imageModel);
}
Besides, if you use [Bind("ImageId,Title,ImageName")], ImageFile cannot be binded to the model.
Sorry for my Spanish in the code.
This is how i upload the file in Base64 and then copy the file to a Directory.
I Pupulate the Object ArchivoAnexoUploadDto using a page http://base64.guru/converter/encode/file for convert a file to a base64.
I Hope tha this extract of the code will be usefull for you
1 - Controller
[HttpPost("UploadFileList")]
public async Task<IActionResult> UploadFileList(List<ArchivoAnexoUploadDto> fileList)
{
IOperationResult<object> operationResult = null;
try
{
operationResult = await _fileService.UploadFileList(fileList);
if (!operationResult.Success)
{
return BadRequest(operationResult.ErrorMessage);
}
return Ok(operationResult.Entity);
}
catch (Exception ex)
{
return BadRequest(operationResult.Entity);
}
}
I Recibe a List of Objects < ArchivoAnexoUploadDto > and the service converts the base 64 to Bytes array.
2 - Service
public async Task<IOperationResult<object>> UploadFileList(List<ArchivoAnexoUploadDto> files)
{
List<ArchivoAnexoCreateDto> fileList = PrepareFileList(files);
Response result = ValidateFiles(fileList);
if (!result.Status)
{
Response responseError = new()
{
Status = false,
Message = ((FormFile)result.Object).FileName,
MessageDetail = result.Message
};
return OperationResult<object>.Ok(responseError);
}
var saveResult = await SaveFileList(fileList);
Response respuesta = new()
{
Status = true,
Message = "Los archivos fueron almacenados exitosamente.",
MessageDetail = ""
};
return OperationResult<object>.Ok(respuesta);
}
private List<ArchivoAnexoCreateDto> PrepareFileList(List<ArchivoAnexoUploadDto> files)
{
List<ArchivoAnexoCreateDto> formFileList = new List<ArchivoAnexoCreateDto>();
foreach (ArchivoAnexoUploadDto newFile in files)
{
byte[] fileBytes = Convert.FromBase64String(newFile.Base64);
string filePath = Path.Combine(_fileSettings.PrincipalPath, _fileSettings.PrincipalFolderName, newFile.NombreArchivo);
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(fileBytes, 0, fileBytes.Length);
FormFile fileData = new FormFile(memoryStream, 0, memoryStream.Length, newFile.NombreArchivo, newFile.NombreArchivo);
ArchivoAnexoCreateDto fileDto = new()
{
FileId = 0,
Data = fileData,
FileName = newFile.NombreArchivo,
Module = newFile.Modulo
};
formFileList.Add(fileDto);
}
return formFileList;
}
private Response ValidateFiles(List<ArchivoAnexoCreateDto> fileList)
{
foreach (ArchivoAnexoCreateDto fileObj in fileList)
{
IFormFile file = fileObj.Data;
try
{
ValidateFile(file);
}
catch (Exception exception)
{
return new Response { Status = false, Message = exception.Message, Object = file };
}
}
return new Response { Status = true, Message = "" };
}
The Service recibe the Array and PrepareFileList return the same data but the array have IFormFile instead of Base64 string.
3 - Dtos
public sealed class ArchivoAnexoUploadDto
{
public long AnexoFileId { get; set; }
public string Base64 { get; set; }
public string NombreArchivo { get; set; }
public Module Modulo {get; set;}
}
public sealed class ArchivoAnexoCreateDto
{
public long FileId { get; set; }
public IFormFile Data { get; set; }
public int FileTypeId { get; set; }
public string FileName { get; set; }
public Module Module { get; set; }
}
ArchivoAnexoUploadDto Is the Dto that recives the base64 and the name of the file.
ArchivoAnexoCreateDto Is the Dto with IFormFile property and is used to copy the file to a Directory.
4 - Validate IFormFile To Copy to Dir
private void ValidateFile(IFormFile fileToCreate)
{
if (fileToCreate == null)
{
throw new Exception("No ha enviado ningun archivo.");
}
IOperationResult<string> fileExtensionResult = _fileService.GetFileExtension(fileToCreate);
if (!fileExtensionResult.Success)
{
throw new Exception(fileExtensionResult.ErrorMessage);
}
if (!_fileSettings.AllowedExtensions.Contains(fileExtensionResult.Entity))
{
throw new Exception("La extención del archivo no es permitida.");
}
IOperationResult<long> fileSizeResult = _fileService.GetFileSize(fileToCreate);
if (!fileSizeResult.Success)
{
throw new Exception("Ha ocurrido un error obteniendo el tamaño del archivo.");
}
if (fileSizeResult.Entity > _fileSettings.MaxFileSize)
{
throw new Exception("El tamaño del archivo supera el limite.");
}
}
This are Conditions for validate (Only for explain) I Did this stuff because the business configured a list of extensions, a size limit of the files, etc.

Deserializing json data from webservice

globally, I have the following object:
public class Geraet
{
public long Geraetenr { get; set; }
public int Typ { get; set; }
public string Platz { get; set; }
public string Bezeichnung { get; set; }
public int Tr { get; set; }
public string Ip { get; set; }
public string Bespielt { get; set; }
}
I populate a list of those objects, serialize them and send them via webservice:
[HttpGet]
public IHttpActionResult Get_Feedback()
{
List<Geraet> geraeteliste = null;
try
{
geraeteliste = GetSpielgeraeteFromDatabase();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
if (geraeteliste == null)
{
return Ok("No record found!");
}
else
{
var json = Newtonsoft.Json.JsonConvert.SerializeObject(geraeteliste);
return Json(json);
}
}
The data received by webservice looks like the following:
"[{\"Geraetenr\":123456789,\"Typ\":61,\"Platz\":\"1-01\",\"Bezeichnung\":\"CSII ADM430\",\"Tr\":3,\"Ip\":\"123.123.123.123\",\"Bespielt\":\"0\"},{\"Geraetenr\":987654321,\"Typ\":61,\"Platz\":\"2-12\",\"Bezeichnung\":\"M-BOX PUR+ GOLD\",\"Tr\":3,\"Ip\":\"124.124.124.124\",\"Bespielt\":\"0\"}]"
In my Xamarin App, I have the same object given above and trying to deserialize it:
private List<Geraet> GetSpielgeraeteFromWebservice()
{
List<Geraet> geraeteliste;
var request = HttpWebRequest.Create(Constants.GeraetelistServicePath);
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var json = reader.ReadToEnd();
geraeteliste = JsonConvert.DeserializeObject<List<Geraet>>(json);
}
}
return geraeteliste;
}
Unfortunately, I get an runtime error in the line geraeteliste = JsonConvert.DeserializeObject<List<Geraet>>(json); saying:
Unhandled Exception:
Newtonsoft.Json.JsonSerializationException: Error converting value "[{"Geraetenr":123456789,"Typ":61,"Platz":"1-01","Bezeichnung":"CSII ADM430","Tr":3,"Ip":"123.123.123.123","Bespielt":"0"},{"Geraetenr":987654321,"Typ":61,"Platz":"2-12","Bezeichnung":"M-BOX PUR+ GOLD","Tr":3,"Ip":"124.124.124.124","Bespielt":"0"}]" to type 'System.Collections.Generic.List`1[GroceryList.Classes.Geraet]'. Path '', line 1, position 3421.
The sending / retrieving stuff does work, otherwise error message would be in the line var json = reader.ReadToEnd(); or I wouldn't have gotten the right values in the error message. So something with the deserialization does not work.
Can anyone maybe help and tell me what is or could be the problem? Why can't he convert? It is the right order and the right values?
Best regards

BSON Object Being Partially Deserialized

I'm trying to deserialize a BSON HTTP Response Message from a Web API call into a custom type.
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:1234");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/bson"));
HttpResponseMessage result;
result = await client.GetAsync("/endpoint/");
MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
new BsonMediaTypeFormatter()
};
if (result.IsSuccessStatusCode)
{
try
{
RootObject res = await result.Content.ReadAsAsync<RootObject>(formatters);
}
catch (Exception e)
{
}
}
I know the Web API is returning BSON, I checked through Fiddler and the above code actually does deserialize most things correctly in the RootObject. It appears that all of the derived classes are not being deserialized and are just being input into the object as null. Here is an example of a derived class that is not being deserialized.
RootObject.Events.Teams.Linescores
RootObject
[DataContract(Namespace = "", Name = "RootObject")]
[Serializable]
public class RootObject: infoBase
{
[DataMember(EmitDefaultValue = false, Order = 30)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 30)]
public IEnumerable<eventInfo> events { get; set; }
public RootObject() { }
}
Events Object
[DataContract(Namespace = "", Name = "event")]
[Serializable]
[KnownType(typeof(subEventTeam))]
public class eventInfo : infoBase
{
[DataMember(EmitDefaultValue = false, Order = 170)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 170)]
public List<eventTeamBase> teams { get; set; }
public eventInfo() { }
}
Teams Base and Specific Team Type
[DataContract(Namespace = "", Name = "team")]
[Serializable]
[KnownType(typeof(bbLinescoreInfo))]
public class eventTeamBase : infoBase {
[DataMember(Order = 20)]
[JsonProperty(Order = 20)]
public string location { get; set; }
[DataMember(Order = 30, EmitDefaultValue = false)]
[JsonProperty(Order = 30, NullValueHandling = NullValueHandling.Ignore)]
public string nickname { get; set; }
[DataMember(EmitDefaultValue = false, Name = "linescores", Order = 130)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 130)]
public IEnumerable<linescoreBase> linescores { get; set; }
public eventTeamBase() { }
}
[DataContract(Namespace = "", Name = "team")]
[Serializable]
public class subEventTeam : eventTeamBase
{
public subEventTeam () { }
}
Linescore Base and Specific Object
[DataContract(Name = "linescores", Namespace = "")]
[Serializable]
[KnownType(typeof(subLinescoreInfo))]
public class linescoreBase : infoBase
{
public bool isProcessing = false;
public int teamId { get; set; }
public linescoreBase() { }
}
[DataContract(Name = "linescores", Namespace = "")]
[Serializable] public class subLinescoreInfo : linescoreBase
{
[DataMember]
public int inning { get; set; }
[DataMember]
public int? score { get; set; }
public subLinescoreInfo() { };
}
Here is the deserialized (and then re-serialized) part of the response that isn't working output into JSON.
{
"status":"OK",
"recordCount":1,
"RootObject":[
{
"events":[
{
"teams":[
{
"location":"Tallahassee",
"nickname":"Razors",
"linescores":[
{},{},{},{},{},{},{},{}]
}
}
}
}
So as you can see, it is filling in some information correctly (There is a lot more, I've cut down significantly just to illustrate the problem). But the linescores are returning null. As mentioned, the data is returning correctly and it is not null.
I feel like I'm doing something wrong with the known types and I've tried numerous combinations of putting them in different places and the results don't change. Any help would greatly appreciated.
After much searching and trying wrong things, I found a similar solution in another thread.
JSON Solution
I solved this by doing pretty much that exact same thing but with BSON instead of JSON.
This is the code that I needed to add in the global config file of the Web API
BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
bsonFormatter.AddQueryStringMapping("accept", "bson", "application/bson");
GlobalConfiguration.Configuration.Formatters.Add(bsonFormatter);
And this code went into the client.
BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
bsonFormatter
};
Everything else remained the same and was deserialized without incident.

Fetching json array, null pointer refrence exception

{"names":["name1","name2","name3","name4"]}
I need to fetch this and show them in a list. What I am doing is
public class brand
{ public string Name
{ get; set; }
}
public class brands
{ public list<brand> Names
{ get; set; }
}
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
getdata();
}
private void getdata()
{
string uri = "URL";
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(new Uri(uri));
req.BeginGetResponse(new AsyncCallback(show), req);
}
private void show(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
StreamReader stream1 = new StreamReader(response.GetResponseStream());
string s1 = stream1.ReadToEnd();
var ser = new DataContractJsonSerializer(typeof(brands));
var stream = new MemoryStream(Encoding.Unicode.GetBytes(s1));
var bb = (brands)ser.ReadObject(stream);
foreach (var ev in bb.Names)
{
textBlock1.Text = ev.Name.ToString();
}
}
This I made after reading blog posts. I am getting NullReferenceException.
Please tell me where I am doing wrong or alternative way to do the same.
First learn how to parse your JSON data. Consider this as a json string.
String jsonData = #"{""names"":[""name1"",""name2"",""name3"",""name4""]}";
var brands = JsonConvert.DeserializeObject<Brands>(jsonData);
foreach (var item in brands.names)
{
Console.WriteLine(item);
}
Where your Brands class is like this
public class Brands
{
public List<string> names { get; set; }
}
This above code explains how to parse your json data. Now, coming to fetching your json data from web service, as your request is not a POST request (it appears to be get from your code), you can use a simple WebCleint.
void getData()
{
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri("url"));
}
void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var brands = JsonConvert.DeserializeObject<Brands>(e.Result);
foreach (var item in brands.names)
{
Console.WriteLine(item);
}
}
Check this blog for any other doubts : Parsing JSON in a Windows Phone Application

get Facebook Pages in Windows Phone 7 using C# SDK

I tried to figure this out using the Windows Phone sample from the Facebook C# SDK page, but have been unsuccessful.
Here's the main code:
private void GetPages()
{
var fb = new FacebookClient(_accessToken);
fb.GetCompleted += (o, e) =>
{
if (e.Error != null)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.Error.Message));
return;
}
var result = (IDictionary<string, object>)e.GetResultData();
// returns data and paging from Facebook
Dispatcher.BeginInvoke(() =>
{
foreach (var item in result)
{
// Not sure if/how to use the custom classes here
//item has .Key and .Value
//.Key = data and .Value contains the key/value pais for each of the pages returned
}
});
};
fb.GetAsync("me/accounts");
}
// Custom Classes
public class FacebookPageCollection
{
[JsonProperty(PropertyName = "data")]
public FacebookPage[] data { get; set; }
[JsonProperty(PropertyName = "paging")]
public FacebookPagePaging paging { get; set; }
}
public class FacebookPage
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "access_token")]
public string AccessToken { get; set; }
[JsonProperty(PropertyName = "category")]
public string Category { get; set; }
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
}
public class FacebookPagePaging
{
[JsonProperty(PropertyName = "previous")]
public Uri previous { get; set; }
[JsonProperty(PropertyName = "next")]
public Uri next { get; set; }
}
This is what the variable "result" returns:
{"data":[{"name":"value1","access_token":"value2","category":"value3","id":"value4","perms":["ADMINISTER","EDIT_PROFILE","CREATE_CONTENT","MODERATE_CONTENT","CREATE_ADS","BASIC_ADMIN"]},{"name":"value1","access_token":"value2","category":"value3","id":"value4","perms":["ADMINISTER","EDIT_PROFILE","CREATE_CONTENT","MODERATE_CONTENT","CREATE_ADS","BASIC_ADMIN"]}],"paging":{"next":"url"}}
What I'd like to do is retrieve and save details for each page.
I have been trying to figure this out and have looked over a number of other posts on here and elsewhere. I just don't have enough experience to figure it out.
Any help is appreciated.
Thank you.
Sri
Here is a trick to understanding how to work with json response in fb c# sdk.
Here is the mapping between Javascript JSON and C# JSON. (Notice there is no DateTime and another complex .net objects as it is not part of the JSON spec found in JSON.org)
JsonObject => keyvalue pairs => IDictionary<string, object> / IDictinary<string, dynamic>
JsonArray => array => IList<object> / IList<dynamic>
string => string
number => long/decimal
boolean => bool
Here is how you do the actual mapping.
var result = (IDictionary<string, object>)e.GetResultData();
var data = (IList<object>)result["data"];
foreach(var act in data) {
var account = (IDictionary<string,object>) act;
var name = (string)account["name"];
var accessToken = (string)account["access_token"];
var id = (string)account["id"];
// normalize to IList<string> permissions, so it is easier to work without casting.
var permissions = ((IList<object>)account["perms"]).Select(x => (string)x).ToList();
}