Submitting a form in asp .net MVC, various errors - c#

[HttpGet]
public ActionResult TrafficDate()
{
CalendarModel model = new CalendarModel();
model.SelectedDate = DateTime.Today;
model.EditMode = false;
//model.TrafficDates = TrafficData.GeTrafficDatesPerMonth(model.SelectedDate);
return View(model);
}
// GET: TrafficDate
[HttpGet]
public ActionResult TrafficDate(DateTime date, bool editMode = false)
{
CalendarModel model = new CalendarModel();
model.SelectedDate = date;
model.EditMode = editMode;
//model.TrafficDates = TrafficData.GeTrafficDatesPerMonth(model.SelectedDate);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TrafficDate(CalendarModel model)
{
The topmost ActionResult was added because it kept complaining that there was no parameterless method. now it complains that there is an ambiguity between the two methods that have HttpGet in the tag above, when I switch the parameterless to be HttpPost instead, then I get the same thing between the two that are HttpPost.
I want my submit button to go to the bottom method of the three. but it seems it wants a parameterless method, does that mean the model is empty when I click submit?
here's a part of the .cshtml file
#model Intern.Models.CalendarModel
#{
ViewBag.Title = "Trafikkalender";
//Layout = "_Layout";
}
<script>
</script>
<form method="post" id="form">
<div id="hiddenFields" hidden="hidden">
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.SelectedDate)
#Html.HiddenFor(m => m.EditMode, new { id = "editMode" })
#Html.HiddenFor(m => m.SubmitMode, new { id = "submitMode" })
#Html.HiddenFor(m => m.RegisterPersonOnThisResourceId, new { id = "registerForResourceId" })
#Html.HiddenFor(m => m.PersonToRegister, new { id = "selectedPerson" })
#Html.HiddenFor(m => m.TimeFrom, new { id = "hiddenTimeFrom" })
#Html.HiddenFor(m => m.TimeTo, new { id = "hiddenTimeTo" })
#Html.HiddenFor(m => m.Message, new { id = "hiddenMessage" })
#Html.HiddenFor(m => m.NewTrafficType, new { id = "hiddenNewTrafficType" })
#Html.HiddenFor(m => m.NewTrafficText, new { id = "hiddenNewTrafficText" })
#Html.HiddenFor(m => m.NewTrafficNumTrains, new { id = "hiddenSelectedNewTrafficNumTrains" })
#Html.HiddenFor(m => m.NewTrafficNumConductors, new { id = "hiddenSelectedNewTrafficNumConductors" })
#Html.HiddenFor(m => m.CopyTraffic, new { id = "hiddenCopyTraffic" })
#Html.HiddenFor(m => m.NewTrafficDate, new { id = "hiddenNewTrafficDate" })
</div>
<div class="panel panel-default">
<div class="panel-body">
<div class="panel-heading">
<h1 id="header" class="page-header">Trafik - #((DayNames)((int)Model.SelectedDate.DayOfWeek)) den #Model.SelectedDate.Day #((MonthNames)Model.SelectedDate.Month) #Model.SelectedDate.Year</h1>
</div>
<div class="row">
<div class="col-md-8"></div>
<div class="col-md-4">
#Html.ActionLink("Föregående dag", "TrafficDate", new { date = Model.SelectedDate.AddDays(-1), editMode = Model.EditMode }, new { #class = "btn btn-primary" })
#Html.ActionLink("Nästa dag", "TrafficDate", new { date = Model.SelectedDate.AddDays(1), editMode = Model.EditMode }, new { #class = "btn btn-primary" })
</div>
</div>
</div>
</div>
<div class="panel">
#if (UserData.isInRole(Convert.ToInt32(User.Identity.Name), "Administratör"))
{
<div class="row">
<div class="col-lg-12">
#Html.ActionLink("Redigera dag(beta)", "ToggleEditMode", "TrafficDate", new { date = Model.TrafficDate.Date, editMode = Model.EditMode }, new { #class = "btn btn-primary" })
<input onclick="javascript: EditDay();" type="button" value="Redigera dag" id="editDayButton" name="editDayButton" class="btn btn-primary" />
<input onclick="javascript: CancelEditDay();" type="button" value="Avsluta redigering" id="cancelEditDayButton" name="cancelEditDayButton" class="btn btn-primary hidden" />
#Html.ActionLink(" ", "PrintDay", new { date = Model.SelectedDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) }, new { #class = "glyphicon glyphicon-print" })
</div>
</div>
}
#if (Model.EditMode)
{
<div class="panel panel-default">
<div class="panel-body">
#for (int ti = 0; ti < Model.TrafficDate.Traffics.Count; ti++)
{
<div class="panel panel-default form-group">
<div class="panel-heading">
#(Html.DropDownListFor(m => m.TrafficDate.Traffics[ti].TrafficType, TrafficData.GetTrafficTypes(Model.TrafficDate.Traffics[ti].TrafficType.ToString()), new { #class = "ddlTrafficType", #id = "ddlTrafficType_" + ti }))
#Html.CheckBoxFor(m => m.TrafficDate.Traffics[ti].Published, new { #class = "cbTrafficPublished", #id = "cbPublished_" + ti }) Publicerad
[<input type="button" value="Radera" class="deleteTraffic btn btn-link NoBorder NoBackGround" data-id="#Model.TrafficDate.Traffics[ti].Id" data-url="#Url.Action("DeleteTraffic")" data-confirm="Är du säker på att du vill radera denna trafik?" />]
<input type="button" class="saveTraffic btn btn-primary btn-sm float-right" value="Spara (#Model.TrafficDate.Traffics[ti].TrafficType.ToString())" data-url="#Url.Action("SaveTraffic")" data-id="#Model.TrafficDate.Traffics[ti].Id" data-confirm="Är du säker på att du vill skriva över de nuvarande inställningarna på denna trafik?" />
<input type="submit" class="btn btn-primary" value="Save traffic (beta)" />
</div>
the submit button is on the second to last line of the code cutout here.
is the problem in my .cshtml file? or have I defined the controller methods wrong in some way? the hiddenfields in the beginning was for a javascript I made to handle the saving of things, but I want to get rid of the javascript and make this the correct way.
Also. the form-group class in the code, I saw that in an example, is that important? do I need that in every div? or is it enough to have it in the div that surrounds the whole block of html involved in the thing I want to submit?

As discussed
[HttpGet]
public ActionResult TrafficDate(DateTime? date, bool? editMode = false)
{
return View();
}
Then remove the parameterless TrafficDate action leaving only your post.
I've tried locally and it seems ok
thanks

Related

Update user Profile in asp.net mvc model is not valid

I'm a beginner to ASP.NET MVC.
I want to update login user profile and I am having a problem. my code says model state is not valid. I've tried every possible solution which I know and also searched on Google.
I'm using Entity Framework and below is my code.
Table name: Userdb
Get action method in the controller:
public ActionResult EditProfile()
{
string username = User.Identity.Name;
Userdb user = db.Userdbs.FirstOrDefault(u => u.u_Email.Equals(username));
Userdb model = new Userdb();
// Personal Details
model.u_Firstname = user.u_Firstname;
model.u_lastname = user.u_lastname;
model.u_dob = user.u_dob;
model.u_mobile = user.u_mobile;
model.u_title = user.u_title;
// this to display data in texbox
ViewBag.u_Email = user.u_Email;
ViewBag.u_Firstname = user.u_Firstname;
ViewBag.u_lastname = user.u_lastname;
ViewBag.u_dob = user.u_dob;
ViewBag.u_mobile = user.u_mobile;
ViewBag.u_title = user.u_title;
// Education Details
model.Degree_level = user.Degree_level;
model.Degree_name = user.Degree_name;
model.Starting_date = user.Starting_date;
model.Completion_date = user.Completion_date;
// Address Details
model.country_name = user.country_name;
model.city_name = user.city_name;
model.Address = user.Address;
model.postal_code = user.postal_code;
// Social Link Details
model.S_fb_url = user.S_fb_url;
model.S_linkedin_url = user.S_linkedin_url;
model.S_github_url = user.S_github_url;
model.S_twitter_url = user.S_twitter_url;
return View(model);
}
Post action method in controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditProfile(Userdb editEntity)
{
if (ModelState.IsValid)
{
string username = User.Identity.Name;
// Get the userprofile
Userdb model =new Userdb();
// Personal Details
model.u_Firstname = editEntity.u_Firstname;
model.u_lastname = editEntity.u_lastname;
model.u_dob = editEntity.u_dob;
model.u_mobile = editEntity.u_mobile;
model.u_title = editEntity.u_title;
ViewBag.u_Email = editEntity.u_Email;
ViewBag.u_Firstname = editEntity.u_Firstname;
ViewBag.u_lastname = editEntity.u_lastname;
ViewBag.u_dob = editEntity.u_dob;
ViewBag.u_mobile = editEntity.u_mobile;
ViewBag.u_title = editEntity.u_title;
// Education Details
model.Degree_level = editEntity.Degree_level;
model.Degree_name = editEntity.Degree_name;
model.Starting_date = editEntity.Starting_date;
model.Completion_date = editEntity.Completion_date;
// Address Details
model.country_name = editEntity.country_name;
model.city_name = editEntity.city_name;
model.Address = editEntity.Address;
model.postal_code = editEntity.postal_code;
// Social Link Details
model.S_fb_url = editEntity.S_fb_url;
model.S_linkedin_url = editEntity.S_linkedin_url;
model.S_github_url = editEntity.S_github_url;
model.S_twitter_url = editEntity.S_twitter_url;
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "Home"); // or whatever
}
return View();
}
View
#model Applicant.Models.Userdb
#{
ViewBag.Title = "EditProfile";
Layout = "~/Views/Shared/_ProfileLayout.cshtml";
}
#using (Html.BeginForm("EditProfile", "Users"))
{
#Html.AntiForgeryToken()
<body>
<div class="container rounded bg-white mt-5 mb-5">
<div class="row">
<div class="col-md-3 border-right">
<div class="d-flex flex-column align-items-center text-center p-3 py-5"><img class="rounded-circle mt-5" width="150px" src="https://st3.depositphotos.com/15648834/17930/v/600/depositphotos_179308454-stock-illustration-unknown-person-silhouette-glasses-profile.jpg"><span class="font-weight-bold">#ViewBag.u_Firstname #ViewBag.u_lastname</span><span class="text-black-50">#ViewBag.u_Email</span><span> </span></div>
</div>
<div class="col-md-5 border-right">
<div class="p-3 py-5">
<div class="d-flex justify-content-between align-items-center mb-3">
<h4 class="text-right">Profile Settings</h4>
</div>
<h6>Personal Detail</h6>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">Name</label>#Html.EditorFor(model => model.u_Firstname, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_Firstname } })</div>
<div class="col-md-6"><label class="labels">Lastname</label>#Html.EditorFor(model => model.u_lastname, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_lastname } })</div>
</div>
<div class="row mt-2">
<div class="col-md-6">
<label class="labels">Gender</label><br />
#Html.RadioButtonFor(model => model.u_Gender, "F")
Female
#Html.RadioButtonFor(model => model.u_Gender, "M")
Male
</div>
<div class="col-md-6"><label class="labels">Designation</label>#Html.EditorFor(model => model.u_title, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_title } })</div>
</div>
<div class="row mt-3">
<div class="col-md-12"><label class="labels">Mobile Number</label>#Html.EditorFor(model => model.u_mobile, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_mobile } })</div>
<div class="col-md-12"><label class="labels">Address</label>#Html.EditorFor(model => model.Addres, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Addres } })</div>
<div class="col-md-12"><label class="labels">Country</label>#Html.EditorFor(model => model.country_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.country_name } })</div>
</div>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">City</label>#Html.EditorFor(model => model.city_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.city_name } })</div>
<div class="col-md-6"><label class="labels">Postal Code</label>#Html.EditorFor(model => model.postal_code, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.postal_code } })</div>
</div>
<hr />
<h6>Education Detail</h6>
<div class="row mt-3">
<div class="col-md-12"><label class="labels">Degree Name</label>#Html.EditorFor(model => model.Degree_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Degree_name } })</div>
<div class="col-md-12"><label class="labels">Degree Level</label>#Html.EditorFor(model => model.Degree_level, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Degree_level } })></div>
</div>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">Starting Date</label>#Html.EditorFor(model => model.Starting_date, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Starting_date } })</div>
<div class="col-md-6"><label class="labels">Completion Date</label>#Html.EditorFor(model => model.Completion_date, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Completion_date } })</div>
</div>
<hr />
<div class="mt-5 text-center">
<input type="submit" value="Save Changes" class="btn" style="background-color:#5777ba; color:#fff;" />
</div>
</div>
</div>
<div class="col-md-4">
<div class="py-5">
<h6>Skills Detail</h6>
<div class="col-md-12"><label class="labels">Skills</label><input type="text" class="form-control" placeholder="experience" value=""></div>
</div>
<div class="">
<h6>Skills Detail</h6>
<div class="col-md-12"><label class="labels">Github Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Linkedin Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Twitter Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Facebook Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
</div>
</div>
</div>
</div>
</body>
}
There are several problems with your view, which could account for the invalid model. If you post the definition of Userdb, complete with any metadata class (if those are still being used) we could see for sure.
First, you aren't putting the necessary name attribute in all your plain input fields. This means they won't get posted to the server as data, so the model binder won't be able to automatically populate those fields in your model.
Second, you've used #Html.EditorFor() in several places, with the identical properties being referenced. This means that what you put in the text box labeled "Name" will be assigned to the u_Firstname field on your model -- but so will what you've put in the "Gender" and "City" fields!
That means that the actual Gender and City properties on your model won't be populated.
Third, you say u_Email is the primary key, but it isn't even posted back from this form.
This brings me to what I suspect the real source of the problem is: your model isn't being fully populated from the form on posting, because you're not collecting all the data. And I'd guess at least some of those properties have Required or other constraints on them that mean leaving them empty isn't allowed. (u_Email is a likely candidate, since it's the primary key.)
If you look at the contents of editEntity while debugging, it will probably be made very clear what's populated and what isn't.
replace this code
db.Entry(model).State = EntityState.Modified;
with
db.Entry(model).State = System.Data.Entity.EntityState.Modified;
the above whole code is true but the main problem is when you change the state of entity EntityState.Modified should be replaced with System.Data.Entity.EntityState.Modified; because EntityState is an object of System.Data.Entity* namespace

MVC Pass value from view to dynamic partial view

I'm trying to make a partial view, which will add dynamically as much fields as I input. I input number of fields, then I want to choose days of week in formed fields and do some work with this data in controller, but I have a problem with passing amount of days in partial view.
Controller :
public class CoursesController : Controller
{
private SchoolContext db = new SchoolContext();
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "CourseId,Name,Language,LanguageProficiency,StartDate,EndDate,TeacherId,NumberOfLessonsPerWeek")] Course course)
{
if (ModelState.IsValid)
{
db.Courses.Add(course);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(course);
}
public ActionResult ShowDaysOfweek(int? countDays)
{
//countDays = 2;
ViewBag.CountDays = countDays;
var days = new List<DayOfWeek> { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };
ViewBag.DaysOfWeek = new SelectList(days);
return PartialView("ShowDaysOfweek");
}
}
In this View I can add patial view by clicking button in script:
#model SchoolManagementSystem.Models.Course
#using (Ajax.BeginForm(new AjaxOptions { }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" }
<div class="form-group">
#Html.Label("Number Of Lessons Per Week", htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-5">
#Html.TextBox("NumberOfLessonsPerWeek", null, htmlAttributes: new { #class = "form-control", #type = "number", #id = "numberOfLessonsPerWeek" })
</div>
<div>
<input type="button" value="Add days" id="Show" class="btn btn-default" />
</div>
</div>
<div id="ShowResults">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<script type="text/javascript">
var url = '#Url.Action("ShowDaysOfweek", "Courses")';
$('#Show').on("click", function () {
var countDays = $('#numberOfLessonsPerWeek').val();
url += '/?countDays=' + countDays;
$('#ShowResults').load(url);
})
</script>
Partial view:
#for (var i = 0; i < ViewBag.CountDays; i++)
{
<div class="form-group">
#Html.Label("Day of week", htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-5">
#Html.DropDownList("DaysOfWeek", (IEnumerable<SelectListItem>)ViewBag.DaysOfWeek, htmlAttributes: new { #class = "form-control", style = "height: 35px" })
</div>
</div>
}
Is it possible to do something? Thanks!
First create the hidden field with partial view url
<input type="hidden" value="#Url.Action("ShowDaysOfweek", "Courses", new { countDays= "numberOfLessonsPerWeek" })" id="hdnURLShowDaysOfweek" />
in javascript read the url and replace the parameter
<script type="text/javascript">
var url = $('#hdnURLShowDaysOfweek').val();
$('#Show').on("click", function () {
url = url.replace("numberOfLessonsPerWeek",$('#numberOfLessonsPerWeek').val());
$('#ShowResults').load(url);
})
</script>

How can I return a view from another model in a controller?

I stumbled across a better way to display my comment form within the post window with <p id="createPostButton">#Html.Action("Create", "Comment", new { id = Model.PostId })</p> (I was originally just trying to create a button to take you to the comment page sending the post id). However, I now get an error when I try to pass back the post/details/{id} view in the CommentController. It keeps trying to look in comment or shared folders passing either post OR details/{id} instead of post/details/{id}.
Post/Details Razor HTML file:
#model FantaC.Models.Post
#{
ViewBag.Title = #Html.DisplayFor(model => model.PostName);
}
<h2>#Html.DisplayFor(model => model.PostName)</h2>
<div class="row">
<div class="col-md-8 whiteBorder scroll">
<div class="postName">
<h4>Written by: #Html.DisplayFor(model => model.UserName)</h4>
<img src="#Html.DisplayFor(model => model.PostImage)" />
</div>
<div class="postContent">
<p>#Html.DisplayFor(model => model.PostContent)</p>
</div>
</div>
<div class="col-md-4 whiteBorder scroll">
<h4>Comments</h4>
#foreach (var comment in Model.PostComments)
{
<h5>#Html.DisplayFor(modelItem => comment.UserName)</h5>
<h5>#Html.DisplayFor(modelItem => comment.CommentSubject)</h5>
<p>#Html.DisplayFor(modelItem => comment.CommentContent)</p>
<p>
#Html.ActionLink("Edit", "../Comment/Edit", new { id = comment.CommentId }) |
#Html.ActionLink("Details", "../Comment/Details", new { id = comment.CommentId }) |
#Html.ActionLink("Delete", "../Comment/Delete", new { id = comment.CommentId })
</p>
}
<p id="createPostButton">#Html.Action("Create", "Comment", new { id = Model.PostId })</p> <!--**********This is the line that is important-->
#*#=Html.RenderAction("Create", "Comments", new { postId = Model.PostId });*#
#*#Html.Partial("Comments")*#
</div>
</div>
<p>
#*#Html.ActionLink("Add a Comment", "Create", "Comment")*#
#Html.ActionLink("Comment", "Create", "Comment", new { id = Model.PostId }, null) |
#Html.ActionLink("Back to List", "Index")
The Comment/Create Razor HTML file that is getting pulled in by the Html.Action:
#model FantaC.Models.Comment
#{
Layout = null;
}
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Comment</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.CommentSubject, htmlAttributes: new { #class = "control-label col-md-10 displayBlock" })
<div class="col-md-12">
#Html.EditorFor(model => model.CommentSubject, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CommentSubject, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommentContent, htmlAttributes: new { #class = "control-label col-md-10 displayBlock" })
<div class="col-md-12">
#Html.EditorFor(model => model.CommentContent, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CommentContent, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
#*<div>
#Html.ActionLink("Back to List", "Index")
</div>*#
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The important section from the CommentController:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(string id, [Bind(Include = "CommentSubject,CommentContent")] Comment model)
{
if (ModelState.IsValid)
{
ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
var commentId = (23817 + db.Comment.Count()).ToString().PadLeft(10, '0');
var comment = new Comment
{
CommentId = commentId,
PostId = id,
UserName = user.UserName,
PostTime = DateTime.Now,
CommentSubject = model.CommentSubject,
CommentContent = model.CommentContent
};
db.Comment.Add(comment);
db.SaveChanges();
return View("Details/" + id, "Post");
}
return View(model);
}
I also tried return View("../post/details/" + id); to no avail. How can I get back up to the post view url (post/details/{id} from the CommentController?
As a side note, I had it almost working by taking out the returns and making the method void, but after clicking the submit comment button the whole comment/create form would disappear. I would be fine going back to that way of doing things if anyone knows a way to make the form stay after clicking the create comment button.
Thanks for any help! :)
Edit:
I forgot to mention that I tried this too. It returns an error that looks like this:
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions.
Source Error:
Line 32: }
Line 33:
Line 34: #Html.Action("Create", "Comment", new { id = Model.PostId })
Line 35:
You should follow the PRG (POST-REDIRECT-GET) pattern. After saving the comment, you should redirect to the post details page.
You may use the RedirectToAction method to return a RedirectResponse back to the browser which will make a new GET request to the post details action method.
So replace
return View("Details/" + id, "Post");
with
return RedirectToAction("Details" , "Post", new {id=id});

Passing a List of objects from Razor View to Controller only passes one item instead of the whole list

I want to pass a List of VoedingBindingModel to my controller by using an Editor Template, however I only receive the first entry of the List in the Controller, never all the entries.
The Controller:
public ActionResult Create()
{
ViewBag.fk_customVoedingId = new SelectList(customvoeding.GetAllCustomvoeding(), "customVoedingId", "customVoedingNaam");
ViewBag.fk_standaardVoedingId = new SelectList(standaardvoeding.GetAllStandaardvoeding(), "standaardVoedingId", "standaardVoedingNaam");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Datum,Tijd,VoedingCollection")]AgendaBindingModel agendaBindingModel)
{
//Do something
}
The Model:
public class AgendaBindingModel
{
[Required]
public List<VoedingBindingModel> VoedingCollection { get; set; }
//More properties
}
The View:
#using Website.Models
#model AgendaBindingModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>agenda</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Datum, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Datum, "{0:dd-MM-yyyy}", new { #class = "form-control-datepicker", placeholder = "DD-MM-YYYY", maxlength = "10" })
#Html.ValidationMessageFor(model => model.Datum, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tijd, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tijd, "{0:hh:mm}", new { htmlAttributes = new { #class = "form-control-timepicker", placeholder = "hh:mm", maxlength = "5" } })
#Html.ValidationMessageFor(model => model.Tijd, "", new { #class = "text-danger" })
</div>
</div>
<div id="CreateVoedingDiv0">
#Html.EditorFor(x => x.VoedingCollection[0])
</div>
<div id="CreateVoedingDiv1"hidden>
#Html.EditorFor(x => x.VoedingCollection[1])
</div>
<div id="CreateVoedingDiv2"hidden>
#Html.EditorFor(x => x.VoedingCollection[2])
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input value="Add" class="btn btn-default" onclick="ShowVoeding()" /> <input value="Remove" class="btn btn-default" onclick="HideVoeding()" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script>
var count = 1;
function ShowVoeding()
{
if (document.getElementById("CreateVoedingDiv" + count).hidden == true)
{
document.getElementById("CreateVoedingDiv" + count).hidden = false;
count++;
}
}
function HideVoeding()
{
count = count - 1;
if (document.getElementById("CreateVoedingDiv" + count).hidden == false) {
document.getElementById("CreateVoedingDiv" + count).hidden = true;
}
}
</script>
Partial class:
(customvoeding and standaardvoeding do the same thing, only customvoeding returns a collection of customvoeding and standaardvoeding returns a collection of standaardvoeding.
public partial class customvoeding
{
private static foodtrackerEntities1 db = new foodtrackerEntities1();
public static List<customvoeding> GetAllCustomvoeding()
{
db.Configuration.LazyLoadingEnabled = false;
return db.customvoeding.ToList();
}
}
You don't seem to be initializing the model and passing it to the view. In the action methods of your controller try adding:
var viewModel = new AgendaBindingModel();
viewModel.VoedingCollection = // TODO: Fill the list from your data source
return View(viewModel );
Try like this. I could not test, but if you like we can advance is this way:
To show all items:
<div id="group">
#for(int i = 0; i < AgendaBindingModel.VoedingCollection.Count; i++)
{
#Html.EditorFor(x => x.VoedingCollection[i])
}
To add new item:
<button onclick=newItem() >+</button>
</div>
<script>
function newItem(){
var div = document.createElement('div');
div.id = CreateNewItem;
div.innerHTML = '#Html.EditorFor(x => x.VoedingCollection[i])';
document.body.appendChild(div);
}
</script>
Your second and third html are broken.
<div id="CreateVoedingDiv2"hidden>
remove hidden
I found out what was preventing me from receiving more than one result:
You can NOT use #Html.EditorFor template for more than 1 value when you specify a template. It does not matter if you use different models or different templates, it just simply does not work.
To fix it, you have to use 'Html.BeginCollectionItem' library, which can be found here.

ASP.NET EnumDropDownListFor generates the DropDown but doesn't select model's value

I have a big problem with my project. I have a ViewModel that has an Enum type attribute : Constants.Days Day ( Monday = 1 to Sunday = 7) that I already use in an Edit View to generate a dropdown list. The model's value is correctly selected in it. I use the EnumDropDownListFor Helper.
In an other View ( a partial view this time generated with the RenderAction helper ) I try to do the same stuff but the DropDown doesn't select model's Day. The first option is selected. I tried with a TextBoxFor and the correct Day is put inside of it. It's very strange... I tried to do a classic DropDownListFor but the result is the same. The value is available, the dropdown is generated correctly, BUT the model's Day value isn't selected in the DropDown. The Update works too.
Can anybody help me please ? Thank you very much :)
Here you can see a screenshot of the View where the Day is correctly put in a TextBox but not selected in the dropdown.
The PartialView :
#model p3t.Models.ScheduledLessonViewModel
<div class="modal" id="#("updateLessonModal" + Model.ScheduledLessonId)" tabindex="-1" role="dialog" aria-labelledby="updateLessonModalLabel">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Planifier un cours</h4>
</div>
#using (Html.BeginForm("UpdateSchedule", "Home"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal ">
<div class="modal-body">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ScheduledLessonId)
<div class="form-group">
#Html.LabelFor(model => model.Day, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Day, htmlAttributes: new { #class = "form-control btn btn-default col-md-10", disabled = "disabled" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Mettre à jour</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
</div>
}
</div>
</div>
The View
#model p3t.Models.ScheduleViewModel
#using p3t.Models.Dal.Dto
#foreach (var lesson in Model.ScheduledLessons)
{
if (lesson.Section.SectionId == Model.Section.SectionId)
{
if (day.Equals(lesson.Day.ToString()) && lesson.BeginHour.Hours == h)
{
Html.RenderAction("UpdateSchedule", lesson);
<div class="lesson">
#if (User.IsInRole("Administrateur") || User.IsInRole("Secrétaire"))
{
<button id="#lesson.ScheduledLessonId" class="pull-left glyphicon glyphicon-cog" data-toggle="modal" data-target="##("updateLessonModal" + lesson.ScheduledLessonId)"></button>
<button id="" class="pull-left glyphicon glyphicon-trash"</button>
}
}
}
}
The Controller's Actions for the View:
public ActionResult UpdateSchedule(ScheduledLessonModel model)
{
ScheduledLessonViewModel slvm = new ScheduledLessonViewModel();
slvm.LessonList = new List<SelectListItem>();
slvm.SectionList = new List<SelectListItem>();
slvm.ClassroomList = new List<SelectListItem>();
var lessonList = lessonRepository.GetAll();
var sectionList = sectionRepository.GetAll();
var classroomList = classroomRepository.GetAll();
foreach (var item in lessonList)
{ slvm.LessonList.Add(new SelectListItem { Value = item.LessonId.ToString(), Text = item.Name }); }
foreach (var item in sectionList)
{ slvm.SectionList.Add(new SelectListItem { Value = item.SectionId.ToString(), Text = item.Tag }); }
foreach (var item in classroomList)
{ slvm.ClassroomList.Add(new SelectListItem { Value = item.ClassroomId.ToString(), Text = item.Name }); }
slvm.ScheduledLessonId = model.ScheduledLessonId;
slvm.Day = model.Day;
slvm.BeginHour = model.BeginHour;
slvm.EndHour = model.EndHour;
slvm.Quadrimester = model.Quadrimester;
slvm.LessonId = model.Lesson.LessonId;
slvm.SectionId = model.Section.SectionId;
slvm.ClassroomId = model.Classroom.ClassroomId;
return PartialView("ScheduleModal", slvm);
}
[HttpPost]
public ActionResult UpdateSchedule(ScheduledLessonViewModel slvm)
{
try
{
ScheduledLessonModel slmodel = new ScheduledLessonModel();
slmodel.Lesson = new LessonModel();
slmodel.Section = new SectionModel();
slmodel.Classroom = new ClassroomModel();
slmodel.ScheduledLessonId = slvm.ScheduledLessonId;
slmodel.Day = slvm.Day;
slmodel.BeginHour = slvm.BeginHour;
slmodel.EndHour = slvm.EndHour;
slmodel.Quadrimester = slvm.Quadrimester;
slmodel.Lesson.LessonId = slvm.LessonId;
slmodel.Section.SectionId = slvm.SectionId;
slmodel.Classroom.ClassroomId = slvm.ClassroomId;
scheduledLessonRepository.Update(slmodel);
return RedirectToAction("Schedule", new { sectionId = slvm.SectionId });
}
catch (Exception)
{
throw;
}
}
In your Schedule GET action, try setting vm.Day to whatever value you want your drop down to have selected.

Categories

Resources