Creating DropDownListFor Using To Tables - c#

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" })

Related

System.Web.Mvc.WebViewPage<T>.Model.get returned null

I am trying to create my first ASP.NET MVC application but since two days I cannot solve my problem.
I am using Entity Framework Code First approach. I want to create DropDownListFor but there is always this error:
System.NullReferenceException
System.Web.Mvc.WebViewPage.Model.get returned null.
My Model:
public class Animals
{
public int AnimalsId { get; set; }
public int ClientsId { get; set; }
public string Name { get; set; }
public int TypesId { get; set; }
public float Age { get; set; }
public float Weight { get; set; }
public virtual Types Types { get; set; }
public IEnumerable<Clients> ClientsList { get; set; }
public virtual ICollection<BookVisit> AnimalsVisits { get; set; }
}
My controller:
public ActionResult Create([Bind(Include = "AnimalsId, ClientsId, Name, TypesId, Age, Weight")] Animals animals)
{
var person = new List<Clients>
{
new Clients { ClientsId = 50, Name = "Timo", Surname = "Werner", Email = "timo.werner#gmail.com", Phone = 123123123 }
};
var animalsView = new Animals
{
ClientsList = person.Select(x => new Clients
{
ClientsId = x.ClientsId
})
};
if (ModelState.IsValid)
{
db.Animals.Add(animals);
db.SaveChanges();
return RedirectToAction("List", "Animal");
}
return View(animalsView);
}
My view (only #model and dropdown):
#model xyz.Models.Animals
#Html.DropDownListFor(model => model.ClientsId, new SelectList(Model.ClientsList, "ClientsId", "Name", "Surname", "Email", "Phone"))
Could you please take a look ?
From the comments, it looks like you are not passing a valid view model object to the view. Your view code is expecting a valid model passed to it and the helper methods are using different properties of that.
public ActionResult Create()
{
var clients = new List<Clients>
{
new Clients { ClientsId = 50, Name = "Timo" },
new Clients { ClientsId = 51, Name = "Microsoft" }
};
var vm = new Animals
{
ClientsList = clients
};
return View(vm);
}
Also your current code which calls the DropDownListFor is wrong. When you create a SelectList from a collection, you have to pass the dataValue field and dataText fields.
#model Animals
#Html.DropDownListFor(model => model.ClientsId,
new SelectList(Model.ClientsList, "ClientsId", "Name"))
This error may also be caused by trying to use a null model in razor view. In such case check if the model is null or not before using it as shown below:
#if (Model != null) {
<a onclick="get('#Url.Action("GetEmployee", "DemoController")', #Model.Id)" ></a>
}

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

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.

Save data from dropdownlist using selectlist

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;}
............
............
}

Fill one property of class by selecting one value on dropdownlist of another model

I have a class Client that have some properties in particular one is restriction_type. Also, I create another class Restriction with an ID and a name properties. The name property correspond to the restriction_type.
Then I display the name of all restrictions in my database in the dropdown list:
#Html.ActionLink("Create New", "Create")
#using (Html.BeginForm("AddRestrictions","Restrictions",FormMethod.Get)){
<p> Type de restriction:
#Html.DropDownList("ClientRestr_type", "All")
</p>
<input type="submit"value="Ajouter"/>
}
That is my controller:
public ActionResult AddRestriction(string ClientRestr_type, Restriction restriction)
{
var RestrLst = new List<string>();
var RestrQry = from d in db.Restrictions
orderby d.name
select d.name;
RestrLst.AddRange(RestrQry.Distinct());
ViewBag.ClientRestr_type = new SelectList(RestrLst);
var clients = from c in db.Restrictions select c;
if (string.IsNullOrEmpty(ClientRestr_type))
return View();
else
{
if (ModelState.IsValid)
{
// Here I have maybe to find the way to solve my problem
}
}
So I want to add the name property of Restriction in the restriction_type property of my Model Client.
Model Client:
public class Client
{
[Required]
public int ID
{
get;
set;
}
[Required]
public string compte
{
get;
set;
}
[Required]
public string portefeuille
{
get;
set;
}
[Required]
public String restriction_type
{
get;
set;
}
[Required]
public Boolean etat
{
get;
set;
}
public Boolean decision
{
get;
set;
}
Model Restriction:
public class Restriction
{
public int restrictionID
{
get;
set;
}
public string name
{
get;
set;
}
}
What do you think about my GetRestrictions() method
private SelectList GetRestrictions()
{
var RestrLst = new List<string>();
var RestrQry = from d in db.Restrictions
orderby d.name
select d.name;
RestrLst.AddRange(RestrQry.Distinct());
return new SelectList(RestrLst);
}
But unfortunately I have an error: Impossible to convert System.Web.Mvc.SelectList to MyApp.Models.Client at line:
model.RestrictionList = GetRestrictions();
I don't understand why
Thank you for your help!
A simplified example:
View model
public class ClientVM
{
public Client Client { get; set; }
public SelectList RestrictionList { get; set; }
}
Controller
[HttpGet]
public ActionResult Create()
{
ClientVM model = new ClientVM();
model.Client = new Client();
model.RestrictionList = GetRestrictions(); // your code to return the select list
return View("Edit", model);
}
[HttpGet]
public ActionResult Edit(int ID)
{
ClientVM model = new ClientVM();
model.Client = // call database to get client based on ID
model.RestrictionList = GetRestrictions();
return View(model);
}
[HttpPost]
public ActionResult Edit(ClientVM model)
{
if (!ModelState.IsValid)
{
model.RestrictionList = GetRestrictions();
return View(model);
}
Client client = model.Client;
// Save and redirect
....
}
View
#model YourNamespace.ClientVM
#using (Html.BeginForm() {
#Html.TextBoxFor(m => m.Client.ID)
#Html.TextBoxFor(m => m.Client.compte)
...
#Html.DropDownListFor(m => m.Client.restriction_type, Model.RestrictionList)
<input type="submit" value="Save" />
}

Categories