Invalid ModelSate because of dropdownlist with concatenated information - c#

I had a program working perfectly. But the dropdownlist of this page had just one information of one column, so I had to add another columns to this dropdownlist, because of the users ask. When I did it, my ModelState started to be Invalid.
ERROR MESSAGE:
The parameter conversion from type 'System.String' to type 'SINCO_MVC.Models.SINCO_CONCESSAO'' failed because no type converter can convert between these types
Im not seeing the reason of this error.
View:
<div class="editor-field" id="IDCONCESSAO">
<%: Html.DropDownListFor(model => model.SINCO_CONCESSAO,
new SelectList(ViewBag.IDCONCESSAO, "Id", "Nome"), string.Empty,
new { #class = "select", style = "width: 250px;" }) %>
</div>
Controller (where I catch the information of the dropdownlist):
// GET: /Concessao/Create
[Authorize(Roles = "ADMINISTRADOR")]
public ActionResult Create(SINCO_LOCALIDADE_CONCESSAO model)
{
ViewBag.IDCONCESSAO = from p in db.SINCO_CONCESSAO.ToList()
join c in db.MUNICIPIOS_VIEW.ToList() on p.IDMUNICIPIO equals c.ID_MUNICIPIO
join d in db.SINCO_TIPO_CONCESSAO.ToList() on p.IDTIPOCONCESSAO equals d.IDTIPOCONCESSAO
select new
{
Id = p.IDCONCESSAO,
Nome = p.IDCONCESSAO + " - " + c.NOME_MUNICIPIO + " - " + d.DSTIPOCONCESSAO
};
PopulateItemChoices(model);
return View(model);
}
Controller (post method):
[Authorize(Roles = "ADMINISTRADOR")]
[HttpPost]
public ActionResult Create(SINCO_LOCALIDADE_CONCESSAO sinco_localidade_concessao, SINCO_CONCESSAO sinco_concessao)
{
if (ModelState.IsValid)
{
db.SINCO_LOCALIDADE_CONCESSAO.Add(sinco_localidade_concessao);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.IDCONCESSAO = from p in db.SINCO_CONCESSAO.ToList()
join c in db.MUNICIPIOS_VIEW.ToList() on p.IDMUNICIPIO equals c.ID_MUNICIPIO
join d in db.SINCO_TIPO_CONCESSAO.ToList() on p.IDTIPOCONCESSAO equals d.IDTIPOCONCESSAO
select new
{
Id = p.IDCONCESSAO,
Nome = p.IDCONCESSAO + " - " + c.NOME_MUNICIPIO + " - " + d.DSTIPOCONCESSAO
};
PopulateItemChoices(sinco_localidade_concessao);
return View(sinco_localidade_concessao);
}
Model:
namespace SINCO_MVC.Models
{
[MetadataType(typeof(SincoLocalidadeConcessaoMetaData))]
public partial class SINCO_LOCALIDADE_CONCESSAO
{
public List<int> SelectedItemIds { get; set; }
public IEnumerable<SelectListItem> ItemChoices { get; set; }
}
public class SincoLocalidadeConcessaoMetaData
{
[Display(Name = "ID LOCALIDADE:")]
public int[] IDLOCALIDADE { get; set; }
[Display(Name = "ID:")]
public int IDCONCESSAO { get; set; }
[Display(Name = "Localidade:")]
public virtual LOCALIDADES_VIEW LOCALIDADES_VIEW { get; set; }
public virtual MUNICIPIOS_VIEW MUNICIPIOS_VIEW { get; set; }
}
}

The reason you get that error message is because a dropdown list returns a value type and your trying to bind to a complex object. Your posting back the selected value of IDCONCESSAO (an int I assume) and trying to bind that to SINCO_CONCESSAO. You need to bind the dropdown to a property of SINCO_CONCESSAO, for example
Html.DropDownListFor(model => model.SINCO_CONCESSAO.ID, ....)

Related

Why does this value in my model return null when used in my controller? (ASP.NET MVC)

within my model i have a bool value called itemCheck:
public class Item
{
public Array userDataItems { get; set; }
public char[] delimiterChar { get; set; }
public bool itemCheck { get; set; }
}
My viewModel, linking the item model to the controller:
public class CategoryItemViewModel
{
public Item ItemList { get; set; }
public Category CategoryList { get; set; }
}
Which i then initialize within my main controller as false:
public ActionResult Index()
{
CategoryItemViewModel CIVM = new CategoryItemViewModel();
CIVM.ItemList = GetItemModel();
CIVM.CategoryList = GetCategoryModel();
return View(CIVM);
}
public Item GetItemModel()
{
var dataFileItems = Server.MapPath("~/App_Data/Item.txt");
Item iModel = new Item()
{
userDataItems = System.IO.File.ReadAllLines(dataFileItems), //Items Text File
delimiterChar = new[] { ',' },
itemCheck = false,
};
return iModel;
}
Then i use it in my view as the bool value to indicate whether a checkbox is ticked or not :
#using (Html.BeginForm("Items", "Items", FormMethod.Post, new { id = "formFieldTwo" }))
{
#Html.CheckBoxFor(m => m.ItemList.itemCheck, false)
}
And lastly i try to access this variable 'itemCheck' which should be set to 'false' within my ActionResult:
[HttpPost]
public ActionResult Items(string ItemDescription, CategoryItemViewModel m)
{
bool originalValue = m.ItemList.itemCheck;
var FkFile = Server.MapPath("~/App_Data/ForeignKeyValue.txt");
var Fk = System.IO.File.ReadAllText(FkFile);
var dataFileItems = Server.MapPath("~/App_Data/Item.txt");
var numberOfLinesItems = System.IO.File.ReadLines(dataFileItems).Count();
var textFileDataItems = ItemDescription + "," + numberOfLinesItems + "," + Fk + "," + originalValue + Environment.NewLine;
System.IO.File.AppendAllText(dataFileItems, textFileDataItems);
return View();
}
However, i get the following error on the line 'bool originalValue = m.ItemList.itemCheck;' :
" System.NullReferenceException: 'Object reference not set to an instance of an object.' "
I fail to understand why my program is giving me this error?
Change :
#Html.CheckBoxFor(m => m.ItemList.itemCheck, false)
To :
#Html.CheckBoxFor(Model => Model.ItemList.itemCheck, false)

SelectListItem is empty, if statement inside method shows it to be filled

error message:
http://prntscr.com/qtlodf
method:
public IActionResult GroepsResultaten(int vakId, int groepId)
{
var studentenLijst = _context.Student.Join(_context.StudentGroep,
s => s.Id,
sg => sg.StudentId,
(s, sg) => new { Student = s, StudentGroep = sg })
.Where(x => x.StudentGroep.GroepId == groepId)
.Select(x => x.Student);
ViewBag.Studenten = new SelectList(studentenLijst, "Id", "Naam");
return View();
}
I've also tried this:
public IActionResult GroepsResultaten(int vakId, int groepId)
{
var studentInfo = _context.Student
.Select(s =>
new
{
s.Id,
Naam = string.IsNullOrEmpty(s.Tussenvoegsel)
? s.Voornaam + " " + s.Achternaam + " - " + s.Studentnummer
: s.Voornaam + " " + s.Tussenvoegsel + " " + s.Achternaam + " - " + s.Studentnummer,
forStudent = s.Studentnummer + "-" + s.Achternaam
});
ViewBag.Studenten = new SelectList(studentInfo, "Id", "Naam");
return View();
}
I'm a bit stuck at this. I want to return multiple input fields (I'm just testing with selectlist at the moment) for all students of group x, from there on I want to be able to grade students for the subject that's included in the view using get method. Because English isn't my first language I've included two screenshots to clarify what I mean.
clarification of what I want to achieve:
group view: http://prntscr.com/qtlrqd
wireframe of method view: http://prntscr.com/qtlswn
models:
public class Student
{
public int Id { get; set; }
[Required]
public string Voornaam { get; set; }
[Required]
public string Achternaam { get; set; }
public string Tussenvoegsel { get; set; }
public string Studentnummer { get; set; }
public List<Resultaat> Resultaten { get; set; }
public List<StudentGroep> Groepen { get; set; }
}
public class Groep
{
public int Id { get; set; }
[Required]
public string Naam { get; set; }
[Required]
public string Groepscode { get; set; }
public List<GroepVak> Vakken { get; set; }
public List<StudentGroep> Studenten { get; set; }
}
public class StudentGroep
{
public Student Student { get; set; }
public int StudentId { get; set; }
public Groep Groep { get; set; }
public int GroepId { get; set; }
}
I hope I've included enough information, I'm available on discord too if that makes it easier.
The problem is what the SelectList class returns. Because view side results that ViewBag.Studenten is null.
Also, you must make sure that the database query returns a value.
Using ViewData resulted in what I want, from here on I can hopefully figure out how to use it for posting grades for each student.
Method:
public IActionResult GroepsResultaten(int vakId, int groepId)
{
var studentenLijst = _context.Student.Join(_context.StudentGroep,
s => s.Id,
sg => sg.StudentId,
(s, sg) => new { Student = s, StudentGroep = sg })
.Where(x => x.StudentGroep.GroepId == groepId)
.Select(x => x.Student)
.ToList();
if (groepId >= 1)
{
ViewData["Studenten"] = studentenLijst.ToList();
}
//ViewBag.Studenten = new SelectList(studentenLijst, "Id", "Naam");
return View();
}
View:
#foreach (var item in ViewBag.Studenten)
{
#item.Voornaam;
<input type="number" />
}

How to fetch all data using join three tables using Entity Framework

I get this error:
System.NullReferenceException: Object reference not set to an instance of an object
How can I resolve this exception?
Join query controller:
var Cs = new List<MyModel>();
using (Join3Entities1 db = new Join3Entities1())
{
DateTime start1 = DateTime.Now;
ViewBag.Start = "Start Time :" + start1;
Cs = (from e in db.Students
join p in db.Marks on e.S_ID equals p.S_ID
join t in db.Details on p.School_ID equals t.School_ID
where p.Score > 50
select new MyModel
{
S_Name = e.S_Name,
Score = (int)p.Score,
Status = p.Status,
Address_City = t.Address_City,
Email_ID = t.Email_ID,
Accomplishments = t.Accomplishments
}).ToList();
DateTime end1 = DateTime.Now;
ViewBag.end = "End Time:" + end1;
TimeSpan time1 = end1 - start1;
ViewBag.time = "TimeSpan:" + time1;
}
return View();
the above code is to join three table I wrote in controller section
model:
public class MyModel
{
public string S_Name { get; set; }
public int Score { get; set; }
public string Status { get; set; }
public string Address_City { get; set; }
public string Email_ID { get; set; }
public string Accomplishments { get; set; }
}
view:
#model IEnumerable<Join3table.Models.MyModel>
#{
ViewBag.Title = "Home Page";
}
#foreach (var per in Model)
{
<tr>
<td>#per.S_Name</td>
<td>#per.Score</td>
<td>#per.Status</td>
<td>#per.Address_City</td>
<td>#per.Email_ID </td>
<td>#per.Accomplishments</td>
</tr>
}
</tbody>
</table>
I created three tables student,mark and details with primary and foreign key relation
instead of doing select new model, try returning each table one by one to see where the nullref is specifically coming from, that way you might be able to narrow it down.
another option to be on the safe side is to make sure to nullrefcheck before calling each column S_Name = e != null && !string.isNullOrEmpty(e.S_Name) ? e.S_Name : string.Empty;

How can I make a cascading dropdown list?

I have Companies and Vacancies tables.
Company has n number of Vacancies. I need to make two dropdown lists.
In one it will be Company, when I select it, there will be Vacancies related to this company.
Here is model of Companies
public Company()
{
this.Clients = new HashSet<Client>();
this.Vacancies = new HashSet<Vacancy>();
}
[Key]
public int CompanyID { get; set; }
public string CompanyName { get; set; }
public string Id { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Client> Clients { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Vacancy> Vacancies { get; set; }
}
Here is model for Vacancies
public partial class Vacancy
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Vacancy()
{
this.Interviews = new HashSet<Interview>();
}
[Key]
public int VacancyId { get; set; }
public string VacancyName { get; set; }
public Nullable<int> CompanyID { get; set; }
public virtual Company Company { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Interview> Interviews { get; set; }
Here is controller where I need to do this
[HttpGet]
public ActionResult WelcomeScreen()
{
// Формируем список команд для передачи в представление
SelectList teams = new SelectList(db.Vacancy, "VacancyId", "VacancyName");
ViewBag.Teams = teams;
return View();
}
//Заносим инфу о вакансии в таблицу
[HttpPost]
public ActionResult WelcomeScreen(Interview interview)
{
db.Interview.Add(interview);
db.SaveChanges();
//Int32 id = interview.Interview_Id;
//TempData["id"] = id;
return RedirectToAction("Index", "Questions", new { id = interview.Interview_Id });
}
How I need to make Cascade Dropdown list?
UPDATE
I try solution
Here is my controller (Questions controller)
[HttpGet]
public ActionResult WelcomeScreen()
{
// Формируем список команд для передачи в представление
//SelectList teams = new SelectList(db.Vacancy, "VacancyId", "VacancyName");
//ViewBag.Teams = teams;
ViewBag.Companies = new SelectList(db.Companies, "CompanyID", "CompanyName");
return View();
}
//Заносим инфу о вакансии в таблицу
[HttpPost]
public ActionResult WelcomeScreen(Interview interview)
{
db.Interview.Add(interview);
db.SaveChanges();
//Int32 id = interview.Interview_Id;
//TempData["id"] = id;
return RedirectToAction("Index", "Questions", new { id = interview.Interview_Id });
}
public ActionResult Vacancies(int companyId)
{
var items = db.Vacancy
.Where(x => x.CompanyID == companyId)
.Select(x => new SelectListItem
{
Value = x.VacancyId.ToString(),
Text = x.VacancyName
})
.ToList();
return Json(items, JsonRequestBehavior.AllowGet);
}
Here is script
<script>
$(function () {
$("#Company").change(function (e) {
var $vacancy = $("#vacancy");
var url = $vacancy.data("url") + '?companyId=' + $(this).val();
$.getJSON(url, function (items) {
$.each(items, function (a, b) {
$vacancy.append('<option value="' + b.Value + '">' + b.Text + '</option>');
});
});
});
});
</script>
And here is View
<div class="right-grid-in-grid">
<div style="margin-left:20px;">
#Html.DropDownList("Company", ViewBag.Companies as SelectList, new { #class = "greeting"})
#Html.ValidationMessageFor(model => model.VacancyId, "", new { #class = "text-danger" })
</div>
<div style="margin-left:20px;">
<select name="id" id="vacancy" data-url="#Url.Action("Vacancies","Questions")" class="greeting"/>
</div>
</div>
But AJAX not works.
The idea of cascading dropdown is, When you load the page, you load the dropdown content for the first SELECT element. The second SELECT element will be an empty one. When user selects an option from the first dropdown, send that to the server which returns the content needed to build the second dropdown.
So in the GET action of your page, get the data needed to render the first dropdown.
public ActionResult Welcome()
{
ViewBag.Companies = new SelectList(db.Companies, "CompanyID", "CompanyName");
return View();
}
Now in the view, you can use the DropDownList helper method to render the SELECT element with the data we set to the ViewBag.Companies. We will also add our second dropdown as well.
#Html.DropDownList("Company", ViewBag.Companies as SelectList)
<select name="id" id="vacancy" data-url="#Url.Action("Vacancies","Home")">
Now we will use some ajax code(using jQuery in this example) to get the content for the second dropdown. Register an event handler for the change event of the first dropdown, get the selected value, make an ajax call to the Vacancies action method which returns the data needed to build the second dropdown in JSON format. Use this JSON data to build the second dropdown in javascript.
$(function(){
$("#Company").change(function (e) {
var $vacancy = $("#vacancy");
var url = $vacancy.data("url")+'?companyId='+$(this).val();
$.getJSON(url, function (items) {
$.each(items, function (a, b) {
$vacancy.append('<option value="' + b.Value + '">' + b.Text + '</option>');
});
});
});
});
Now the last part is, implementing the Vacancies method.
public ActionResult Vacancies(int companyId)
{
var items = db.Vacancies
.Where(x=>x.CompanyID==comapnyId)
.Select(x => new SelectListItem { Value = x.VacancyId.ToString(),
Text = x.VacancyName })
.ToList();
return Json(items, JsonRequestBehavior.AllowGet);
}
Assuming db is your DbContext class object.
Ajax is not necessary for implementing cascading dropdowns. You can post the form with the selected companyId and the action method can return the same with second dropdown filled. But people usually use ajax to give a nice user experience

Drop down list in MVC from DB text, value

I have problem with dropdownlist. I want show text in selectedlist but select Id.
How I implement view? In view I must save selected data to model (odbiorca)
Controller:
var odbiorca = dbU.Uczniowie.OrderBy(d => d.Nazwisko).Select(m => m.Nazwisko + " " + m.Imie).ToList(); //return Names
var odbiorcaId= dbU.Uczniowie.OrderBy(d => d.Id).Select(m => m.Nazwisko + " " + m.Imie).ToList(); //return IDs
List<SelectListItem> items = new List<SelectListItem>();
for (int i=0;i<dbU.Uczniowie.Count();i++)
{
items.Add(new SelectListItem { Text = odbiorca[i], Value = odbiorcaId[i] });
}
ViewBag.odbiorca = items;
Model:
public class Uwaga
{
[Key]
[Required]
public string Id { get; set; }
[Required]
public string odbiorca { get; set; }
[Required]
public DateTime data { get; set; }
}
I tried this solution but the program saves text, but not value.
#Html.DropDownList("odbiorca", "----")
Both of your linq statements return the same values.
var odbiorca = dbU.Uczniowie.OrderBy(d => d.Nazwisko).Select(m => m.Nazwisko + " " + m.Imie).ToList(); //return Names
var odbiorcaId= dbU.Uczniowie.OrderBy(d => d.Id).Select(m => m.Nazwisko + " " + m.Imie).ToList(); //return IDs
both of these return a list of m.Nazwisko + " " + m.Imie there is no Id.
you should just use one query to get your select list
var list = dbU.Uczniowie.Select(a => new {Text= a.Nazwisko + " " + a.Imie, Value = a.Id}).ToList();
ViewBag.odbiorca = list.Select(a => new SelectListItem{ Text = a.Text, Value = a.Value.ToString()});
Try this approach. Lets take your model class:
public class Uwaga
{
[Key]
[Required]
public string Id { get; set; }
Required]
public string odbiorca { get; set; }
[Required]
public DateTime data { get; set; }
}
In the view you can use the same helper: #Html.DropDownList("odbiorca", "----")
But, in the controller you set the "id" and "text" columns through a SelectList object. Take the example in the default action in the controller:
public ActionResult Index()
{
//Creates a example list with multiple "Uwaga" items,
//but you might want to pull the data from the database
List<Uwaga> UwagaList = new List<Uwaga>();
for (int i = 1; i <= 10; i++)
{
Uwaga item = new Uwaga();
item.Id = i;
item.odbiorca = "odbiorca " + i;
UwagaList.Add(item);
}
//Create a SelectList object, the first parameter is the list created above.
//The second parameter is the "id" key and the thirth
//parameter is the text you want to display in the dropdown.
var SelectList = new SelectList(UwagaList, "Id", "odbiorca");
//Fill the dropdownlist "odbiorca" using ViewData.
ViewData["odbiorca"] = SelectList;
}
I hope it helps.

Categories

Resources