C# loading grid with json - c#

I'm trying to load a grid with json that I receive. This is my code in Home.cs:
private void getTickets()
{
try
{
string urlName = "tickets";
string method = "GET";
string json = null;
HttpStatusCode statusCode = HttpStatusCode.Forbidden;
Tickets data = null;
RestClient client = RequestClient.makeClient();
MakeRequest request = new MakeRequest(null, null, urlName, method);
IRestResponse response = client.Execute(request.exec());
statusCode = response.StatusCode;
json = response.Content;
var ticketWrapper = JsonConvert.DeserializeObject<TicketWrapper>(json);
if ((int)statusCode == 200)
{
gridTicket.DataSource = ticketWrapper.tickets;
}
else
{
MessageBox.Show("error");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Ticket wrapper class
class TicketWrapper
{
public IEnumerable<Tickets> tickets { get; set; }
}
Tickets class
class Tickets
{
public int id;
public string title;
public string description;
public int user_id;
public int subject_id;
}
If I debug I can see that I receive the json but ticketWrapper is null what could be wrong here?
Debug image:

Try to change public fields in Ticket class to properties:
class Tickets
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public int user_id { get; set; }
public int subject_id { get; set; }
}
Also I think that IEnumerable is not the best option for serialization. Try to use List in TicketWrapper.
Additionally move your break point down, because in current position ticketWrapper will be always null (expression has not yet been executed).

Related

Received Model is empty in the controler after post

I have one API in my webservice App that receives an empty model after the post.
This is the code in my testclient that calls the API
private async void AddDriverPayment()
{
ModelPalmDriverPaymentRequest modelPalmDriverPaymentRequest = new ModelPalmDriverPaymentRequest()
{
SCS_ID = int.Parse(gttDXTextEditAddDriverPaymentSCS_ID.Text),
DriverID = int.Parse(gttDXTextEditAddDriverPaymentDriverID.Text),
Amount = decimal.Parse(gttDXTextEditAddDriverPaymentAmount.Text),
Remark = gttDXTextEditAddDriverPaymentRemark.Text,
PaymentType = gttDXTextEditAddDriverPaymentPaymentType.Text,
PaymentYear = int.Parse(gttDXTextEditAddDriverPaymentPaymentYear.Text),
PaymentWeek = int.Parse(gttDXTextEditAddDriverPaymentPaymentWeek.Text),
DocumentPath = gttDXTextEditAddDriverPaymentDocumentPath.Text,
DatePayment = dateTimePickerAddDriverPayment.Value
};
string JsonData = JsonConvert.SerializeObject(modelPalmDriverPaymentRequest);
System.Net.Http.StringContent restContent = new StringContent(JsonData, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
try
{
var response = await client.PostAsync(comboBoxEditPalmAddDriverPayment.Text, restContent);
if (response.IsSuccessStatusCode)
{
var stream = await response.Content.ReadAsStringAsync();
ModelPalmDriverPaymentResponse Result = JsonConvert.DeserializeObject<ModelPalmDriverPaymentResponse>(stream);
textBoxAddDriverPaymentResult.Text = Result.SCS_ID.ToString() + " " + Result.PaymentID.ToString();
}
else
{
textBoxAddDriverPaymentResult.Text = response.StatusCode + " " + response.ReasonPhrase;
}
}
catch (Exception ex)
{
textBoxAddDriverPaymentResult.Text = ex.Message;
}
}
And this is the controller code in the webservice
[Route("palm/AddDriverPayment")]
[ApiController]
public class ControllerPalmDriverPayment : ControllerBase
{
private readonly RepositoryPalmDriverPayment _repositoryPalmDriverPayment = new();
[HttpPost]
public IActionResult AddDriverPayment(ModelPalmDriverPaymentRequest modelPalmDriverPaymentRequest)
{
try
{
return base.Ok(_repositoryPalmDriverPayment.AddDriverPaymemnt(modelPalmDriverPaymentRequest));
}
catch (System.Exception)
{
return base.BadRequest("Nope not working...");
}
}
}
The model looks like this (I copied the model class from the service into the client, so I am sure they are exact the same)
public class ModelPalmDriverPaymentRequest
{
public int SCS_ID;
public int DriverID;
public decimal Amount;
public string? Remark;
public string? PaymentType;
public int PaymentYear;
public int PaymentWeek;
public string? DocumentPath;
public DateTime DatePayment;
}
When I try the code, I can see in debug of the testclient that when I post the data, the model is correct filled,
but then I can see in debug on the webservice that the received model is empty
I have other API's in this webservice that I test with the same client, they all do not have this problem.
I found this question but the answers don't help me
Anybody has any idea what the problem here is ?
EDIT
I found the problem, and wrote it in an answer so anybody with the same problem can find it.
Specify Content-Type: application/json on the client side or use the [FromBody] attribute on your ModelPalmDriverPayemntRequest parameter on the controller method.
More details about FromBody attribute here
I have it working now, the problem was I forgot to provide getters and setters in the model
So once I changed this
public class ModelPalmDriverPaymentRequest
{
public int SCS_ID;
public int DriverID;
public decimal Amount;
public string? Remark;
public string? PaymentType;
public int PaymentYear;
public int PaymentWeek;
public string? DocumentPath;
public DateTime DatePayment;
}
into this
public class ModelPalmDriverPaymentRequest
{
public int SCS_ID { get; set; }
public int DriverID { get; set; }
public decimal Amount { get; set; }
public string Remark { get; set; }
public string PaymentType { get; set; }
public int PaymentYear { get; set; }
public int PaymentWeek { get; set; }
public string DocumentPath { get; set; }
public DateTime DatePayment { get; set; }
}
It worked again

My xamarin app freezes when i try JsonConvert.DeserializeObject <T>

When I get a json response from HttpClient () and try to deselize, my Xamarin application freezes (UI works, but the code after in class ExecuteGetRequest line 15 does not work). What can it be because of?
No errors.
I call the method of obtaining a list of anime user
ShikimoriMain shikimoriMain = new ShikimoriMain();
var UserInformation = await shikimoriMain.GetUserInformation(Convert.ToInt64(UserID));
var UserAnimeList = await shikimoriMain.GetUserAnimeList(Convert.ToInt64(UserID), 1, 5);
string animeName = UserAnimeList.Anime[0].Anime.Name;
ShikimoriMain.GetUserAnimeList
public async Task<ShikimoriUserAnimeList> GetUserAnimeList(long id, int page, int limit)
{
string[] args = new string[] { ShikimoriCategories.UserID + "/" + id + ShikimoriCategories.UserAnimeList + $"?limit={limit}&page={page}" };
return await ExecuteGetRequest<ShikimoriUserAnimeList>(args);
}
ExecuteGetRequest
public async Task<T> ExecuteGetRequest<T>(string[] args) where T : class
{
T returnedObject;
using (var client = new HttpClient())
{
// client.BaseAddress = new Uri($"{httpApiv1}/{args}");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, httpApiv1 + String.Join("/", args));
request.Headers.TryAddWithoutValidation("User-Agent", "Search Anime");
HttpResponseMessage responseMessage = await client.SendAsync(request);
string json = await responseMessage.Content.ReadAsStringAsync(); // successfully get json
returnedObject = JsonConvert.DeserializeObject<T>(json); // after that the code is not executed
return returnedObject;
}
}
ShikimoriUserAnimeList
public class ShikimoriUserAnimeList
{
[JsonProperty()]
public List<GetAnime> Anime { get; set; }
}
public class GetAnime
{
[JsonProperty("id")]
public int ID { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("anime")]
public Anime Anime { get; set; }
}
public class Anime
{
[JsonProperty("id")]
public int ID { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("russian")]
public string NameRU { get; set; }
[JsonProperty("image")]
public AnimeImage AnimeImage { get; set; }
[JsonProperty("kind")]
public string King { get; set; }
[JsonProperty("score")]
public string Score { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("episodes")]
public int Episodes { get; set; }
}
public class AnimeImage
{
[JsonProperty("original")]
public string Original { get; set; }
[JsonProperty("preview")]
public string Preview { get; set; }
[JsonProperty("x96")]
public string ImageX96 { get; set; }
[JsonProperty("x48")]
public string ImageX48 { get; set; }
}
For the sake of completion:
An error was being thrown but was not visible in the device log. Wrapping the JsonConvert.DeserializeObject<T>(json) in a try catch block helped finding the Exceptionbeing thrown.
try
{
returnedObject = JsonConvert.DeserializeObject<T>(json); // after that the code is not executed
return returnedObject;
}
catch (Exception ex)
{
... (debug and fix the error that occurred)
}
I had same problem, I've realized that using HttpClient async will cause deadlock in winforms or xamarin (however it works well with Asp) and I changed these lines
HttpResponseMessage responseMessage = await client.SendAsync(request);
string json = await responseMessage.Content.ReadAsStringAsync(); // successfully get json
Like these (Make them work synchronous):
HttpResponseMessage responseMessage = client.SendAsync(request).Result;
string json = responseMessage.Content.ReadAsStringAsync().Result; // successfully get json
And change your method as default synchronous
Take a look at Here

Restsharp error on deserialzation when nested value is null

I'm running into an error when a nested value is null. If the value is not null everything works as expected. This does not happen if the value is not nested.
The error is:
InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.
The error happens when I'm checking response.ErrorException != null on the List Contract
Json returned: Contract administrator is nested and blank error: ends is not nested blank and no error:
"result": [
{
"sys_id": "06dc3133db1747808c47499e0b96192e",
"number": "CNTR001234",
"short_description": "Contract 123",
"u_internal_contact": {
"link": "https://website",
"value": "5b4080490a0a3c9e016cb2a9f4eb57b1"
},
"vendor": {
"link": "https://website",
"value": "b7e7c073c0a801690143e7b7d29eb408"
},
"ends": "",
"payment_amount": "60000",
"u_status": "Active",
"starts": "2018-01-01",
"contract_administrator": ""
}
]
}
Code
public class Results
{
public List<Contract> items { get; set; }
}
public class Contract
{
public string sys_id { get; set; }
public string number { get; set; }
public string short_description { get; set; }
public string ends { get; set; }
public string payment_amount { get; set; }
public string u_status { get; set; }
public string starts { get; set; }
public Vendor vendor { get; set; }
public ContractAdmin contract_administrator { get; set; }
public InternalContact u_internal_contact { get; set; }
}
public class Vendor
{
public string link { get; set; }
public string value { get; set; }
}
public class ContractAdmin
{
public string link { get; set; }
public string value { get; set; }
}
public class InternalContact
{
public string link { get; set; }
public string value { get; set; }
}
public class refResults
{
public List<refName> itemName { get; set; }
}
public class refName
{
public string name { get; set; }
}
class ImportContracts
{
public static void ProcessImport()
{
RestClient contractsRequest = new RestClient(Properties.Settings.Default.RestURL);
contractsRequest.Authenticator = new HttpBasicAuthenticator(Properties.Settings.Default.userName, Properties.Settings.Default.password);
contractsRequest.AddHandler("application/json", new RestSharp.Deserializers.JsonDeserializer());
RestRequest request = new RestRequest();
request.RootElement = "result";
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
IRestResponse<List<Contract>> response = contractsRequest.Execute<List<Contract>>(request);
Console.WriteLine(response.Content);
if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var ex = new ApplicationException(message, response.ErrorException);
throw ex;
}
foreach (Contract contract in response.Data)
{
//Console.WriteLine(contract.sys_id);
string strVendor = GetName(contract.vendor.link.ToString());
string strInternalContact = GetName(contract.u_internal_contact.link.ToString());
string strContractAdmin = GetName(contract.contract_administrator.ToString());
}
}
static public string GetName (string link)
{
RestClient nameRequest = new RestClient(link);
nameRequest.Authenticator = new HttpBasicAuthenticator(Properties.Settings.Default.userName, Properties.Settings.Default.password);
nameRequest.AddHandler("application/json", new RestSharp.Deserializers.JsonDeserializer());
RestRequest requestedName = new RestRequest();
requestedName.RootElement = "result";
requestedName.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
IRestResponse<List<refName>> response = nameRequest.Execute<List<refName>>(requestedName);
if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var ex = new ApplicationException(message, response.ErrorException);
throw ex;
}
foreach (refName refname in response.Data)
{
return refname.name;
}
return "name not found";
}
}
Any help would be appreciated!
Looking at your JSON, "contract_administrator" is not null, it's an empty string. Your contract requires a ContractAdmin object, so what it's likely doing is attempting to cast an empty string to a ContractAdmin.
If you change "contract_administrator" to be null instead of an empty string, I'm willing to bet that it will parse correctly.

StatusCode: 401, ReasonPhrase: 'Unauthorized' gets displayed when calling a Post Method through HTTPClient using C#

I am trying to access an API's Post method through HTTP Client and passing the AuthToken. When I tried to access in post man I am able to get the response, but when I ran in C#, I got StatusCode: 401, ReasonPhrase: 'Unauthorized' error. I am sharing the request and Response screens of Postman along with my code. can anyone let me know the mistake which i did in the code and how to solve the issue.
Postman Request Header and Response Body
Postman Request Body
below is my C# code.
public class PostEmpData
{
public string cExternalGUID = "10134",
cEmployeeID = "10134", cLastName = "Anderson", cFirstName = "Derek", cAccessGroup = "", cActive = "A";
public int nCardNumber = 10134, nPayMethod = 2;
public string[] cGroupsList = new string[0] { };
public DateTime dHireDate = DateTime.Parse("1999 / 11 / 03"), dTermDate = DateTime.Parse("01 / 01 / 0001"), dRateEffectiveDate = DateTime.Parse("2017 - 07 - 15");
public decimal nPayRate = 1500;
}
public class PostEmployeeClass
{
public int _interfaceID { get; set; }
public int _errorCode { get; set; }
public string _errorDescription { get; set; }
public List<EmpPostResponse> respList;
}
public class EmpPostResponse
{
public string RetKey { get; set; }
public int ErrorCode { get; set; }
public string Description { get; set; }
public string Success { get; set; }
public string SecondaryList { get; set; }
}
static async Task<List<EmpPostResponse>> CallPostEmployeeAsync(object postdata)
{
Console.WriteLine("Post Employee Process Started");
PostEmployeeClass authclass = null;
List<EmpPostResponse> data = null;
HttpResponseMessage response = await client.PostAsJsonAsync("xxxxxxV2/api/ED907F98-9132-4C7D-B4D4-7648A2577F6D/Integration/employees", postdata);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
Console.WriteLine("success");
authclass = await response.Content.ReadAsAsync<PostEmployeeClass>();
data = authclass.respList;
}
else
Console.WriteLine("fail:" + response.StatusCode.ToString());
return data;
}
static void Main(string[] args)
{
Console.WriteLine("Starting the Process");
RunAsync().Wait();
}
static async Task RunAsync()
{
PostEmpData objPost = new PostEmpData();
client.BaseAddress = new Uri("https://xxxx.xxxxx.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
string AuthToken="XXXXXXXXXXXXX";
client.DefaultRequestHeaders.Add("AuthToken", AuthToken);
Console.WriteLine(AuthToken);
var postdata = CallPostEmployeeAsync(objPost);
}catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
I've reviewed your code and there are a few things that I noticed.
One thing that is not going to work: PostEmpData will serialize into an empty object as it contains no properties. So the body will be something like: {}. You will need to add properties to the class:
public class PostEmpData
{
public string cExternalGUID { get; set; } = "10134";
public string cEmployeeID { get; set; } = "10134";
public string cLastName { get; set; } = "Anderson";
public string cFirstName { get; set; } = "Derek";
public string cAccessGroup { get; set; } = "";
public string cActive { get; set; } = "A";
public int nCardNumber { get; set; } = 10134;
public int nPayMethod { get; set; } = 2;
public string[] cGroupsList { get; set; }= new string[0] { };
public DateTime dHireDate { get; set; }= DateTime.Parse("1999 / 11 / 03");
public DateTime dTermDate { get; set; }= DateTime.Parse("01 / 01 / 0001");
public DateTime dRateEffectiveDate { get; set; }= DateTime.Parse("2017 - 07 - 15");
public decimal nPayRate { get; set; }= 1500;
}
There is a good chance that this causes the unauthorized response. And that it may have nothing to do with the token.
And there is also another difference compared to the Postman request. With Postman you send an array of object [{}], but with code you send one object. So you may have to post a list of PostEmpData.

How to connect to XML-RPC from c#

How to connect to XML-RPC Api from c# ,
A client can interact with a Pandorabot by POST'ing to:
http://www.pandorabots.com/pandora/talk-xml
The form variables the client needs to POST are:
botid - see H.1 above.
input - what you want said to the bot.
custid - an ID to track the conversation with a particular customer. This variable is optional. If you don't send a value Pandorabots will return a custid attribute value in the element of the returned XML. Use this in subsequent POST's to continue a conversation.
How to call?
This should get you going:
public void Talk()
{
string xmlResult = null;
Result result = null; // Result declared at the end
string botId = "c49b63239e34d1"; // enter your botid
string talk = "Am I a human?";
string custId = null; // (or a value )
using (var wc = new WebClient())
{
var col = new NameValueCollection();
col.Add("botid", botId);
col.Add("input", talk);
if (!String.IsNullOrEmpty(custId))
{
col.Add("custid", custId);
}
byte[] xmlResultBytes = wc.UploadValues(
#"http://www.pandorabots.com/pandora/talk-xml",
"POST",
col);
xmlResult = UTF8Encoding.UTF8.GetString(xmlResultBytes);
result = Result.GetInstance(xmlResultBytes);
}
//raw result
Console.WriteLine(xmlResult);
// use the Result class
if (result.status == 0) // no error
{
Console.WriteLine("{0} -> {1}",
result.input, result.that);
}
else // error
{
Console.WriteLine("Error: {0} : {1}",
result.input, result.message);
}
}
[XmlRoot(ElementName="result")]
public class Result
{
static XmlSerializer ser = new XmlSerializer(typeof(Result) , "");
public Result()
{
}
public static Result GetInstance(byte[] bytes)
{
return (Result)ser.Deserialize(new MemoryStream(bytes));
}
[XmlAttribute]
public int status { get; set; }
[XmlAttribute]
public string botid { get; set; }
[XmlAttribute]
public string custid { get; set; }
[XmlElement]
public string input { get; set; }
[XmlElement]
public string that { get; set; }
[XmlElement]
public string message { get; set; }
}

Categories

Resources