I am trying to create a list via array like this:
private Application[] GetApps()
{
DataSet ds = new Dataset();
string query = "query";
ds = GetData(query);
var appList = new Application[ds.Tables[0].Rows.Count];
for(var i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
DataRow item = ds.Tables[0].Rows[i];
appList[i].Name = item["Name"].ToString();
appList[i].Confidentiality = int.Parse(item["Conf"].ToString());
appList[i].Id = item["ID"].ToString();
}
return appList;
}
I keep getting an object null error and I know I have to be missing something completely obvious that I'm just not seeing. Do I need to declare the new array in some other way?
When you create appList, you are only creating the array itself. .NET does not automatically populate the array with Application objects for you to manipulate. You need to create a new Application object, and set the properties on that object, then you can assign the object to the array.
There are multiple Application classes withing the .NET framework, none of which seem to match your code, so the below example will simply assume that Application is a custom type of your own design.
for(var i = 0; i < ds.Tables[0].Rows.Count; i++)
{
DataRow item = ds.Tables[0].Rows[i];
Appliction app = new Application();
app.Name = item["Name"].ToString();
app.Confidentiality = int.Parse(item["Conf"].ToString());
app.Id = item["ID"].ToString();
appList[i] = app
}
As an aside, note that you can replace i <= x - 1 with i < x and the behavior is exactly the same.
Finally, you should introduce checks for all of your accessors if there is a chance that they could return null. For example, if item["Name"] returns null, then calling item["Name"].ToString() is equivelant to calling null.ToString(), which will also result in a NullReferenceException.
Related
as you can see I have ten team in my database, and here's my code, now I want to generate randomly matches in asp.net C#
in this code the problem is that "d" is a list and the return type of Data is object,
the the picture of error is below.
note in database team_id and team_name in relation when you call team id team_name will be show or call.
function is in service and service is calling in controller.
[HttpGet("DoMatch")]
public IActionResult DoMatch()
{
var res= _matchService.DoMatch();
return Ok(res);
}
public ResponseModel DoMatch()
{
var random = new Random();
List<Team> list = _context.Team.ToList();
Dictionary<int, List<Team>> d = new Dictionary<int, List<Team>> { };
var count = list.Count();
for (int i = 0; i < count / 2; i++)
{
List<Team> temp = new List<Team>();
int index1 = random.Next(list.Count);
temp.Add(list[index1]);
list.RemoveAt(index1);
int index2 = random.Next(list.Count);
temp.Add(list[index2]);
list.RemoveAt(index2);
d.Add(i, temp);
}
return new ResponseModel
{
Data = d,
IsSuccess = true
};
}
the error or exception is:
System.NotSupportedException: The collection type 'System.Collections.Generic.Dictionary2[System.Int32,System.Collections.Generic.List1[Fantasy_League.Models.Team]]' on 'FantasyLeague.Models.ViewModels.ResponseModel.Data' is not supported.
The actual problem that you're running into, as described by the exception message you're getting, is that Dictionary<int, ...> cannot be serialized to be sent back in the web response. JSON requires each key to be a string. So you'll need to decide what you actually want your model to look like. Most likely it would work just fine to use the Values from your dictionary.
Data = d.Values,
That will make the JSON data come across as an array where each element is an array with the paired teams in it.
But Fildor makes a good point in his comment, that you could do this more easily by shuffling and pairing up adjacent teams:
Data = list.OrderBy(t => random.Next()).Chunk(2);
Then all that fancy dictionary logic goes away.
I am trying to make call to database and store result in record, stored proc always returns 4 records, but some time I got 3 records and reader shows 4 count but null in first record. What is wrong with code ?
List record = new List();
List<Task> listOfTasks = new List<Task>();
for (int i = 0; i < 2; i++)
{
listOfTasks.Add(Task.Factory.StartNew(() => {
IDataCommand cmd = ds.CreateCommand("DropTicket", "returnTableTypeData",
CommandType.StoredProcedure);
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
TicketTextOutputRecord rec = new TicketTextOutputRecord();
rec.ValidationNumber = (string)reader["ValidationNumber"];
rec.IsSuccess = (bool)reader["IsSuccess"];
rec.Error = (string)reader["Error"];
record.Add(rec);
}
//reader.Close();
//reader.Dispose();
}));
}
Task.WaitAll(listOfTasks.ToArray());
return record;
This sounds like a concurrency error; it is not intended that a connection is accessed concurrently; you are allowed overlapping readers (if MARS is enabled), but the actual access must still not be concurrent in terms of multiple threads trying to do things at the same time. The moment you do that, all behavior is undefined. Frankly, I'd just execute these sequentially, not concurrently. You are allowed to work concurrently if you use completely unrelated connections, note.
I fixed exactly the same error before.
List is not thread safe.
When adding items concurrently, the internal pointer of list can get confused and can cause item to return null even if non null value was added.
This produces the problem:
var list = new List<object>();
var listOfTasks = new List<Task>();
for (var i = 0; i < 10; i++)
{
listOfTasks.Add(Task.Factory.StartNew(() => list.Add(new object())));
}
Task.WaitAll(listOfTasks.ToArray());
Use a thread safe list will fix the problem. But I’d change the task to return the result rather than adding it to a list. Then use LINQ or Task.WhenAll to get those results.
var listOfTasks = new List<Task<object>>();
for (var i = 0; i < 10; i++)
{
listOfTasks.Add(Task.Factory.StartNew(() => new object()));
}
var list = await Task.WhenAll(listOfTasks.ToArray());
// OR
Task.WaitAll(listOfTasks.ToArray());
var list = listOfTasks.Select(t => t.Result).ToList();
I'm attempting to move from using VB WPF to C# WPF, What I have attempted so far is using an online converter because of the amount of code I have. The problem being that I have come into some troubles understanding some errors presented and being a beginner in C# I'm a little lost.
The code below is what I'm currently using with standard VB WPF and work perfectly fine and a copy of what the c# converter changes it into. (Note I have added Bing Maps WPF Reference to both VB and C#)
Private Sub Aberdeen() Handles BTNCounty.Click
If TXTCounty.Text = "Aberdeen" Then
Dim CountyLocation(2) As Microsoft.Maps.MapControl.WPF.Location
CountyLocation(0) = New Microsoft.Maps.MapControl.WPF.Location(57.143652, -2.1056584)
CountyLocation(1) = New Microsoft.Maps.MapControl.WPF.Location(57.143652, -2.1056584)
CountyLocation(2) = New Microsoft.Maps.MapControl.WPF.Location(57.124838, -2.0991633)
Dim names = New String() {"Aberdeen Central", "Aberdeen Lochnagar", "Aberdeen Kincorth"}
For index = 0 To CountyLocation.Length - 1
Dim Pin = New Microsoft.Maps.MapControl.WPF.Pushpin()
Dim CoordinateTip = New ToolTip()
CoordinateTip.Content = names(index)
Pin.Location = CountyLocation(index)
Pin.ToolTip = CoordinateTip
BingMap.Children.Add(Pin)
Next
End If
End Sub
Below is the example of the converted code into c#
private void Aberdeen()
{
if (TXTCounty.Text == "Aberdeen") {
Microsoft.Maps.MapControl.WPF.Location[] CountyLocation = new Microsoft.Maps.MapControl.WPF.Location[3];
CountyLocation(0) = new Microsoft.Maps.MapControl.WPF.Location(57.143652, -2.1056584);
CountyLocation(1) = new Microsoft.Maps.MapControl.WPF.Location(57.143652, -2.1056584);
CountyLocation(2) = new Microsoft.Maps.MapControl.WPF.Location(57.124838, -2.0991633);
dynamic names = new string[] {
"Aberdeen Central",
"Aberdeen Lochnagar",
"\tAberdeen Kincorth"
};
for (index = 0; index <= CountyLocation.Length - 1; index++) {
dynamic Pin = new Microsoft.Maps.MapControl.WPF.Pushpin();
dynamic CoordinateTip = new ToolTip();
CoordinateTip.Content = names(index);
Pin.Location = CountyLocation(index);
Pin.ToolTip = CoordinateTip;
BingMap.Children.Add(Pin);
}
}
}
I recieve 3 errors which I was wondering if you could tell me what they mean and how to resolve the issue?
CountyLocation is a variable but used like a method?
2 The name index does not exist in the current context?
3 System.Windows.FrameworkElement.ToolTip is a property but is used like a type?
Any help would be much appreciated as this very much foreign territory for me.
Please see the answers inline.
The main issue is that the converter has converted all your type inference calls (Dim variable = ...) to dynamics, which is incorrect. You should use var for type inference.
private void Aberdeen()
{
if (TXTCounty.Text == "Aberdeen") {
Microsoft.Maps.MapControl.WPF.Location[] CountyLocation = new Microsoft.Maps.MapControl.WPF.Location[3];
// Error 1: Setting array variables is done using square brackets, otherwise it's considered a method invocation
CountyLocation[0] = new Microsoft.Maps.MapControl.WPF.Location(57.143652, -2.1056584);
CountyLocation[1] = new Microsoft.Maps.MapControl.WPF.Location(57.143652, -2.1056584);
CountyLocation[2] = new Microsoft.Maps.MapControl.WPF.Location(57.124838, -2.0991633);
// extra: you don't need dynamic here, just var will do
var names = new string[] {
"Aberdeen Central",
"Aberdeen Lochnagar",
"\tAberdeen Kincorth"
};
// Error 2: you need to declare the index variable (added var)
for (var index = 0; index <= CountyLocation.Length - 1; index++) {
// Error 3: don't need dynamic here
var Pin = new Microsoft.Maps.MapControl.WPF.Pushpin();
// don't need dynamic here
var CoordinateTip = new ToolTip();
// Same as error 1: Array access is done with square brackets
CoordinateTip.Content = names[index];
// Same as error 1: Array access is done with square brackets
Pin.Location = CountyLocation[index];
Pin.ToolTip = CoordinateTip;
BingMap.Children.Add(Pin);
}
}
}
I have an application that is doing all of our reporting with locally stored RDLs. I have two forms, one is a simple viewer that contains a TabPageControl, and the other is an FLP of controls that the user can use to select report parameters. We are planning on having over 30+ options, but at the moment we only have around 5 (certain ones display for certain reports, the rest are hidden).
The issue I'm running into is that I need to have some way to get the options they chose out of a List or Collection. The method I'm using right now is
public void AddReportToViewer(string reportName, List<ReportParameter> parameterList = null)
{
TabPage newPage = new TabPage();
ReportViewer reportViewer = new ReportViewer();
newPage.Text = reportName;
newPage.Controls.Add(reportViewer);
tbcReports.TabPages.Add(newPage); //adding the report viewer to page, should do this at the end of the method
reportViewer.Reset();
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.LocalReport.ReportPath = "MyPath/reportName";
ReportDataSource rds = new ReportDataSource();
//parse parameters to individual objects to use with method calls
int parameterEmployeeID = 0;
int parameterStoreID = 0;
List<int> parameterStoreIDs = null;
DateTime parameterFromDate = DateTime.Now;
DateTime parameterToDate = DateTime.Now;
//Use parameters to get objects, just one here, but we have multiple
List<EmployeeTimeclockReportObjects> timeclock = reportBL.getEmployeeTimeclock(parameterEmployeeID, parameterStoreID, parameterFromDate, parameterToDate);
reportBindingSource.DataSource = timeclock;
rds = new ReportDataSource("TimeclockEntries", reportBindingSource);
reportViewer.LocalReport.DataSources.Add(rds);
reportViewer.RefreshReport();
reportViewer.Dock = DockStyle.Fill;
}
This all works, but here's where I need help
int parameterEmployeeID = 0;
int parameterStoreID = 0;
List<int> parameterStoreIDs = null;
DateTime parameterFromDate = DateTime.Now;
DateTime parameterToDate = DateTime.Now;
I need to strip the values from the list of report parameters so I can use them in the data population methods. For example, I'm doing something like...
int parameterEmployeeID = Convert.ToInt32(parameterList[parameterList.FindIndex(x => x.Name == "employeeID")].Values[0]);
But then I run into issues on the List<int> parameterStoreIDs, because I can't convert a StringCollection to a List of ints.
Does anyone have any recommendations on either a) converting the StringCollection to a list of ints, or b) anything else I could try doing to get the information back from the second form besides a List<ReportParameters> ???
For question (a), consider something like this:
I am not clear on what variable in the code would be the StringCollection, so for the sake of the example I'm just calling it strings.
List<int> ints = strings.Cast<string>(s => Convert.ToInt32(s)).ToList();
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I'm trying to loop through rows and get their Indexes (Primary Keys from SQL). I'm getting a NRE on "this.SelectRowIndexes.Add(ResourceKey)" I can't figure out why it would matter and how can I fix this?
CODE:
private void GetIndexes()
{
List<int> SelectRowIndexes = new List<int>();
for (int i = 0; i < gridViewRecords.Rows.Count; i++)
{
DataRowView drv = (DataRowView)gridViewRecords.CurrentRow.DataBoundItem;
DataRow selectedRow = drv.Row;
ResourceKey = Convert.ToInt32(selectedRow["ResourceAndInstallKey"]);
this.SelectRowIndexes.Add(ResourceKey);
}
}
I also have it up in my class (this has been a ton of troubleshooting, so my code looks terrible)
public List<int> SelectRowIndexes { get; set; }
I had this prior. Several of the answers quoted this code. I changed mine because the if-else was actually used for something else, which has now been deleted
if (this.SelectRowIndexes == null)
{
this.SelectRowIndexes.Add(ResourceKey);
}
else
{
this.SelectRowIndexes.Add(ResourceKey);
}
If SelectRowIndexes is null then you can't add anything to the list. You first need to initialize an empty list with
this.SelectRowIndexes = new List<int>();
What do you actually want to do if this.SelectRowIndexes is null? Currently you're just unconditionally calling Add on it, because both branches of your if statement do the same thing.
Note that it definitely wouldn't be null if you'd assigned a new value to it - but instead in this line, you're declaring a new local variable called SelectRowIndexes:
List<int> SelectRowIndexes = new List<int>();
... which you're then completely ignoring. Perhaps you meant to set the value of the property/field instead?
SelectRowIndexes = new List<int>();
With that change, you should avoid the exception - but you'll still have the basically-broken code. You should almost certainly just get rid of the if check... it's not doing you any good right now.
However, I would suggest that you probably should be declaring a separate local variable for resourceKey - the fact that you're updating an instance variable in a loop is somewhat peculiar... as is the fact that you're not using your loop index at all... you're doing the same thing for each iteration of the loop, using the current row rather than row i. Is that deliberate?
Fundamentally, you might well want to start this code again... it looks like you might just want to use LINQ:
private void GetIndexes()
{
SelectRowIndexes = gridViewRecords.Rows
.Cast<DataRowView>()
.Select(drv => (int) drv.Row["ResourceAndInstallKey"])
.ToList();
}
The this keyword allows you to access a member named SelectRowIndexes within the scope of the class. That member is probably not initialized. Remove the List<int> type declaration and it will be perfect.
private List<int> SelectRowIndexes;
private void GetIndexes()
{
SelectRowIndexes = new List<int>();
for (int i = 0; i < gridViewRecords.Rows.Count; i++)
{
DataRowView drv = (DataRowView)gridViewRecords.CurrentRow.DataBoundItem;
DataRow selectedRow = drv.Row;
ResourceKey = Convert.ToInt32(selectedRow["ResourceAndInstallKey"]);
if (this.SelectRowIndexes == null)
{
this.SelectRowIndexes.Add(ResourceKey);
}
else
{
this.SelectRowIndexes.Add(ResourceKey);
}
}
}
You instantiate a local variable
List<int> SelectRowIndexes = new List<int>();
and then you are adding to your class property/field this.SelectedRowIndexes which you are most likely not assigning anywhere and it is null and you get NRE.
this.SelectRowIndexes.Add(ResourceKey);
Change this so
private void GetIndexes()
{
this.SelectRowIndexes = new List<int>();
for (int i = 0; i < gridViewRecords.Rows.Count; i++)
{
DataRowView drv = (DataRowView)gridViewRecords.CurrentRow.DataBoundItem;
DataRow selectedRow = drv.Row;
ResourceKey = Convert.ToInt32(selectedRow["ResourceAndInstallKey"]);
this.SelectRowIndexes.Add(ResourceKey);
}
}