Save data from dropdownlist using selectlist - c#

I am trying to save data using SelectListItem. I have managed to display the data but, I can't think of a way to save a selected item into the database.
My controller methods are:
public ActionResult Create()
{
ViewBag.ProposerID = new SelectList(db.Proposers, "ID", "ProposerName");
List<SelectListItem> projectType = new List<SelectListItem>();
projectType.Add(new SelectListItem { Text = "Development", Value = "1" });
projectType.Add(new SelectListItem { Text = "Research", Value = "2" , Selected = true});
projectType.Add(new SelectListItem { Text = "Hybrid", Value = "3" });
projectType.Add(new SelectListItem { Text = "Other", Value = "4" });
ViewBag.ProjectType = projectType;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
[Bind(Include = "ID,ProjectTitle,Description,ProposedDate,ProjectType,ProjectStatus,ProjectDifficulty,ProposerID")] Project project)
{
try {
if (ModelState.IsValid && ModelState != ModelState)
{
db.Projects.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception)
{
ViewBag.ErrorMessage = "Something went wrong!! Please try again.";
// Error message
}
ViewBag.ProposerID = new SelectList(db.Proposers, "ID", "ProposerName", project.ProposerID);
return View(project);
}
and my View:
<div class="form-group">
#Html.LabelFor(model => model.ProjectType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProjectType", "")
#Html.ValidationMessageFor(model => model.ProjectType, "", new { #class = "text-danger" })
</div>
</div>
I have managed to display the data but, I am confused on how to get selected item and save it.
My Model is:
public class Project
{
public int ID { get; set; }
[Required]
[DisplayName("Project Title")]
public string ProjectTitle { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[DisplayName("Project Description")]
public string Description { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayName("Proposed Date")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime ProposedDate { get; set; }
// Development or Research etc.
[Required]
[DisplayName("Project Type")]
public string ProjectType { get; set; }
// Project Is Taken or Not
[DisplayName("Project Status")]
public ProjectStatus ProjectStatus { get; set; }
[DisplayName("Project Difficulty")]
public ProjectDifficulty ProjectDifficulty { get; set; }
[ForeignKey("Proposer")]
public int ProposerID { get; set; }
public virtual Proposer Proposer { get; set; }
}

First of all change you ViewBag key so it is different than the model property name:
ViewBag.ProjectTypeOptions = projectType;
and in your view use DropDownListFor helper this way:
#Html.DropDownListFor(x=>x.ProjectType, new SelectList(ViewBag.ProjectTypeOptions,"Value","Text"))
now you will get selecred item value posted in Model in ProjectType property.
and your model should have property of type string not IEnumerable<SelectListItem> like this:
public class Project
{
public string ProjectType { get;set;}
............
............
}

Related

How to solve null value when using DropDownListFor in View?

There is a problem I have been troubleshooting a day and a half and I need some help.
The code looks fine , but the issue is that it returns Null.
I can get the property of that value on the View Side.
It throws:
No ViewData IEnumerable.
This is what |I have done so far and I need some help , my View use the Multiple Model but its correct class name with correct properties.
[HttpPost]
public ActionResult CourseList()
{
var course = new List<string>()
{ "Private(Copyrighted)","Public Domain", "Creative Commons Licences", "CC Attribution", "CC Attribution Share ALike", "CC Attribution Non-Commercial",
"CC Attribution Non-Commercial Share Alike", "CC Attribution Non Directive", "CC Attribution Non-Commercial No Directives"
};
// List of items here.
List<SelectListItem> select_list = new List<SelectListItem>();
var query = from li in course
select
new SelectListItem
{
Value = li.ToString(),
Text = li.ToString(),
};
select_list = query.ToList();
ViewBag.course = select_list;
eNtsaCourseList eCourse = new eNtsaCourseList();
return View(eCourse);
}
// eNtsaRegCourses.
public class RegCoursesViewModel
{
public eNtsaCourses Courses { get; set; }
public eNtsaCourseList eCourses { get; set; } // I am using this property for my View to access dropdownlist.
public eNtsaDashboardViewModel Dashboard { get; set; }
public List<eNtsaCourseList> lsteNtsaDashboard { get; set; }
public RegCoursesViewModel MainModel { get; set; }
}
public class eNtsaCourseList
{
public string CourseLicence { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public string CourseList { get; set; }
}
#using (Html.BeginForm("CourseList", "Home", FormMethod.Post))
{
<div class="form-group row">
<label for="Content-Licence" class="col-sm-3 col-form-label">Content Licence</label>
<div class="col-sm-5">
#Html.DropDownListFor(m => m.eCourses.CourseList, ViewBag.course as List<SelectListItem>)
</div>
</div>
}

How to validate a unique property while user giving input (code first approach in .Net, MVC5)?

Model Class:
public class Course
{
[Key]
public int Id { get; set; }
[MinLength(5, ErrorMessage = "Code must be (5) characters long")]
[Index(IsUnique = true)]
[Column(TypeName = "VARCHAR")]
[Required]
[Display(Name = "Code")]
public string CourseCode { get; set; }
[Index(IsUnique = true)]
[Column(TypeName = "VARCHAR")]
[Required]
[Display(Name = "Name")]
[Remote("IsCourseNameExist", "Courses", HttpMethod = "POST", ErrorMessage = "Course is existed.")]
public string CourseName { get; set; }
//[System.ComponentModel.DataAnnotations.Compare("CourseName", ErrorMessage = "Already this Course is exist.")]
//[NotMapped]
//public string VeryfyName { get; set; }
[Range(0.5, 5, ErrorMessage = "Credit Must be between (0.5) to (5.0)")]
[Display(Name = "Credit")]
public decimal CourseCredit { get; set; }
public string Description { get; set; }
public int DepartmentId { get; set; }
public int SemesterId { get; set; }
[ForeignKey("DepartmentId")]
public virtual Department Department { get; set; }
[ForeignKey("SemesterId")]
public virtual Semester Semester { get; set; }
}
In Controller Class:
public JsonResult IsCourseNameExist(string CourseName)
{
//var course = .....
return Json(course == null);
}
In View:
<div class="form-group">
#Html.LabelFor(model => model.CourseName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CourseName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CourseName, "", new { #class = "text-danger" })
</div>
</div>
Description:
I am using Code First EF and very new in this area.
I have a Model class "Course" which generated a DB table named "Courses".
In view, user will add courses for a selected department and semester. But the Course Name property is unique.If user give a course name already exist in "Courses" table and submit button, then some error generates. That's why I want to make confirm that the user can not put any existing course name. So it needs checking before submission.
I have searched a lot, as I am newbie, everything is not clear to me. I found a way to use [Remote()] in model class and then use an action in controller to solve this. But cant apply it.
I expect some brief how to write the code that I mentioned in Controller class and what additional things need to add in view.
Thanks!
You can use a conditional statement combined with .Any() lambda expression.
public JsonResult IsCourseNameExist(string CourseName)
{
if(dbContext.Courses.Any(x => x.CourseName.Trim().ToUpper().Equals(CourseName.Trim().ToUpper())
{
return Json(false);
}
else
{
return Json(true);
}
}
Using .ToUpper() will help this be more efficient, because if your table you have a course name called Math 101.. and the user types in math 101 that might be submitted without error.
Let me know if this helps.

Display Decimal number asp.net MVC [duplicate]

The code below works fine but, in the textbox the decimal value has this format "0,0000"
(, is the decimal separator). I'd like have only 2 decimal. How can I do this ?
Thanks,
//Database model used with NHibernate
public class Bank
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName{ get; set; }
public virtual decimal Amount { get; set; }
}
//MVC Model
public class MyModel
{
public Bank Bank { get; set; }
}
//View
#Html.TextBoxFor(m => m.Bank.Amount, new { id = "tbAmount"})
Update 1
In the debugger, I don't see any decimal, wehn I do step by step inside (o #HTML.Textbofor) the view, the value does not have any decimal but when the page is displayed there are 4 decimals
//Database model used with NHibernate
public class Bank
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName{ get; set; }
public virtual decimal Amount { get; set; }
}
//Class for view
public class ViewBank
{
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public decimal Amount { get; set; }
}
//MVC Model
public class MyModel
{
public Bank Bank { get; set; }
var ViewBank = new ViewBank() { Amount = Bank.Amount};
}
//View
#Html.TextBoxFor(m => m.Amount, new { id = "tbAmount"})
I would use editor templates and I would not use my NHibernate domain models in my views. I would define view models which are specifically tailored to the requirements of the given view (in this case limiting the amount to 2 decimals):
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public decimal Amount { get; set; }
and then:
#Html.EditorFor(m => m.Bank.Amount)
This works for me
#Html.TextBox("Amount", String.Format("{0:0.00}", Model.Bank.Amount), new { id = "tbAmount"})
EDIT:
This is for TextBoxFor (does not work on MVC3)
#{var formated = String.Format("{0:0.00}", Model.Bank.Amount);}
#Html.TextBoxFor(m => m.Bank.Amount, formated, new { id = "tbAmount"})
In MVC 4 you can now pass the format as the second parameter
//View
#Html.TextBoxFor(m => m.Bank.Amount, "{0:n2}", new { id = "tbAmount"})
If you don't have customized editor template for Decimal type then EditorFor decorated with DisplayFormatAttribute would probably work out of the box.
For a custom editor template I ended up using something like:
#model decimal?
#{
string displayValue;
if (Model == null)
{
displayValue = null;
}
else {
var formatString = (ViewData.ModelMetadata).DisplayFormatString;
displayValue = formatString == null ? Model.ToString() : string.Format(formatString, Model);
}
}
<div class="form-group">
#Html.LabelFor(c => c)
#Html.TextBoxFor(c => c, new { type = "text", Value = displayValue, #class = "form-control" })
#Html.ValidationMessageFor(c => c)
</div>
Which works when the property is decorated with DisplayFormatAttribute like so:
[DisplayFormat(DataFormatString = "{0:n1}", ApplyFormatInEditMode = true), Display(Name = "Commission")]
public decimal? CommissionPercentage { get; set; }
This works for me.
in MVC5, in View:
#Html.TextBoxFor(o => o.Amount, "{0:n0}", new { #class = "form-control" })
Output before StringFormatting --> 15000.00
Output after StringFormatting --> 15000

Creating DropDownListFor Using To Tables

I´m having a problem creating a DropDownListFor using a relation between to tables that are related on an entity code first:
public class Motivo_Agenda
{
[Key]
[Required]
public string DESC_MOTIVO { get; set; }
}
public class Agenda // Agenda da produção
{
[Key]
public int ID_AGD { get; set; }
[Required]
public DateTime DATA_AGD { get; set; }
[Display(Name = "De")]
public TimeSpan DE { get; set; }
[Required]
[Display(Name = "Até")]
public TimeSpan ATE { get; set; }
[Required]
public virtual Motivo_Agenda MOTIVO_AGENDA { get; set; }
}
I´m tryng to create a Drop Down List to add a new item to the Agenda Table this is my controller:
bAxaltaModel dbAxalta = new dbAxaltaModel();
// GET: Agenda
public ActionResult Edit()
{
ViewBag.MOTIVO_AGENDA = new SelectList(dbAxalta.Motivos_Agenda, "DESC_MOTIVO", "DESC_MOTIVO");
return View();
}
[HttpPost]
public ActionResult Edit([Bind(Include = "DE,ATE,DATA_AGD,FLAG_SAB_DOM,MOTIVO_AGENDA")]Agenda Agendas)
{
var errors = ModelState.Values.SelectMany(v => v.Errors).ToList();
if (ModelState.IsValid != false)
{
dbAxalta.Agendas.Add(Agendas);
dbAxalta.SaveChanges();
var query = dbAxalta.Agendas.Where(m => m.DATA_AGD == Agendas.DATA_AGD);
TempData["Agendas"] = query.ToList();
return View();
}
ViewBag.MOTIVO_AGENDA = new SelectList(dbAxalta.Motivos_Agenda, "DESC_MOTIVO", "DESC_MOTIVO", Agendas.MOTIVO_AGENDA);
return View();
}
And my DropDown is this:
#Html.DropDownListFor(m => m.MOTIVO_AGENDA, ViewBag.MOTIVO_AGENDA as SelectList, htmlAttributes: new { #class = "form-control" })
But I´m getting the following error:
The parameter conversion from type 'System.String' to type 'Axalta_Project.Models.Motivo_Agenda' failed because no type converter can convert between these types.
Any ideas how can I bind these?
When using DropDownListFor, the first parameter is the selected value so you will need to add this to your model.
Ideally, use a Model class rather than ViewBag in a similar format to the following:
public class MyModel {
public int SelectedAgendaId {get; set;}
public SelectList Agendas {get;set;}
}
Then use something like this:
#Html.DropDownListFor(m => m.SelectedAgendaId, Model.Agendas, htmlAttributes: new { #class = "form-control" })

ASP.NET MVC DropDownList not setting selected value

Consider the following model:
public class TagType
{
public int Id { get; set; }
public string Description { get; set; }
}
public class Tag
{
public int Id { get; set; }
public string Description { get; set; }
public TagType TagType { get; set; }
public DropDownListViewModel TagTypeViewModel { get; set; }
public int TagTypeId { get; set; }
}
I have the following Action in a controller:
public ActionResult Edit(int id)
{
// Load from database
IEnumerable<TagType> tagTypes = TagTypeDal.GetAll().ToList();
Tag tag = TagDal.Get(id);
tag.TagTypeViewModel = new DropDownListViewModel();
tag.TagTypeViewModel.Items = new List<SelectListItem>();
tag.TagTypeViewModel.Items.Add(new SelectListItem { Text = "None", Value = "-1" });
tag.TagTypeViewModel.Items.AddRange(tagTypes
.Select(tt => new SelectListItem
{
Text = tt.Description,
Value = tt.Id.ToString(),
Selected = tt.Id == tag.TagType.Id
}).ToList());
return View(tag);
}
The select list has one element that has Selected=true, and it's not the first element.
And on my Edit.cshtml I have:
#model Models.Tag
#Html.DropDownListFor(model => model.TagTypeId,
#Model.TagTypeViewModel.Items,
new { #class = "form-control" })
My problem is that the generated drop down never selects the element that has Selected=true, it always shows the first element.
Am I calling the wrong overload for DropDownListFor? Or am I building the select list wrong? Or is it somethig else?
You should fill model.TagTypeId with selected TagTypeId in your Controller.
DropDownListFor selected value depends on first parameter value.

Categories