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