Simple form post always sends null to controller - c#

I have no idea what's the reason, it's so straight and simple, but, curiously, doesn't work. I always recieve NULL as model in controller.
Here is the code:
Model
public class EnrolleePlaces
{
[HiddenInput(DisplayValue=false)]
public int id { get; set; }
public string SpecialtyCode { get; set; }
public string Specialty { get; set; }
public int Places { get; set; }
}
Controller
public ViewResult EditPlaces(int id)
{
return View(repo.EnrolleePlaces.FirstOrDefault(p => p.id == id));
}
[HttpPost]
public ActionResult NewPlaces(EnrolleePlaces places) // 'places' is ALWAYS null
{
if (ModelState.IsValid)
{
repo.SaveEnrolleePlaces(places);
return RedirectToAction("Settings");
}
return View("EditPlaces", places);
}
public ViewResult CreatePlaces()
{
return View("EditPlaces", new EnrolleePlaces());
}
And a view
#model Domain.Entities.EnrolleePlaces
#{
Layout = null;
}
Edit: #Model.Specialty
#using (Ajax.BeginForm("NewPlaces", "Enrollee", new { area = "Admin" },
new AjaxOptions() { UpdateTargetId = "AdminContent" } ,
new { enctype = "multipart/form-data" }))
{
#Html.EditorForModel()
// here is input type="submit"
}
I have over 15 controllers in my project, made by the same pattern, but only this one is strange

have you tried changing the name of the parameter that your action method receives ?
for example:
[HttpPost]
public ActionResult NewPlaces(EnrolleePlaces dd) // any name other than "places"
{
if (ModelState.IsValid)
{
repo.SaveEnrolleePlaces(places);
return RedirectToAction("Settings");
}
return View("EditPlaces", places);
}

Related

Redirect to action pass complex model

I want to pass to RedirectToAction model with List type property
For example, I have this simple model:
public class OrgToChooseFrom
{
public string OrgId { get; set; }
public string FullName { get; set; }
}
And complex model as this:
public class SelectCounteragentViewModel
{
public List<OrgToChooseFrom> Counteragents { get; set; }
public OrgToChooseFrom SelectedOrg { get; set; }
}
When I pass simple model with RedirectToAction every value is in place
[HttpGet]
public IActionResult ConfirmChoice(OrgToChooseFrom vm)
{
return View(vm);
}
But when I try to pass complex model SelectCounteragentViewModel, there are empty list and null for the "SelectedOrg" field
[HttpGet]
public IActionResult SelectFromCAOrganizations(SelectCounteragentViewModel vm)
{
return View(vm);
}
How can I do it?
RedirectToAction cannot pass complex model.You can try to use TempData as
Kiran Joshi said.Here is a demo:
public IActionResult Test()
{
SelectCounteragentViewModel vm = new SelectCounteragentViewModel { Counteragents = new List<OrgToChooseFrom> { new OrgToChooseFrom { OrgId ="1", FullName = "d" } }, SelectedOrg = new OrgToChooseFrom { OrgId = "1", FullName = "d" } };
TempData["vm"] = JsonConvert.SerializeObject(vm);
return RedirectToAction("SelectFromCAOrganizations", "ControllerName");
}
[HttpGet]
public IActionResult SelectFromCAOrganizations()
{
SelectCounteragentViewModel vm = JsonConvert.DeserializeObject<SelectCounteragentViewModel>(TempData["vm"].ToString());
return View(vm);
}

Pass Model into Layout Page MVC

I am doing Web project with MVC 5 . I need pass to some data to layout page (data as Category_id or Category_Name).
I read some answers that say I need to make View Model , but my project must be in MVC and not in MVVM,
Do you any ideas?
Thanks!
you have to create a base view model that you will have to use for ALL your views
using Microsoft.AspNetCore.Mvc.Rendering;
public interface IBaseViewModel
{
public int CategoryId { get; set; }
public List<SelectListItem> CategoryList { get; set; }
}
public class BaseViewModel : IBaseViewModel
{
public int CategoryId { get; set; }
public List<SelectListItem> CategoryList { get; set; }
}
action
public IActionResult Index()
{
var baseViewModel=new BaseViewModel();
InitBaseViewModel(baseViewModel);
return View(baseViewModel);
}
private void InitBaseViewModel(IBaseViewModel baseViewModel)
{
//this is for test
// in the real code you can use context.Categories.Select ....
var items = new List<SelectListItem> {
new SelectListItem {Text = "Category1", Value = "1"},
new SelectListItem {Text = "Category2", Value = "2"},
new SelectListItem {Text = "Category3", Value = "3"}
};
baseViewModel.CategoryList= items;
}
layout
#model IBaseViewModel // you can omit it but I like to have it explicitly
#if(Model!=null && Model.CategoryList!=null && Model.CategoryList.Count > 0)
{
<select class="form-control" style="width:450px" asp-for="CategoryId" asp-items="CategoryList">
}
for another view you can create this action code
public IActionResult MyAction()
var myActionViewModel= new MyActionViewModel {
..... your init code
}
InitBaseViewModel(myActionViewModel);
return View(myActionViewModel)
}
public class MyActionViewModel : BaseViewModel
//or
public class MyActionViewModel : IBaseViewModel
{
public .... {get; set;}
}
You can pass directly a obj to View if you want in this way:
public virtual async Task<IActionResult> Index()
{
var model = await MethodThatRedurnModel();
return View(model);
}

ASP.NET MVC - Hidden Field binded doesn't contain value

I'm having a trouble with my project (ASP.NET MVC 5/AJAX/BOOTSTRAP).
When click on Save button on Page, .Net calls in POST the proper action, but the Hidden Fields for PSATOKEN does not contain value (see #Html.HiddenFor(m => m.PSAToken) in the View), despite PSAToken contains a GUID value (saw in Debug Mode) in the Controller method.
Let's see some code below.
Many thanks to answerers!
Model
public interface IPSAPageViewModel
{
String PSAToken { get; set; }
int IdPSAAzienda { get; set; }
}
public abstract class BasePSAPageViewModel : IPSAPageViewModel
{
public String PSAToken { get; set; }
public int IdPSAAzienda { get; set; }
}
public class DatiGeneraliViewModel : BasePSAPageViewModel
{
public DatiGeneraliViewModel()
{
this.Item = new InformazioniGenerali();
}
public Crea.PSA.ServiceLayer.BO.InformazioniGenerali Item { get; set; }
public List<SelectListItem> FormeGiuridicheList { set; get; }
public List<SelectListItem> FormeConduzioneList { set; get; }
}
Controller
private ViewResult ViewPSAPage(IPSAPageViewModel vm)
{
base.createViewBagPaginePrecSucc();
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
[HttpParamAction]
public ActionResult SalvaDatiGeneraliProsegui(DatiGeneraliViewModel vm)
{
return salvataggioDatiGenerali(vm, true);
}
[HttpPost]
[ValidateAntiForgeryToken]
[HttpParamAction]
public ActionResult SalvaDatiGenerali(DatiGeneraliViewModel vm)
{
//Here vm.PSAToken doesn't contain the value setted
return salvataggioDatiGenerali(vm);
}
private ActionResult salvataggioDatiGenerali(DatiGeneraliViewModel vm, bool proseguiCompilazione = false)
{
if (ModelState.IsValid)
{
var resp = aziendeManager.Save(vm.PSAToken, vm.Item, SessionManager.UserIdConnected, CONTROLLERNAME);
if (resp.Success)
{
var psaAzienda = resp.DataObject;
setVarsInSession(psaAzienda.idToken.ToString(), psaAzienda.idPsaAzienda.ToString(), psaAzienda.Aziende.ragioneSociale);
//Here there is some Value (POST)
vm.PSAToken = psaAzienda.idToken.ToString();
//vm.IdPSAAzienda = psaAzienda.idPsaAzienda.ToString();
if (proseguiCompilazione)
return RedirectToAction("DatiAziendaliRiepilogativi", new { id = psaAzienda.idToken });
}
else
ModelState.AddModelError("", resp.Message);
}
setSuccessMessage();
vm.FormeGiuridicheList = aziendeManager.GetAllFormeGiuridiche().ToSelectItems();
vm.FormeConduzioneList = aziendeManager.GetAllFormeConduzione().ToSelectItems();
return ViewPSAPage(vm);
}
View
to see the view click here
Here you can see the value at debug in VS
But in the generated HTML the Hidden Field of PSATOKEN is empty
I found the solution here:
patrickdesjardins.com/blog/… .

ASP.NET MVC Retrieve Data from Database to DropDownList using Select Tag

I'm currently retrieving data from my Database to DropDownList's now using ViewBag as shown below. I have been told and have seen online that it's best to use Strongly Typed instead of ViewBag when using the Select Tag. Can someone please assist me in getting this to work using a ViewModel/Strongly Typed approach? I would greatly appreciate it!! I'm in the process of learning MVC, I have been used to WebForms and having a hard time wrapping my head around the MVC approach :(
Employee Model:
public class Employee
{
[Key]
public int EmpId { get; set; }
[Required]
public string EmpFirstName { get; set; }
[Required]
public string EmpLastName { get; set; }
public int DeptId { get; set; }
public Department Department { get; set; }
public int BldgId { get; set; }
public Building Building { get; set; }
}
EmployeeController:
public class EmployeeController : Controller
{
private DataEntryContext _context;
public EmployeeController(DataEntryContext context)
{
_context = context;
}
public IActionResult Index()
{
return View(_context.Employees.ToList());
}
// Populate Department values to DropDownList
private IEnumerable<SelectListItem> GetDepartments()
{
var dept = _context.Departments
.Select(s => new SelectListItem
{
Value = s.DeptId.ToString(),
Text = s.DeptTitle
})
.ToList();
return (dept);
}
// Populate Building values to DropDownList
private IEnumerable<SelectListItem> GetBuildings()
{
var bldg = _context.Buildings
.Select(b => new SelectListItem
{
Value = b.BldgId.ToString(),
Text = b.BldgName
})
.ToList();
return (bldg);
}
public IActionResult Create()
{
// Load values to DropDownLists for Departments and Buildings
ViewBag.DeptListName = GetDepartments();
ViewBag.BldgListName = GetBuildings();
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Employee employee)
{
if (ModelState.IsValid)
{
_context.Employees.Add(employee);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(employee);
}
public IActionResult Edit(int? id)
{
if (id == null)
{
return View("Error");
//return NotFound();
}
var employee = _context.Employees
.Where(e => e.EmpId == id)
.Single();
if (employee == null)
{
return View("Error");
//return NotFound();
}
ViewBag.DeptListName = GetDepartments();
ViewBag.BldgListName = GetBuildings();
return View(employee);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Employee employee)
{
if (ModelState.IsValid)
{
ViewBag.DeptListName = GetDepartments();
ViewBag.BldgListName = GetBuildings();
_context.Employees.Update(employee);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(employee);
}
}
Employee Create View:
Below is how I'm retrieving the values to the tags below for Departments and Buildings.
<select asp-for="DeptId" asp-items="#ViewBag.DeptListName" class="form-control">
<option>Select Department</option>
</select>
<select asp-for="BldgId" asp-items="#ViewBag.BldgListName" class="form-control">
<option>Select Building</option>
</select>
ViewModels:
{
public class DeptViewModel
{
public int DeptId;
public IEnumerable<SelectListItem> DeptList;
}
}
EmployeeController:
public IActionResult Create()
{
var model = new DeptViewModel { DeptList = DeptList() }; return View(model);
}

display comments and post form on the same page to add new comments

I am building a web application in ASP.NET MVC. I have a comment page where comments are displayed in a list with the latest to oldest and also have a form at the bottom where a user can post new comments.
Form entries should also be highlighted in addition to having the page displaying the latest comments.
Whats the best way to do this, where displayed data and a post form are on the same page?
Is it possible to do this without ajax as well ?
--Code extract--
class CommentsViewModel
{
public IList<Comment> comments { get; set; }
public Comment comment { get; set; }
public SelectList commentCategories { get; set; }
}
class Comment
{
[Required]
public string commentData { get; set; }
[Required]
public int? commentCategory { get; set; }
}
class Comments : Controller
{
public ActionResult Index()
{
Site db = new Site();
CommentsViewModel commenstVm = new
{
comments = db.GetComments(),
comment = new Comment(),
commentCategories = db.GetCommentCategories()
};
return View(commentsVm);
}
[HttpPost]
public ActionResult AddNewComment(CommentsViewModel commentVm)
{
Site db = new Site();
if (!ModelState.IsValid)
{
return View("Index", commentVm);
}
db.AddComment(commentVm.comment);
return RedirectToAction("Index");
}
}
Here's a basic View and the Controller that you can use as a starting point.
Model and ViewModel:
public class CommentsViewModel
{
public IList<Comment> comments { get; set; }
public CommentsViewModel()
{
comments = new List<Comment>();
}
}
public class Comment
{
[Required]
public string commentData { get; set; }
/** Omitted other properties for simplicity */
}
View:
#using (#Html.BeginForm("Index", "Comments"))
{
#Html.TextBoxFor(t => t.comment.commentData)
#Html.ValidationMessageFor(t=> t.comment.commentData, "", new {#class = "red"})
<button name="button" value="addcomment">Add Comment</button>
}
#foreach (var t in Model.comments)
{
<div>#t.commentData</div>
}
Controller:
public class CommentsController : Controller
{
/** I'm using static to persist data for testing only. */
private static CommentsViewModel _viewModel;
public ActionResult Index()
{
_viewModel = new CommentsViewModel();
return View(_viewModel);
}
[HttpPost]
public ActionResult Index(Comment comment)
{
if (ModelState.IsValid)
{
_viewModel.comments.Add(
new Comment() {commentData = comment.commentData});
return View("Index", _viewModel);
}
return RedirectToAction("Index");
}
}

Categories