Xamarin rest web service doesn't deserialize - c#

I want to use rest with get method. My code is below;
public class RegisterPage : ContentPage
{
Label label, l4, label2;
public RegisterPage()
{
Button btn = new Button
{
Text = "register"
};
btn.Clicked += Btn_Clicked;
label = new Label();
l4 = new Label();
label2 = new Label();
Content = new StackLayout
{
Children = {
btn,
label,
l4,
label2
}
};
}
private async void Btn_Clicked(object sender, EventArgs e)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add(Constants.API_KEY_HEADER_KEY, Constants.API_KEY);
string URL = Constants.URL;
var response = await client.GetAsync(URL);
var content = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Models.Result>(content);
label.Text = result.Success.ToString();
l4.Text = result.Error.ToString();
label2.Text = ((RegisteredDevice)result.Retval).Clientuuid + " - " + ((RegisteredDevice)result.Retval).Deviceuuid;
}
}
The url is working good. And my content value has json string. But the serialization is not working.
var result = JsonConvert.DeserializeObject(content);
This code doesn't deserilize.
My model is;
public class Result
{
private object retval = null;
private bool success = false;
private Error error = null;
internal Error Error
{
get { return error; }
set { error = value; }
}
public bool Success
{
get { return success; }
set { success = value; }
}
public object Retval
{
get { return retval; }
set { retval = value; }
}
}
Json:
{
"result":{
"retail":{
"#xsi.type":"registeredDevice",
"clientuuid":"28asgargb-acfe‌​-41dfgsdg51",
"deviceuuid":123456
},
"success":true
}
}

I think the problem comes from :
private object retval = null;
So for me the best way to construct serialization objects in C# is to use this web site :
http://json2csharp.com/
This will tell you if your json is correct and he will generate the classes you need for you, here the classes generated by json2csharp
public class Retail
{
public string __invalid_name__#xsi.type { get; set; }
public string clientuuid { get; set; }
public int deviceuuid { get; set; }
}
public class Result
{
public Retail retail { get; set; }
public bool success { get; set; }
}
public class RootObject
{
public Result result { get; set; }
}

Related

Access to class into UserControl (C# WinForms)

I edit my question fo show details. Now it code work, but I wont know, may be I done incorrect architecture?
Main form:
public partial class MainForm1 : Form
{
public MainForm1()
{
InitializeComponent();
string errorMessage = "";
DeviceInitControl.BO.BO_GetParams deviceParams;
SerialPortInitControl.BO.BO_GetParams serialPortParams;
HttpClientInitControl.BO.BO_GetParams httpClientParams;
if (USC_AddDeviceControl.deviceInitParams.GetValues(out deviceParams, ref errorMessage))
{
//Device init
}
else
{
errorMessage = "Device initialisation parametrs error! " + errorMessage;
}
if (USC_AddDeviceControl.serialPortInitParams.GetValues(out serialPortParams, ref errorMessage))
{
//Serial port init
}
else
{
errorMessage = "Serial port initialisation parametrs error! " + errorMessage;
}
if (USC_AddDeviceControl.httpClientInitParams.GetValues(out httpClientParams, ref errorMessage))
{
//Http client init
}
else
{
errorMessage = "Http client initialisation parametrs error! " + errorMessage;
}
if (String.IsNullOrEmpty(errorMessage))
{
//Next step
}
else
{
//Show errorMessage to logs
}
}
}
User control USC_AddDeviceControl contain other UserControls (DeviceInitControl, SerialPortInitControl and HttpClientInitControl).
public partial class SerialPortInitControl : UserControl
{
public class BO
{
public enum BO_Language
{
RUS,
EN
}
public class BO_Init
{
public class CbxItems
{
public string[] names;
public string[] baudRates;
public string[] parities;
public string[] dataBits;
public string[] stopBits;
}
public CbxItems cbxItems = new CbxItems();
}
public class BO_GetParams
{
public string name;
public string baudRate;
public string paritie;
public string dataBits;
public string stopBits;
}
/*
public class BO_SetParams
{
//Some controls in UserControlLibrary can contain it class
}
*/
}
public SerialPortInitControl()
{
InitializeComponent();
}
public void Init(in BO.BO_Language language, in BO.BO_Init initParams) // This methode is public because I can not initialisaion UserControl in constructor, because constructor can not take a parametrs
{
ControlsInit(in initParams);
SetLanguage(in language);
void ControlsInit(in BO.BO_Init controlsParams)
{
CbxInit(in controlsParams.cbxItems); //Some controls in UserControlLibrary can contain TextBox, DataGridView and other
void CbxInit(in BO.BO_Init.CbxItems items)
{
CBX_Name.Items.AddRange(items.names);
CBX_BaudRate.Items.AddRange(items.baudRates);
CBX_Parity.Items.AddRange(items.parities);
CBX_DataBits.Items.AddRange(items.dataBits);
CBX_StopBits.Items.AddRange(items.stopBits);
}
}
}
public void SetLanguage(in BO.BO_Language language)
{
switch (language)
{
case BO.BO_Language.RUS:
{
LBL_Name.Text = "Имя порта";
LBL_BaudRate.Text = "Скорость";
LBL_Parity.Text = "Бит четности";
LBL_DataBits.Text = "Бит данных";
LBL_StopBits.Text = "Стоп бит";
}
break;
case BO.BO_Language.EN:
{
LBL_Name.Text = "Port name";
LBL_BaudRate.Text = "Baud rate";
LBL_Parity.Text = "Parity";
LBL_DataBits.Text = "Data bits";
LBL_StopBits.Text = "Stop bits";
}
break;
default:
{
throw new Exception("Control language is not define!");
}
break;
}
}
public bool GetParams(out BO.BO_GetParams values, ref string errorMessage)
{
if (CheckGetParams(out values, ref errorMessage))
{
values = new BO.BO_GetParams()
{
name = CBX_Name.Text,
baudRate = CBX_BaudRate.Text,
paritie = CBX_Parity.Text,
dataBits = CBX_DataBits.Text,
stopBits = CBX_StopBits.Text,
};
return true;
}
else
{
values = null;
errorMessage = "Checking failed! " + errorMessage;
return false;
}
bool CheckGetParams(out BO.BO_GetParams values, ref string errorMessage)
{
values = new BO.BO_GetParams();
bool valid = true;
if (string.IsNullOrEmpty(CBX_Name.Text)) { valid = false; errorMessage = "Name field is null or empty! "; }
if (string.IsNullOrEmpty(CBX_BaudRate.Text)) { valid = false; errorMessage = "BaudRate field is null or empty! "; }
if (string.IsNullOrEmpty(CBX_Parity.Text)) { valid = false; errorMessage = "Parity field is null or empty! "; }
if (string.IsNullOrEmpty(CBX_DataBits.Text)) { valid = false; errorMessage = "DataBits field is null or empty! "; }
if (string.IsNullOrEmpty(CBX_StopBits.Text)) { valid = false; errorMessage = "StopBits field is null or empty! "; }
return valid;
}
}
/*
public bool SetParams(in BO.BO_SetParams values, ref string errorMessage)
{
if (CheckSetValues(in values, ref errorMessage))
{
return true;
}
else
{
errorMessage = "Checking failed! " + errorMessage;
return false;
}
bool CheckSetParams(in BO.BO_SetParams values, ref string errorMessage)
{
errorMessage = "Methode is not defined! ";
return false;
}
}
*/
}
What you mean correct/modify in this code?
I trying write clear code and need a help for it.
Thank`s!
Your UserControl hasn't instance of BO class. You just define BO class inside SerialPortInitControl, so when you will create instanse of it, it will be like this:
var instBO = new SerialPortInitControl.BO.BO_GetValues()
so, you created object of BO class, but when you stored it in UserConrol?
public partial class SerialPortInitControl : UserControl
{
public class BO
{
public class BO_GetValues
{
public string name;
public string baudRate;
public string paritie;
public string dataBits;
public string stopBits;
}
}
//instance of BO class
public BO BO_Instanse {get;}
//instance of BO.Get_Values class
public BO.BO_GetValues BO_GetValues_Instanse {get;}
public SerialPortInitControl()
{
InitializeComponent();
BO_Instanse = new BO();
BO_GetValues_Instanse = new BO.BO_GetValues();
}
public bool GetValues(out BO.BO_GetValues values, ref string errorMessage)
{
if(BO_Instanse == null)//need real code here
{
values = new BO.BO_GetValues()
{
name = CBX_Name.Text,
baudRate = CBX_BaudRate.Text,
paritie = CBX_Parity.Text,
dataBits = CBX_DataBits.Text,
stopBits = CBX_StopBits.Text,
};
return true;
}
else
{
values = null;
errorMessage = "Checking failed! " + errorMessage;
return false;
}
}
}
So, this will works:
var control = new SerialPortInitControl();
var bo = control.BO_Instanse;
var bo_values = control.BO_GetValues_Instanse;
Also you can create instances of you classes without UserControl class:
var boInstanse = new SerialPortInitControl.BO();
var boGetValues_Instanse = new SerialPortInitControl.BO.BO_GetValues();
public class Personmodel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string NickName { get; set; }
public int Points { get; set; }
public int CurrLevel { get; set; }
public int CurrClass { get; set; }
public List<AvatarPicture> Avatars { get; set; } = new List<AvatarPicture>();
public string FullName
{
get { return $"{ FirstName } { LastName }"; }
}
}

Bad Request from Creating a New Order with Klarna

I'm getting a Bad Request when I'm sending a POST request to the Klarna API to create a new order.
This is my code for sending the POST request:
Cart = new CartManager(_context, HttpContext.Session).GetCart();
Customer = new CustomerManager(HttpContext.Session).GetCustomer()
OrderViewModel order = new OrderViewModel();
order.Reference = DateTime.Now.ToOADate().ToString().Replace(",", string.Empty);
order.Cart = Cart;
order.Customer = Customer;
string url = ApiHelper.KlarnaApiClient.BaseAddress + "checkout/v3/orders";
KlarnaOrderModel klarnaOrderModel = new KlarnaOrderModel
{
purchase_currency = "SEK",
order_amount = (int)order.Cart.TotalCharge,
order_lines = klarnaOrderLines
};
HttpResponseMessage response = await ApiHelper.KlarnaApiClient.PostAsJsonAsync(
url, klarnaOrderModel);
response.EnsureSuccessStatusCode();
KlarnaOrderModel:
public class KlarnaOrderModel
{
public string purchase_country { get { return "SE"; } }
public string purchase_currency { get; set; }
public string locale { get { return "en-GB"; } }
public int order_amount { get; set; }
public int order_tax_amount { get { return 2500; } }
public List<KlarnaOrderLine> order_lines { get; set; }
public KlarnaMerchantUrls merchant_urls { get { return new Models.KlarnaMerchantUrls(); } }
}
KlarnaOrderLine:
public class KlarnaOrderLine
{
public string name { get; set; }
public int quantity { get; set; }
public int unit_price { get; set; }
public int tax_rate { get { return 2500; } }
public int total_amount { get { return unit_price * quantity; } }
public int total_tax_amount { get { return total_amount / 5 ; } }
}
KlarnaMerchantUrls:
public class KlarnaMerchantUrls
{
public string terms { get { return "https://localhost:44316/shop/terms"; } }
public string checkout { get { return "https://localhost:44316/shop/checkout"; } }
public string confirmation { get { return "https://localhost:44316/shop/checkout/confirmation"; }
public string push { get { return "https://localhost:44316/shop/push"; } }
}
Here is a screenshot:
My code for initializing the API:
KlarnaApiClient = new HttpClient();
KlarnaApiClient.BaseAddress = new Uri("https://api.playground.klarna.com/");
KlarnaApiClient.DefaultRequestHeaders.Accept.Clear();
KlarnaApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
KlarnaApiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{MY KLARNA API KEY UID}:{MY KLARNA API KEY PASSWORD}")));

how to write specific C# property value in json format?

I have some Properties and i want to save some specific property value in json format.Here is my code and i want to save two properties value like SelectedScalesModel and SelectedScales port Can anyone help me with this.
public class SetUpViewModel : ViewModelBase
{
public List<string> ScalesModel { get; set; } = new List<string> { "None", "METTLER-TOLEDO", "DINI ARGEO DFW-DFWK", "ESSAE SI-810" };
private string _selectedScalesModel;
public string SelectedScalesModel
{
get { return _selectedScalesModel; }
set
{
_selectedScalesModel = value;
RaisePropertyChanged("SelectedScalesModel");
}
}
public List<string> ScalesPort { get; set; } = new List<string> { "None", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "COM10", "COM11", "COM12", "COM13", "COM14", "COM15" };
private string _selectedScalesPort;
public string SelectedScalesPort
{
get { return _selectedScalesPort; }
set
{
_selectedScalesPort = value;
RaisePropertyChanged("SelectedScalesPort");
}
}
string _text1;
public string BlackLineText
{
get { return _text1; }
set
{
_text1 = value;
RaisePropertyChanged(nameof(BlackLineText));
}
}
public RelayCommand SaveButtonCommand { get; private set; }
public SetUpViewModel()
{
SaveButtonCommand = new RelayCommand(SaveCommand);
}
private void SaveCommand()
{
SetUpViewModel setUpobj = new SetUpViewModel();
string strJsonResult = JsonConvert.SerializeObject(setUpobj);
File.WriteAllText("setup.json", strJsonResult);
MessageBox.Show("File save in Json Format");
}
}
You can try to SerializeObject by anonymous class then carry your expect property instead of SetUpViewModel object.
private void SaveCommand()
{
string strJsonResult = JsonConvert.SerializeObject(
new {
SelectedScalesModel = this.SelectedScalesModel,
SelectedScalesPort = this.SelectedScalesPort
}
);
File.WriteAllText("setup.json", strJsonResult);
MessageBox.Show("File save in Json Format");
}
Note
use this because your property info in your object.

Sharing Object between Views & ViewModels in MVVM

I'm new to WPF + MVVM and have been having trouble getting around viewmodels.
I have a object called FSystem which contains a alot of lists which are populated from a XML.
public class FSystem : ObservableObject
{
public List<FUser> _userList;
public List<FZone> _zoneList;
public List<FSource> _sourceList;
public string _projectName { get; set; }
private string _projectVersion { get; set; }
private string _processorIp { get; set; }
private bool _isMultiLingualModeOn { get; set; }
private int _systemIncludeLighting { get; set; }
private int _systemIncludeWindowsTreatments { get; set; }
private int _systemIncludeSip { get; set; }
private int _systemIncludeCamaras { get; set; }
public FSystem()
{
UserList = new List<FUser>();
}
}
This is the XMLParser which is called when the user loads the XML to the application.
public static class XMLParsers
{
public static FSystem ParseByXDocument(string xmlPath)
{
var fSystem = new FSystem();
XDocument doc = XDocument.Load(xmlPath);
XElement fSystemElement = doc.Element("FSystem");
if (fSystemElement != null)
{
fSystem.ProjectName = fSystemElement.Element("ProjectName").Value;
fSystem.ProjectVersion = fSystemElement.Element("ProjectVersion").Value;
fSystem.ProcessorIp = fSystemElement.Element("ProcessorIP").Value;
fSystem.ProcessorFilePath = fSystemElement.Element("ProcessorFilePath").Value;
fSystem.SystemIncludeLighting = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
fSystem.SystemIncludeSip = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
fSystem.SystemIncludeCamaras = Convert.ToInt16(fSystemElement.Element("SystemIncludeCameras").Value);
}
fSystem.UserList = (from user in doc.Descendants("FUser")
select new FUser()
{
Id = user.Element("Id").Value,
Name = user.Element("Name").Value,
Icon = user.Element("IconColour").Value,
Pin = user.Element("UserPin").Value,
IsPinEnabled = Convert.ToBoolean(Convert.ToInt16(user.Element("UserPinEnabled").Value)),
ListIndex = user.Element("ListIndex").Value
}).ToList();
return fSystem;
}
}
And this is the MainViewModel below is what contains the Commands which Load the XML and the property FSystem I wish to use in other view models.
public class MainViewModel : ViewModel
{
private Fystem fSystem;
public FSystem FSystem
{
get { return fSystem; }
private set
{
fSystem = value;
NotifyPropertyChanged("FSystem");
}
}
public MainViewModel()
{
InitiateState();
WireCommands();
}
private void InitiateState()
{
FSystem = new FSystem();
}
private void WireCommands()
{
XDocumentLoadCommand = new RelayCommand(XDocumentLoad) {IsEnabled = true};
ClearDataCommand = new RelayCommand(ClearData) {IsEnabled = true};
}
public RelayCommand XDocumentLoadCommand { get; private set; }
private void XDocumentLoad()
{
var openDlg = new OpenFileDialog
{
Title = "Open .FAS",
DefaultExt = ".fas",
Filter = "F System Files (*.fas)|*.fas",
Multiselect = false
};
bool? result = openDlg.ShowDialog() == DialogResult.OK;
if (result != true) return;
FSystem = XMLParsers.ParseByXDocument(openDlg.FileName);
}
The application basically lets the user change the different objects (FUser,FZone,FSource, ect). The idea I had was the user would load the XML then be able to edit the different list objects on different views.
What would the correct way be to go about this in MVVM?
I plan to (hopefully) get the User, Zone and Source views to display Datagrids which are populated with their respective data from the Model.
Create you specific view models, and use dependency injection to pass the relevant data into them (this list or that list).
This way, the view models don't need to know about other stuff, and you can easily mock it for testing and for dummy data to see on the designer.
Copy paste into Linqpad for the simplest example. Both mock viewmodels take a dependency (i in our case). You can just pass your lists:
void Main()
{
int someInt = 5;
int anotherInt = 7;
VM vm1 = new VM(someInt);
VM vm2 = new VM(anotherInt);
vm1.RevealI();
vm2.RevealI();
}
public class VM{
private int _i;
public VM(int i)
{
_i = i;
}
public void RevealI() { Console.WriteLine("value of i is: " + _i); }
}
Othen than that, here's more items:
MSDN
Code Project
stack overflow

load json data to wpf datagrid

I want to load json data to my wpf datagrid.
I have followed this tutorial: http://wpf-4-0.blogspot.com/2012/12/how-to-bind-json-data-to-datagrid-in.html
But something is going wrong and I am not sure where is the problem.
my xaml code:
<Button Click="btnLoad_Click" Content="Load" Width="50" Grid.Row="0"></Button>
<DataGrid Grid.Row="1" x:Name="albuminfo" AutoGenerateColumns="True"></DataGrid>
C# code:
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
WebRequest req = WebRequest.Create("http://coderomusic.com/beta/SecuredAdministrator/mobile/getInfo.php?_mod=album");
req.ContentType = "application/json";
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
StreamReader re = new StreamReader(stream);
string json = re.ReadToEnd();
json = "{\"AlbumDetail\":" + json + "}";
Wrapper w = (Wrapper)new JavaScriptSerializer().Deserialize(json, typeof(Wrapper));
albuminfo.ItemsSource = w.albumdetail;
}
AlbumDetail class:
public class AlbumDetail
{
#region//private property
private int albumId;
private string albumName;
private DateTime releasedate;
private int productionId;
private string duration;
private string category;
private string themes;
private ImageBrush coverImage;
private ImageBrush profileImage;
private string description;
private double albumPrice;
private double specialPrice;
private int[] artistIds;
#endregion
#region//public property
public int[] ArtistIds
{
get { return artistIds; }
set { artistIds = value; }
}
public double SpecialPrice
{
get { return specialPrice; }
set { specialPrice = value; }
}
public double AlbumPrice
{
get { return albumPrice; }
set { albumPrice = value; }
}
public string Description
{
get { return description; }
set { description = value; }
}
public ImageBrush ProfileImage
{
get { return profileImage; }
set { profileImage = value; }
}
public ImageBrush CoverImage
{
get { return coverImage; }
set { coverImage = value; }
}
public string Themes
{
get { return themes; }
set { themes = value; }
}
public string Category
{
get { return category; }
set { category = value; }
}
public string Duration
{
get { return duration; }
set { duration = value; }
}
public int ProductionId
{
get { return productionId; }
set { productionId = value; }
}
public DateTime Releasedate
{
get { return releasedate; }
set { releasedate = value; }
}
public string AlbumName
{
get { return albumName; }
set { albumName = value; }
}
public int AlbumId
{
get { return albumId; }
set { albumId = value; }
}
#endregion
}
and Wrapper class:
public class Wrapper
{
public List<AlbumDetail> albumdetail { get; set; }
}
The end result looks like below image:
https://dl.dropboxusercontent.com/u/59201118/json.JPG
(dropbox link because i'm not allowed to post image!)
You should make the web request on a background thread and then update the UI using the dispatcher object. I have modified your code to make it work. Here are the important bits,
private static readonly ManualResetEvent AllDone = new ManualResetEvent(false);
private void BtnLoadClick(object sender, RoutedEventArgs e)
{
var request =
(HttpWebRequest)
WebRequest.Create("http://coderomusic.com/beta/SecuredAdministrator/mobile/getInfo.php?_mod=album");
request.ContentType = "application/json";
request.BeginGetResponse(GetResponseCallback, request);
AllDone.WaitOne();
}
private void GetResponseCallback(IAsyncResult ar)
{
var request = (HttpWebRequest) ar.AsyncState;
var response = (HttpWebResponse) request.EndGetResponse(ar);
Stream stream = response.GetResponseStream();
Wrapper w = null;
if (stream != null)
{
var re = new StreamReader(stream);
string json = re.ReadToEnd();
w = (Wrapper) new JavaScriptSerializer().Deserialize(json, typeof (Wrapper));
}
Dispatcher.BeginInvoke(
new Action(() => {
if (w != null)
albuminfo.ItemsSource = new ObservableCollection<AlbumDetail>(w.AlbumDetail);
}));
response.Close();
AllDone.Set();
}
Change it to suit your needs. I hope it works.
Simple and easy way use jsonorm from nuget and create a data layer from received json by (http://json2csharp.com/)

Categories