Here is the GET REQUEST
var destname = textBox1.Text;
var client1 = new RestClient("https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/autosuggest/v1.0/UK/GBP/en-GB/?query=" + destname);
var request1 = new RestRequest(Method.GET);
request1.AddHeader("x-rapidapi-key", "");
request1.AddHeader("x-rapidapi-host", "skyscanner-skyscanner-flight-search-v1.p.rapidapi.com");
IRestResponse response1 = client1.Execute(request1);
var results = JsonConvert.DeserializeObject<DestinationName>(response1.Content);
And here is the classes
public partial class Place1
{
public string PlaceId { get; set; }
public string PlaceName { get; set; }
public string CountryId { get; set; }
public string RegionId { get; set; }
public string CityId { get; set; }
public string CountryName { get; set; }
}
public partial class DestinationName
{
public List<Place1> Places { get; set; }
}
When I do what is below I should be getting ES-sky which is the first element of the list but for some reason it gives me the last element of the list.
foreach (var a in results.Places)
{
label1.Text = a.PlaceId;
}
Here is the list
ES-sky
BCN-sky
ALC-sky
AGP-sky
MAD-sky
PMI-sky
IBZ-sky
TENE-sky
TFS-sky
TFN-sky
How would I adapt the code so that my output is ES-sky and not TFN-sky.
You are looping through the list, every time its writing value to "label1.Text". Use SingleOrDefault()/FirstOrDefault(). Dont use foreach loop.
Example:
var firstValue=results.Places.FirstOrDefault();
label1.Text = firstValue.PlaceId;
Instead of iterating through the loop here:
foreach (var a in results.Places)
{
label1.Text = a.PlaceId;
}
Just get the first value with appropriate validation:
if(results.Places != null && results.Places.Any())
{
var result = results.Places.First();
label1.Text = a.PlaceId;
}
You can bind only first place data in list from server side and get it on client side OR
bind FirstorDefault method to get first place data from list in client side.
I created a simple RESTful application in WCF(c#). When I'm populating using (GET) I've received this error
"Object reference not set to an instance of an object".
I received the error in the part of target.DocumentLines[0].itemCode = "";.
Here's my code:
public PRRequestData[] getAllPR()
{
List<PRRequestData> list = new List<PRRequestData>();
try
{
string sqlSelect = "SELECT DocEntry, Comments, ReqDate FROM OPRQ";
APP.strCommand = sqlSelect;
DataTable dt = new DataTable();
dt = APP.Ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
// Person target = Activator.CreateInstance();
PRRequestData target = new PRRequestData();
target.requiredDate = row["ReqDate"].ToString();
target.remarks = row["Comments"].ToString();
target.docEntry = row["DocEntry"].ToString();
// DataColumnAttribute.Bind(row,target);
sqlSelect = "SELECT ItemCode, Quantity, Price, VendorNum, TaxCode FROM PRQ1 WHERE DocEntry = '" + row["DocEntry"].ToString() + "' ";
APP.strCommand = sqlSelect;
for (var i = 0; i < APP.Ds.Tables[0].Rows.Count; i++)
{
target.DocumentLines[0].itemCode = "";
}
list.Add(target);
}
return list.ToArray();
}
catch (Exception e)
{
e.ToString();
}
return list.ToArray();
Here's my DataContract source code also:
[DataContract(Namespace = "")]
public class PRRequestData
{
[DataMember]
public string docEntry { get; set; }
[DataMember]
public string remarks { get; set; }
[DataMember]
public string requiredDate { get; set; }
//[DataMember]
//public int rowcount { get; set; }
[DataMember]
public RequestDataDetails[] DocumentLines;
}
[DataContract]
public class RequestDataDetails
{
[DataMember]
public string itemCode { get; set; }
[DataMember]
public decimal quantity { get; set; }
[DataMember]
public decimal price { get; set; }
[DataMember]
public string supplier { get; set; }
[DataMember]
public string taxcode { get; set; }
}
Looks like you're not initialising this property
[DataMember]
public RequestDataDetails[] DocumentLines;
I recommend you to use List instead of RequestDataDetails[], as anyway you'll have to use an internal list.
Initialise the List of RequestDataDetails to fill it from the query, before the for loop.
List<RequestDataDetails> requestDetails = new List<RequestDataDetails>
Then change the for loop to add to that list instead of setting an array, im using the assignment you were doing, not sure if it'll do what you expect, just tell me if it suits your needs.
requestDetails.add(new RequestDataDetails { itemCode = "" });
instead of
target.DocumentLines[0].itemCode = "";
Then after the for loop convert the list to an array and assign it to target
target.DocumentLines = requestDetails.ToArray();
Hope it works!
I'm currently working on parsing a csv file that was exported by another application. This application exported the data in a strange way. This export is from accoutning and it looks similar to this..
I'm trying to figure out a way to read the csv file, then split up the multiple 'All Accounts' values and 'Amt' Values so that M200 and 300.89 is another entry, M300 and 400.54 are another entry, and M400 and 100.00 are another entry. So after inserting this single row into the database, I should actually have 4 rows like so..
This is how I'm currently reading and inserting into the database.
List<RawData> data = new List<RawData>();
try
{
string text = File.ReadAllText(lblFileName.Text);
string[] lines = text.Split('\n');
int total = 0, reduced = 0;
foreach (string line in lines)
{
RawData temp = new RawData(line);
total++;
if (!(temp.FirstAccount.Length == 0 || temp.FirstAccount == "1ST-ACCT-NO"))
{
reduced++;
data.Add(temp);
}
}
}
catch (IOException ex)
{
Console.WriteLine("Unable to read file. " + ex.ToString());
MessageBox.Show(ex.ToString());
}
try
{
foreach (RawData rData in data)
{
tCarsInTransit cit = new tCarsInTransit
{
FIRST_ACCT_NO = rData.FirstAccount,
ACCOUNT_NO_DV = rData.AccountNoDv,
ACCT_NO = rData.AcctNo,
ACCT_NO_L = rData.AccNoL,
ACCT_NUM_DV = rData.AcctNumDv,
ACCT_PFX = rData.AcctPfx,
ACCT_PFX_PRT = rData.AcctPfxPrt,
ACCT_TYPE_DV = rData.AcctTypeDv,
ADV_NO = rData.AdvNo,
ALL_PRT_FLAG = rData.AllPrtFlag,
AMT = rData.Amt,
AMT_GLE = rData.AmtGle,
BASE_GLE = rData.BaseGle,
CNT_CAT = rData.CntCat,
COLD_PRT_FLAG = rData.ColdPrtFlag,
COST_DV = rData.CostDv,
COST_OVRD_FLAG_DV = rData.CostOvrdFlagDv,
CR_ACCT_DV = rData.CrAcctDv,
CR_ACCT_DV_GLE = rData.CrAcctDvGle,
CROSS_POSTING_FLAG = rData.CrossPostingFlag,
CROSS_POST_CAT = rData.CrossPostCat,
CTRL_NO = rData.CtrlNo,
CTRL_TYPE_DV = rData.CtrlTypeDv,
DESC_REQD_DV = rData.DescReqdDv,
DR_ACCT_DV = rData.DrAcctDv,
GL_DIST_ACCT_DV = rData.GLDistAcctDv,
GL_DIST_DV = rData.GLDistDv,
GRP_NO_DV = rData.GrpNoDv,
ID_PORT_DATE_TIME_FMT_CAT = rData.IdPortDateTimeFmtCat,
INACTIVITY_DV = rData.InactivityDv,
JOIN_COL = rData.JoinCol,
JRNL_DATE = rData.JrnlDate,
JRNL_PFX = rData.JrnlPfx
};
tCIT.tCarsInTransits.Add(cit);
tCIT.SaveChanges();
lblMessage.ForeColor = System.Drawing.Color.Green;
lblMessage.Text = "Finished uploading. ";
}
}
catch (DbEntityValidationException ex)
{
foreach (var eve in ex.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
I am not sure how to accomplish this. The above currently inserts the csv file into Sql Server the exact way the csv file was exported. Any ideas would greatly be appreciated! Thanks!
EDIT: Here is the RawData class.
class RawData
{
public string FirstAccount { get; set; }
public string AccountNoDv { get; set; }
public string AcctNo { get; set; }
public string AccNoL { get; set; }
public string AcctNumDv { get; set; }
public string AcctPfx { get; set; }
public string AcctPfxPrt { get; set; }
public string AcctTypeDv { get; set; }
public string AdvNo { get; set; }
public string AllPrtFlag { get; set; }
public string Amt { get; set; }
public string AmtGle { get; set; }
public string BaseGle { get; set; }
public string CntCat { get; set; }
public string ColdPrtFlag { get; set; }
public string CostDv { get; set; }
public string CostOvrdFlagDv { get; set; }
public string CrAcctDv { get; set; }
public string CrAcctDvGle { get; set; }
public string CrossPostingFlag { get; set; }
public string CrossPostCat { get; set; }
public string CtrlNo { get; set; }
public string CtrlTypeDv { get; set; }
public string DescReqdDv { get; set; }
public string DrAcctDv { get; set; }
public string GLDistAcctDv { get; set; }
public string GLDistDv { get; set; }
public string GrpNoDv { get; set; }
public string IdPortDateTimeFmtCat { get; set; }
public string InactivityDv { get; set; }
public string JoinCol { get; set; }
public string JrnlDate { get; set; }
public string JrnlPfx { get; set; }
public RawData(string csvString)
{
string[] citData = csvString.Replace(", ", "").Replace(".,", ".").Split(',');
try
{
FirstAccount = citData[0];
AccountNoDv = citData[1];
AcctNo = citData[2];
AccNoL = citData[3];
AcctNumDv = citData[4];
AcctPfx = citData[5];
AcctPfxPrt = citData[6];
AcctTypeDv = citData[7];
AdvNo = citData[8];
AllPrtFlag = citData[9];
Amt = citData[10];
AmtGle = citData[11];
BaseGle = citData[12];
CntCat = citData[13];
ColdPrtFlag = citData[14];
CostDv = citData[15];
CostOvrdFlagDv = citData[16];
CrAcctDv = citData[17];
CrAcctDvGle = citData[18];
CrossPostingFlag = citData[19];
CrossPostCat = citData[20];
CtrlNo = citData[21];
CtrlTypeDv = citData[22];
DescReqdDv = citData[23];
DrAcctDv = citData[24];
GLDistAcctDv = citData[25];
GLDistDv = citData[26];
GrpNoDv = citData[27];
IdPortDateTimeFmtCat = citData[28];
InactivityDv = citData[29];
JoinCol = citData[30];
JrnlDate = citData[31];
JrnlPfx = citData[32];
}
catch (Exception ex)
{
Console.WriteLine("Something went wrong. " + ex.ToString());
}
}
}
EDIT 2: AllAccounts in the images is acutally 'AccountNoDv' and there are actually many different fields that have multiples like 'AccountNoDv'(AllAccounts) but we might be removing those as this is not a final export. As of right now the two fields I'm worried most about are AccountNoDv and Amt.
Try something like this:
foreach (string line in lines)
{
RawData temp = new RawData(line);
var AllAccounts = temp.AccountNoDv.split(' ');
var Amts = temp.Amt.split(' ');
if (AllAccounts.Length() == Amts.Length() && Amts.Length() > 1) {
// We have multiple values!
reduced++;
for (int i = 0; i < AllAccounts.Length(); i++) {
RawData temp2 = RawDataCopy(temp); // Copy the RawData object
temp2.AccountNoDv = AllAccounts[i];
temp2.Amt = Amts[i];
total++;
data.Add(temp2);
}
}
else {
total++;
if (!(temp.FirstAccount.Length == 0 || temp.FirstAccount == "1ST-ACCT-NO"))
{
reduced++;
data.Add(temp);
}
}
}
And:
private RawData RawDataCopy(RawData copyfrom) {
// Write a function here that returns an exact copy from the one provided
// You might have to create a parameterless constructor for RawData
RawData RawDataCopy = new RawData();
RawDataCopy.FirstAccount = copyfrom.FirstAccount;
RawDataCopy.AccountNoDv = copyfrom.AccountNoDv;
RawDataCopy.AcctNo = copyfrom.AcctNo;
// . . . . . . . .
RawDataCopy.JrnlPfx = copyfrom.JrnlPfx;
return RawDataCopy;
}
Then also add a parameterless constructor to your RawData class:
public RawData()
{
}
Perhaps it would be sexier to implement the ICloneable interface and call the Clone() function instead of the RawDataCopy function, but it gets the idea across.
In Linq you can use SelectMany to increase the number of elements in a list. Here is a rough example of how this could be done. I make the assumption that the number of sub elements in AllAccounts and Amt is the same. A more robust solution would check for these issues.
So after you have loaded your data list:
var expandedData =
data.SelectMany(item =>
// split amount (will just return one item if no spaces)
item.Amt.Split(" ".ToCharArray())
// join this to the split of all accounts
.Zip(item.AllAccounts.Split(" ".ToCharArray()),
// return the joined item as a new anon object
(a,b) => new { amt=a, all=b }),
// take the original list item and the anon object and return our new item
(full,pair) => { full.Amt = pair.amt; full.AllAccounts = pair.all; return full; }));
You will now have a list of your data items with the multiple items expanded into the list.
I don't have test data to test so I might have some minor typos -- but I put in lots of comments to make the Linq as clear as possible.
Here is is simple example I wrote in LinqPad for myself to make sure I understood how SelectMany worked:
string [] list = { "a b c d","e","f g" };
var result = list.SelectMany((e) =>
e.Split(" ".ToCharArray()),
(o,item) => new { org = o, item = item}).Dump();
I have returned some odata data to a c# client using:
Uri uri = new Uri("testserver/WebApi/odata");
var container = new CourseService.Container(uri);
How do I convert the data into a list?
The returned data is a list of courses:
public partial class Course
{
public string Name { get; set; }
public string Description { get; set; }
public string Guid { get; set; }
}
here's a sample code for you.
List<Course> CourseList = new List<Course>();
foreach (var item in container)
{
Course obj = new Course();
obj.Name = item.Name;
obj.Description = item.Description;
obj.Guid = item.Guid;
CourseList.Add(obj);
}
I am attaching Class Detail as my DataSource to the report;
class Detail
{
public string Name { get; set; }
public string State { get; set; }
public string City { get; set;}
public List<Transaction> tran { get; set; }
}
class Transaction
{
public string TransactionDate { get; set; }
public string TransactionDescription { get; set; }
}
and in my query i send it as List.
public List GetAccount(string account) {
List detail = new List();
sql ....
foreach (DataRow dr in dt.Rows)
{
detail.Add(new Detail()
{
Name= dr["name"].Equals(DBNull.Value) ? string.Empty : dr["name"].ToString(),
.....
tran = GetTransactionDetail(account)// calling a list
});
}
return detail;
}
public List<Transaction> GetTransactionDetail(string account)
{
....
}
and at the Form1.cs
XtraReport1 rep = new XtraReport1();
printControl1.PrintingSystem = rep.PrintingSystem;
var ls = query.GetAccount(accountNo);
rep.DataSource = ls;
rep.CreateDocument();
in the report i should get a list of transaction details but i get only the first row.
thanks,
It depends how your report is designed. Usually you need a separate band (DetailReport) for all of the details to be visible (if you're using XRTable).
Sir you should use DataSet and query.GetAccount(accountNo) returns DataTable
Then try like this. It works for me.
XtraReport1 rep = new XtraReport1();
printControl1.PrintingSystem = rep.PrintingSystem;
var ds = new ds("TestDataSet");
var ls = query.GetAccount(accountNo);
ds.Tables.Add(ls);
rep.DataSource = ds;
rep.DataMember = ls.TableName;
rep.CreateDocument();