I have a DropDownListFor that doesn't seem to be setting the expected Model property. Here's the HTML:
#using (Html.BeginForm())
{
#Html.DropDownListFor(x => x.SelectedItem,
new SelectList(Model.ItemList, "Id", "Desc"), null,
new { #class = "selected-list", #size = "3" });
<div>
#Model.SelectedItem
</div>
<input type="submit" value="Do Stuff"
asp-controller="My"
asp-action="DoStuff"
asp-route-itemId="#Model.SelectedItem" />
</div>
}
The div is just there for debugging purposes, and it either shows 0 or blank.
The underlying model has a property:
public int SelectedItem { get; set; }
I've also tried a string:
public string SelectedItem { get; set; } = String.Empty;
(Hence why 0 or blank)
The actual list itself displays fine, it just doesn't update the model on select. How can I get it to update the model?
If you use asp-route-itemId, your action need contains parameter named itemId to receive the value. But for your scenario, it seems to be useless to receive such value, because it will always receive the value you set instead of the dropdown changed value.
Here is a simple demo you could follow and check if any difference with yours:
Model
public class TestVM
{
public string SelectedItem { get; set; } = String.Empty;
public List<Item> ItemList { get; set; }
}
public class Item
{
public int Id { get; set; }
public string Desc { get; set; }
}
View(Index.cshtml)
#model TestVM
#using (Html.BeginForm())
{
#Html.DropDownListFor(x => x.SelectedItem,
new SelectList(Model.ItemList, "Id", "Desc"), null,
new { #class = "selected-list", #size = "3" });
<div>
#Model.SelectedItem
</div>
<input type="submit" value="Do Stuff"
asp-controller="Home"
asp-action="DoStuff" />
}
Controller
[HttpGet]
public IActionResult Index()
{
//Note: hard-coded the model just for easy testing.....
var model = new TestVM()
{
SelectedItem = "1",
ItemList = new List<Item>()
{
new Item(){Id=1,Desc="aa"},
new Item(){Id=2,Desc="bb"},
new Item(){Id=3,Desc="cc"}
}
};
return View(model);
}
[HttpPost]
public IActionResult DoStuff(TestVM model)
{
return View("index", model);
}
Result
Related
I have the following form:
#using (Html.BeginForm())
{
#Html.LabelFor(a => a.SomeText)
#Html.TextBoxFor(a => a.SomeText, new { #class = "form-control" })
#Html.ValidationMessageFor(a => a.SomeText)
<select name="ListOne" id="ListOne">
#foreach (var item in Model.ListOne)
{
<option value="#item.Id">#item.Name</option>
}
</select>
#Html.DropDownListFor(a => a.ListTwo, listTwo, null);
<input type="submit" value="Do Stuff" class="btn-primary"
asp-controller="My" asp-action="DoStuff"/>
. . .
}
On the server side, I have a simple controller method:
public async Task<IActionResult> DoStuff(MyViewModel myViewModel)
{
// ...
}
A breakpoint here shows that neither select list gets passed through, despite them both being visible in the HTML.
The VM looks like this:
public class MyViewModel
{
public string? SomeText { get; set; }
public SelectList? ListOne { get; set; } = new(new List<SelectListItem>());
public SelectList? ListTwo { get; set; } = new(new List<SelectListItem>());
}
ListOne and ListTwo are both null.
Please - could someone tell me why?
This is my form in contact class
<form method="POST">
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="E-mail" name="subid" autofocus="">
</div>
<button href="" class="btn btn-gm btn-success">View</button>
</fieldset>
This is my code in controller and i have view called Contact
[HttpGet]
public ActionResult Contact()
{
return View();
}
[HttpPost]
public ActionResult Contact(string subid)
{
try
{
var webClient = new WebClient();
string url = string.Format(BASE_URL + "Subjectstatus/{0}", subid);
var json = webClient.DownloadString(url);
var js = new JavaScriptSerializer();
ViewBag.attendlist = js.Deserialize<List<attendlist>>(json);
return View();
}
catch
{
ViewBag.con = "gg";
return null;
}
}
This is my attendlist class
public class attendlist
{
[Display(Name = "ID")]
public string sid { get; set; }
[Display(Name = "Name")]
public string name { get; set; }
[Display(Name = "Subject")]
public string sub { get; set; }
[Display(Name = "Date")]
public string date { get; set; }
}
This is Contact View im trying to loop it using for each
#foreach (var dd in ViewBag.attendlist)
{
<h3>#dd.ID</h3>
}
This is the error when im try to load contact view
[HttpGet]
public ActionResult Contact()
{
return View( new ViewContact() );
}
[HttpPost]
public ActionResult Contact(ViewContact contact)
{
try
{
var webClient = new WebClient();
string url = string.Format(BASE_URL + "Subjectstatus/{0}", contact.subid);
var json = webClient.DownloadString(url);
var js = new JavaScriptSerializer();
attendlist list= js.Deserialize<attendlist>(json)
contact.attendlist = list;
return View(contact);
}
catch
{
ViewBag.con = "gg";
return null;
}
}
Class ViewContact
public class ViewContact
{
public attendlist list { get; set; }
public string subid { get; set; }
}
And the foreach at the view
foreach(var dd in Model.list){
//your html view code
}
The view
<form method="POST">
<fieldset>
<div class="form-group">
#Html.TextBoxFor(m => m.subid, new { #class = "form-control", #placeholder = "Email" }) >
</div>
<button href="" class="btn btn-gm btn-success">View</button>
</fieldset>
*Note textboxfor , get the model atributte and it bind later it correctly to the action submit
*Note that now you have to pass a contect not a string to Contact(ViewContact contact) action
I am trying to save some changes to a database.
The view gets a Model, and should be able to make changes and have them saved. However, when i submit the form, the ContactInfo parameter in the post method is not null, but all the properties are.
I'm using MVC5 with Razor. the script is in a seperate .ts-file
In controller:
[HttpPost]
public bool SaveInfoChanges(ContactInfo editedContactInfo)
{
// Save data
return true;
}
Script:
export function saveInfoChanges() {
$("#EditContactInfoForm").submit();
};
HTML:
#if (true)
{
#using (Html.BeginForm("SaveInfoChanges", "ContactInfoBox", FormMethod.Post, new { id = "EditContactInfoForm" }))
}
<table>
#Html.HiddenFor(model => model.Name)
#Html.HiddenFor(model => model.Address1)
#Html.HiddenFor(model => model.Address2)
#Html.HiddenFor(model => model.ZipAndCity)
#Html.HiddenFor(model => model.Country)
<tr>
<td>test</td>
<td>
#Html.TextBoxFor(model => model.Address3, new { id = "ContactTypeInput", placeholder = "", style = "width:300px" })
</td>
</tr>
</table>
}
}
Model:
public class ContactInfo
{
public string ContactInfoBoxHeaderText { get; set; }
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string ZipAndCity { get; set; }
public string Country { get; set; }
}
I can't think of more relevant information to give, but please don't hesitate to ask.
Thanks in advance!
Removing the #if solved the problem. I just need to find another way to hide/show the elements.
Problem:
Hello I'm having troubles all of a sudden with my DropDownListFor which was working just fine. I was styling my web app a bit but didn't change anything on dropdownlistfor
<!-- Genre -->
<div class="form-group">
#Html.LabelFor(m => m.Genre)
#Html.DropDownListFor(m => m.Genre, new SelectList(Model.Genres.OrderBy(n=>n.Name), "Id", "Name"), "Select Genre", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Genre)
</div>
And in Controller
[Authorize]
public ActionResult Create()
{
var viewModel = new GigFormViewModel
{
Genres = _context.Genres.ToList()
};
return View(viewModel);
}
Okay so, here's the visual of my problem:
Blank display box
Yet the item is selected and will save properly to database
So it's just visual thing that bothers me..saving and everything else is working just fine.
I even inspected element and color of the items are black tried to change background of display box in case font is white so I can see it but nope, the selection just does not display at all.
Edit: Viewmodel ->
public class GigFormViewModel
{
[Required]
public string Name { get; set; }
[Required]
public string Venue { get; set; }
[Required]
[FutureDate]
public string Date { get; set; }
[Required]
[ValidTime]
public string Time { get; set; }
[Required]
public int Genre { get; set; }
public IEnumerable<Genre> Genres { get; set; }
public DateTime GetDateTime()
{
return DateTime.Parse(string.Format("{0} {1}", Date, Time));
}
And Genre class
public class Genre
{
public byte Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
}
Try with this change
#Html.DropDownListFor(m => m.Genre, new SelectList(Model.Genres.OrderBy(n=>n.Name), "Id", "Name",0), "Select Genre", new { #class = "form-control" })
may be it will work for you..;)
this is my models:
public class Ressource
{
[Key]
public int RessourceId { get; set; }
public string TitreR { get; set; }
public string Link { get; set; }
public string Type { get; set; }
public string Desc { get; set; }
public int Position { get; set; }
public int Rating { get; set; }
public string Tags { get; set; }
public int SectionId { get; set; }
public int UserId { get; set; }
}
public class Section
{
[Key]
public int SectionId { get; set; }
public string Titre { get; set; }
public String Tags { get; set; }
public virtual ICollection<Ressource> Ressources { get; set; }
}
public class structure
{
public Ressource ress;
public List<string> liste;
}
In this view, I enter the resource's title (TitreR), a description (Desc) and I choose from a list of tags which ones I want to link with this resource as well as entering a tag:
#model Mocodis.Models.structure
#{
ViewBag.Title = "AjouterRessource";
}
<h2>AjouterRessource</h2>
#using (Html.BeginForm("AjouterRessource", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<input type="hidden" name="SectionId" value="#Model.ress.SectionId" />
<legend>Ressource</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ress.TitreR)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ress.TitreR)
#Html.ValidationMessageFor(model => model.ress.TitreR)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ress.Desc)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ress.Desc)
#Html.ValidationMessageFor(model => model.ress.Desc)
</div>
</fieldset>
}
<form id="orderProductForm219" name="orderProductForm219" method="post" >
<b>Choisir les mots clés:</b>
<br /><br />
#foreach (string s in #Model.liste)
{
<input type="checkbox" name="tags[]" value="#s"> #s<br />
}
<input type="text" name="tags" id="tags" value="" />
<p>
<input type="submit" value="Create" />
<input type="hidden" name="tag" value="tags" />
<input type="hidden" name="res" value="#Model.ress" />
</p></form>
(I didnt put the javascript for it)
Finally the controllers are:
public ActionResult AjouterRessource(int SectionId)
{
Ressource res = new Ressource();
res.SectionId = SectionId;
Section sec = _db.Sections.Where(r => r.SectionId == SectionId).FirstOrDefault();
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
List<string> l = new List<string>();
l = sec.Tags.Split(delimiterChars).ToList();
structure s = new structure();
s.ress = res;
s.liste = l;
return View(s);
}
public string Check ( string list, string s)
{
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
List<string> l = new List<string>();
List<string> liste = new List<string>();
l = s.Split(delimiterChars).ToList();
liste = list.Split(delimiterChars).ToList();
foreach (string item in l)
{
if (!liste.Contains(item))
liste.Add(item);
}
return (string.Join(" ", liste.ToArray()));
}
[Authorize]
[HttpPost]
[InitializeSimpleMembership]
public ActionResult AjouterRessource(Ressource res, int SectionId, string tag)
{
if (ModelState.IsValid)
{
res.SectionId = SectionId;
var model = _db.Sections.Where(c => c.SectionId == SectionId).FirstOrDefault();
res.Tags = tag;
model.Tags = Check(model.Tags, tag);
_db.Entry(model).State = EntityState.Modified;
_db.Entry(res).State = EntityState.Added;
_db.SaveChanges();
return RedirectToAction("Section", new { SectionId = SectionId });
}
return View();
}
I keep getting: Object reference not set to an instance of an object on the line: #Html.ValidationSummary(true) in my view. Can you tell me how to fix it please?
Thank you
Every time I have gotten that error it has been from not initializing something. Looking through your code the only spot I am seeing that might need it is when you are setting structure. You might try putting a constructor on that class to initialize the fields and see if that helps. something like
public structure()
{
ress = new Resource();
liste = new List<string>();
}
You probably need to add the { get; set; } to the resource and list under structure as well. Hopefully this helps.