Object reference error adding a new select list item - c#

I'm having a problem with the List<SelectListItem>. Whenever the code hits the foreach it says:
object reference not set to an instance of an object.
Am I missing something or can anyone explain why it is failing there?
public ActionResult HammerpointVideos(string category, string type)
{
var stuff = Request.QueryString["category"];
var ItemId = (from p in entities.EstimateItems
where p.ItemName == category
select p.EstimateItemId).FirstOrDefault();
var Videos = (from e in entities.EstimateVideos
where e.EstimateItemId == ItemId
select new Models.HammerpointVideoModel
{
VideoName = e.VideoName,
VideoLink = e.VideoLink
}).ToList();
var model= new Models.HammerpointVideoListModel();
List<SelectListItem> list = model.VideoList;
foreach (var video in Videos)
{
list.Add(new SelectListItem()
{
Selected=false,
Value = video.VideoLink,
Text = video.VideoName
});
}
}

Is ViedoList initialized before? I assume it is not. Create new list add items to it and after that add reference to it in your model:
var model = new Models.HammerpointVideoListModel();
List<SelectListItem> list = new List<SelectListItem>();
foreach (var video in Videos)
{
list.Add(new SelectListItem()
{
Selected=false,
Value = video.VideoLink,
Text = video.VideoName
});
}
model.VideoList = list;

Probably You didn't initialized VideoList in the parameterless constructor of HammerpointVideoListModel class, so it is NOT an empty list.
Put
VideoList = new List<SelectedListItem>();
in the constructor.

Related

How can I create a list inside a list with a foreach in c# ?

In other words I need all the elements of list "Categories" to be the "Parent" and elements of list "commodities" be the children.
Example
public string GetCommodities()
{
List<dynamic> categories = new List<dynamic>();
List<dynamic> commodities = new List<dynamic>();
foreach (var comcat in QuickQuoteRepo.CommodityCategories.All().OrderBy(o => o.Order))
{
categories.Add(new
{
comcat.Category,
});
foreach (var com in comcat.Commodities.OrderBy(o => o.Name))
{
commodities.Add(new
{
com.Name,
});
}
}
var response = new JavaScriptSerializer().Serialize(commodities);
return response;
}
And see if it's possible to all commodities names inside each category, within this foreach.
I tried adding a dynamic list such as:
dynamic listOfElements = new { CAT = categories, COMM = commodities };
But it does't return elemnts as parents or dependency of categories. Is the same as adding
commodities.Add(new
{
comcat.Category,
com.Name,
});
public string GetCommodities()
{
List<dynamic> categoryCommodityList = new List<dynamic>();
foreach (var comcat in QuickQuoteRepo.CommodityCategories.All().OrderBy(o => o.Order))
{
var allCommodities = comcat.Commodities.OrderBy(o => o.Name).Select(com => com.Name).ToList();
categoryCommodityList.Add(new { Catagory = comcat.Category, Items = allCommodities } );
}
return new JavaScriptSerializer().Serialize(categoryCommodityList);
}
You class structure does not support parent-child relationships. I mean, if what you want is that each Category holds a list of commodities, then you would need something like this:
var result = from c in comcat
select new { Category = c, Commoddities = c.Commoddities};
This will return a hierarchy of Categories including all Commodities underneath it.
If you are just receiving a flat data set, then you need something like this:
var result = from c in comcat
select new { Category = c,
Commoddities = c.Where(x=>x.Category.Name == c.Name).Select(x=>x.Commodity) };
Hopefully you get the idea...

View List from controller to View

I am just trying out stuff, I have items from different models and want to return them to as one(if its possible).
I have this ActionResult which returns all products from my database:
[HttpGet]
public ActionResult GetAllContents()
{
ViewData["listy"] = GetColors();
var i = (from p in db.tProducts
select p).ToList();
return View(i);
}
and the list is coming from this method
public List<SelectListItem> GetColors()
{
var listy = new List<SelectListItem>();
var colorList = from a in db.tColors
select new SelectListItem
{
Text = a.id.ToString(),
Value = a.name
};
foreach (var item in colorList)
listy.Add(item);
return listy;
}
So how do I display this list as a dropdown on the View?
you can use as below
#Html.DropDownList("listy", ViewData["listy"] as List<SelectListItem>)
You need to parse your object to list of SelectListItem, you can use the following
#Html.DropDownListFor(m => m.Colors, ViewData["listy"] as List<SelectListItem>, "-Colors-", new { })

How to make sure that selectlist items belong to the same SelectListGroup?

I am experimenting with the <optgroup> element and am trying to make several items belong to the same optgroup.
My code:
public async Task<ActionResult> GetStatsView()
{
var users = await _administrationServiceAPI.GetPersons();
var tanks = await _administrationServiceAPI.GetTanks();
var list = new List<SelectListItem>();
foreach (var u in users.Payload)
{
SelectListItem item = new SelectListItem {Text = u.Name, Value = u.Id.ToString(), Group = new SelectListGroup {Name = "Users"} };
list.Add(item);
}
foreach (var u in tanks.Payload)
{
SelectListItem item = new SelectListItem { Text = u.Name, Value = u.Id.ToString(), Group = new SelectListGroup { Name = "Tanks" } };
list.Add(item);
}
#ViewBag.MyList = list;
return View("StatsView");
}
view:
#Html.DropDownList("MyList")
result:
Desiered result is:
Users
UserName
UserName
UserName
Tanks
Tank
Tank
Tank
How do I do this?
To make it work, you need to reuse the SelectListGroup. Just use it like this:
var usersGroup = new SelectListGroup {Name = "Users"};
foreach (var u in users.Payload)
{
SelectListItem item = new SelectListItem {Text = u.Name, Value = u.Id.ToString(), Group = usersGroup };
list.Add(item);
}
And of course similarly for Tanks.
It does not matter that the name is the same, an instance used must be the same in various items to group them into single optgroup.

StringBuilder within IEnumerable

I have a ControlMeasure table that holds information on each control measure and a ControlMeasurepeopleExposed Table that holds a record for each person exposed in the control measure this could be 1 record or many records.
I Have a controller that populates a List view
For each item in the list, Control Measure, I would like to create a string that shows all the People at risk
e.g.
PeopleString = "Employees, Public, Others";
Ive added a foreach in the controller to show what I'm trying to do however I'm aware that this wont work.
The controller is this:
public ActionResult ControlMeasureList(int raId)
{
//Populate the list
var hazards = new List<Hazard>(db.Hazards);
var controlMeasures = new List<ControlMeasure>(db.ControlMeasures).Where(x => x.RiskAssessmentId == raId);
var cmcombined = (
from g in hazards
join f in controlMeasures
on new { g.HazardId } equals new { f.HazardId }
select new CMCombined
{
Activity = f.Activity,
ControlMeasureId = f.ControlMeasureId,
ExistingMeasure = f.ExistingMeasure,
HazardName = g.Name,
LikelihoodId = f.LikelihoodId,
Rating = f.Rating,
RiskAssessmentId = f.RiskAssessmentId,
SeverityId = f.SeverityId,
}).OrderBy(x => x.Activity).ToList();
var cmPeopleExp = new List<ControlMeasurePeopleExposed>(db.ControlMeasurePeopleExposeds).Where(x => x.RiskAssessmentId == raId);
var peopleExp = from c in cmPeopleExp
join d in db.PeopleExposeds
on c.PeopleExposedId equals d.PeopleExposedId
orderby d.Name
select new RAPeopleExp
{
RAPeopleExpId = c.PeopleExposedId,
PeopleExpId = c.PeopleExposedId,
PeopleExpName = d.Name,
RiskAssessmentId = c.RiskAssessmentId,
ControlMeasureId = c.ControlMeasureId
};
var model = cmcombined.Select(t => new FullControlMeasureListViewModel
{
ControlMeasureId = t.ControlMeasureId,
HazardName = t.HazardName,
LikelihoodId = t.LikelihoodId,
Rating = t.Rating,
SeverityId = t.SeverityId,
Activity = t.Activity,
ExCM = t.ExistingMeasure,
//This section here is where I'm struggling
var PeopleString = new StringBuilder();
foreach (var p in peopleExp)
{
PeopleString.AppendLine(p.PeopleName);
{
PeopleExposed = PeopleString,
});
return PartialView("_ControlMeasureList", model);
}
I know I cant directly put this code in the controller but it does represent what I want to do.
You can't foreach within an object initializer (which is what you're trying to do when instantiating FullControlMeasureListViewModel). You can, however, use a combination of string.Join and peopleExp.Select:
var model = cmcombined.Select(t => new FullControlMeasureListViewModel
{
//other props
PeopleExposed = string.Join(",", peopleExp
.Where(p => p.ControlMeasureId == t.ControlMeasureId)
.Select(p => p.PeopleExpName));
//other props
});

ArgumentOutOfRangeException when writing to a model

I'm trying to write to a model for the first time to use in my view: the first time I write to the model I get an ArgumentOutOfRangeException.
Getting error on first write to array:
private IAdditionalQuestionsService _service;
private SelectedAdditionalQuestionAnswerModel _model;
private void InitializeController()
{
_service = GetObject<IAdditionalQuestionsService>();
//GetPageHeaderText(inst);
ViewBag.GetPageTitle = "Additional Questions";
}
[HttpGet]
public virtual ActionResult Edit()
{
Institution inst = _service.GetInstitution(State.GetInstitutionRecordId());
_model = GetObject<SelectedAdditionalQuestionAnswerModel>();
_model.AddQuestAnswModel = new List<AdditionalQuestionAnswerModel>();
GetPageConfiguration1(inst);
return View(_model);
}
AdditionalQuestionAnswerModel m = GetObject<AdditionalQuestionAnswerModel>();
int c = 0;
foreach (var x in inst.AdditionalQuestions)
{
foreach (var y in x.AdditionalQuestionAnswers)
{
// Error is happening on next line *************
_model.AddQuestAnswModel[c].QuestionText = x.QuestionText;
_model.AddQuestAnswModel[c].InstitutionId = x.InstitutionId;
_model.AddQuestAnswModel[c].AdditionalQuestionId = x.Id;
_model.AddQuestAnswModel[c].AnswerText = y.AnswerText;
_model.AddQuestAnswModel[c].IsSelected = false;
c++;
}
}
You can't use _model.AddQuestAnswModel[c] because you never added any items to your list.
Instead of that, create a new object and set its values and then add the item to your list.
Something like this:
AdditionalQuestionAnswerModel newItem = new AdditionalQuestionAnswerModel();
//set the values here to newItem
_model.AddQuestAnswModel.Add(newItem);
You're firstly instantiating your list
_model.AddQuestAnswModel = new List<AdditionalQuestionAnswerModel>();
then you try to access to the first element
_model.AddQuestAnswModel[c] // c == 0
without adding any element to the list.
Add an element before trying to access to a list by index, or more simple:
foreach (var y in x.AdditionalQuestionAnswers)
{
AdditionalQuestionAnswerModel newObj = new AdditionalQuestionAnswerModel
{
QuestionText = x.QuestionText;
InstitutionId = x.InstitutionId;
AdditionalQuestionId = x.Id;
AnswerText = y.AnswerText;
IsSelected = false;
};
_model.AddQuestAnswModel.Add(newObj);
}
Ir means that there no item in your _model.AddQuestAnswModel at the indicated postition, and from your code, I see that _model.AddQuestAnswModel has only be initiated with new List<AdditionalQuestionAnswerModel>(), so it does not contain items (unless you're doing it in the contructor).
You need to fill it like so :
_model.AddQuestAnswModel.Add(item);

Categories

Resources