Please I need some help, on the adding new movie. I am facing an issue with [HttpPost] and I really don't know if it from it or not, but when I remove [HttpPost] the page is working.
My NewMovie View:
#model Vildy4.ViewModels.MovieFormViewModel
#{
ViewBag.Title = "NewMovie";
}
<h2>New Movie</h2>
#using (Html.BeginForm("NewMovie", "Movies"))
{
<div class="form-group">
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.ReleaseDate)
#Html.TextBoxFor(m => m.ReleaseDate, "{0: d MMM yyyy}", new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.Genres)
#Html.DropDownListFor(m => m.GenresId, new SelectList(Model.Genres, "Id", "Name"), "Select Genre", new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.NumberInStock)
#Html.TextBoxFor(m => m.NumberInStock, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.NumberInStock)
</div>
#Html.HiddenFor(m => m.Id)
<button type="submit" class="btn btn-primary">Save</button>
}
My Action:
[HttpPost]
public ActionResult NewMovie(Movie movie)
{
if (!ModelState.IsValid)
{
var viewModel = new MovieFormViewModel(movie)
{
Genres = _context.Genres.ToList()
};
return View("NewMovie", viewModel);
}
if (movie.Id == 0)
{
movie.DateAdded = DateTime.Now;
_context.Movies.Add(movie);
}
else
{
var movieInDb = _context.Movies.Single(m => m.Id == movie.Id);
{
movieInDb.Name = movie.Name;
movieInDb.Genre = movie.Genre;
movieInDb.ReleaseDate = movie.ReleaseDate;
movieInDb.DateAdded = movie.ReleaseDate;
movieInDb.NumberInStock = movie.NumberInStock;
}
}
_context.SaveChanges();
return RedirectToAction("Index", "Movies");
}
Error:
Server Error in '/' Application.
The resource cannot be found.
Description:HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Movies/NewMovie
When I remove [HttpPost] it is working normally, but I can not post.
I checked many threads (e.g. asp.net mvc 4 [HttpPost] not working) but it does not solve the issue.
I have another Controller with almost the same action and it works perfect.
Movie model:
public class Movie
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
[Required]
public string Genre { get; set; }
[Display(Name = "Genre")]
[Required]
public byte GenresId { get; set; }
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime ReleaseDate { get; set; }
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime DateAdded { get; set; }
[Required]
[Range(1,20)]
public int NumberInStock { get; set; }
}
MovieFormViewModel code:
public class MovieFormViewModel
{
public IEnumerable<Genre> Genres { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int? Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Display(Name = "Genre")]
[Required]
public byte? GenresId { get; set; }
[Display(Name = "Release Date")]
[Required]
public DateTime? ReleaseDate { get; set; }
[Display(Name = "Number in Stock")]
[Range(1, 20)]
[Required]
public int? NumberInStock { get; set; }
public string Title
{
get
{
return Id != 0 ? "Edit Movie" : "New Movie";
}
}
public MovieFormViewModel()
{
Id = 0;
}
public MovieFormViewModel(Movie movie)
{
Id = movie.Id;
Name = movie.Name;
ReleaseDate = movie.ReleaseDate;
NumberInStock = movie.NumberInStock;
GenresId = movie.GenresId;
}
}
Here is the Headers:
Request URL: http://localhost:3593/Movies/NewMovie
Request Method: GET
Status Code: 404 Not Found
Remote Address: [::1]:3593
Referrer Policy: no-referrer-when-downgrade
here is also the route in my application, which is the default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
on the Source Page after getting the error, I noticed that I am getting the below Exception:
[HttpException]: A public action method 'NewMovie' was not found on controller 'Vildy4.Controllers.MoviesController'.
I also searched but I could not find the solution, because action is there in the controller and when i do [HttpGet] it is working only [HttpPost] not working!
Related
I try to update one property in table from SelectedList
Here is my model
public partial class Interwier
{
[Key]
public int Interwier_id { get; set; }
[Display(Name = "ФИО")]
public string FIO { get; set; }
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "Телефон")]
public string Telephone { get; set; }
[Display(Name = "День рождения")]
public System.DateTime Birthday { get; set; }
[Display(Name = "Город")]
public string City { get; set; }
[Display(Name = "Зарплата")]
public string Salary { get; set; }
[Display(Name = "Английский язык")]
public string English { get; set; }
public Nullable<int> VacancyId { get; set; }
public string Status { get; set; }
public virtual Vacancy Vacancy { get; set; }
}
I need to update Status property.
Here is Edit action in controller
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Interwier interwierModel = db.InterwierModels.Find(id);
if (interwierModel == null)
{
return HttpNotFound();
}
return View(interwierModel);
}
// POST: Interwier/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Email,Telephone,Birthday,City,Salary,English,Status")] Interwier interwierModel)
{
if (ModelState.IsValid)
{
db.Entry(interwierModel).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Incoming");
}
return View(interwierModel);
}
And here is how it looks on View
<div class="form-group" style="padding-left: 515px;">
<div class="col-md-10">
#Html.DropDownListFor(model => model.Status, new[]
{
new SelectListItem() {Text = "Подтвердить", Value = "Одобрено"},
new SelectListItem() {Text = "Отправить в архив", Value = "Архив"},
}, "Статус", new { #class = "form-control" })
</div>
</div>
When I click submit button I have this error
How I can handle this?
You need to include Interwier_id property as hidden field. Use HiddenFor extension method. You don't post the ID to server that's why EF cannot find the entity in DB. Assuming the code below is within the BeginForm block.
#Html.DropDownListFor(model => model.Interwier_id)
<div class="form-group" style="padding-left: 515px;">
<div class="col-md-10">
#Html.DropDownListFor(model => model.Status, new[]
{
new SelectListItem() {Text = "Подтвердить", Value = "Одобрено"},
new SelectListItem() {Text = "Отправить в архив", Value = "Архив"},
}, "Статус", new { #class = "form-control" })
</div>
</div>
And also update properties that you bind from Id to Interwier_id:
[Bind(Include = "Interwier_id,...")]
I'm getting a validation error message on my DropDownList within my Create Action if I click the submit button without selecting a value from the DropDownList.
The validation error that I'm getting is The value "" is invalid. I would like the validation error message to say State is required! instead.
I added the required validation attribute to the StId property on the ViewModel but that did not resolve the issue.
Customer Model
public class Customer
{
public int CustId { get; set; }
public string CustFirstName { get; set; }
public string CustLastName { get; set; }
public int StId { get; set; }
public State State { get; set; }
}
State Model
public class State
{
public int StId { get; set; }
public string StAbbr { get; set; }
public List<Customer> Customers { get; set; }
}
CustomerFormViewModel
public class CustomerFormViewModel
{
public int CustId { get; set; }
[Required(ErrorMessage = "First Name is required!")]
[Display(Name = "First Name")]
public string CustFirstName { get; set; }
[Required(ErrorMessage = "Last Name is required!")]
[Display(Name = "Last Name")]
public string CustLastName { get; set; }
[Required(ErrorMessage = "State is required!")]
[Display(Name = "State")]
public int StId { get; set; }
public IEnumerable<State> States { get; set; }
}
CustomerController
public class CustomerController : Controller
{
private OneClickAwayDbContext _context;
public CustomerController(OneClickAwayDbContext context)
{
_context = context;
}
public ActionResult Index()
{
return View(_context.Customers.ToList());
}
public ActionResult Create()
{
var states = _context.States.ToList();
var viewModel = new CustomerFormViewModel
{
States = states
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormViewModel vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.CustFirstName = vm.CustFirstName;
customer.CustLastName = vm.CustLastName;
customer.StId = vm.StId;
}
_context.Customers.Add(customer);
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
var stateViewModel = new CustomerFormViewModel
{
States = _context.States.ToList()
};
return View("Create", stateViewModel);
}
}
}
Create.chtml
#using (Html.BeginForm("Create", "Customer"))
{
<div class="form-group">
#Html.LabelFor(c => c.CustFirstName)
#Html.TextBoxFor(c => c.CustFirstName, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustFirstName)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustLastName)
#Html.TextBoxFor(c => c.CustLastName, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustLastName)
</div>
<div class="form-group">
#Html.LabelFor(s => s.StId)
#Html.DropDownListFor(s => s.StId, new SelectList(Model.States, "StId", "StAbbr"), "", new { #class="form-control"})
#Html.ValidationMessageFor(s => s.StId)
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
}
Please include jquery.validate.js and jquery.validate.unobtrusive.js in your cshtml file
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
add this line in web.config
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
include following jquery file in your layout page.
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
Using this your submit button click event is not going to your [HttpPost] Action of your view if any validation are required.
I am very new to MVC5 and JQuery and I trying to create a cascading drop down. When the user selects a Practice from the drop down I am trying to get the Opticians that work in that Practice to populate.
Optician Model:
public class Optician
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid OpticianId { get; set; }
[ForeignKey("User")]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
public IEnumerable<SelectListItem> UserList { get; set; }
[ForeignKey("Practice")]
public Guid PracticeId { get; set; }
public virtual Practice Practice { get; set; }
public IEnumerable<SelectListItem> PracticeList { get; set; }
public virtual ICollection<ApplicationUser> Users { get; set; }
public virtual ICollection<Practice> Practices { get; set; }
}
Practice Model:
public class Practice
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Display(Name = "Practice")]
public Guid PracticeId { get; set; }
[Display(Name = "Practice Name")]
public string PracticeName { get; set; }
public virtual ICollection<Optician> Opticians { get; set; }
public virtual ICollection<Booking> Bookings { get; set; }
}
Application User Model:
public class ApplicationUser : IdentityUser
{
[Display(Name = "Title")]
public string Title { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
}
Controller :
public ActionResult TestDropDown()
{
var PracticeListItems = (from d in db.Practices
select d.PracticeName).ToList();
SelectList Practice = new SelectList(PracticeListItems);
ViewData["Practice"] = Practice;
return View();
}
public JsonResult Opticians(Guid? Id)
{
var OpticianList = (from d in db.Opticans
where d.PracticeId == Id
select d.User.FirstName).ToList();
return Json(OpticianList);
}
The View:
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script>
$(document).ready(function () {
$("#Optician").prop("disabled", true);
$("#Practice").change(function () {
if ($("#Practice").val() != "Select") {
var PracticeOptions = {};
PracticeOptions.url = "/Bookings1/Opticians";
PracticeOptions.type = "POST";
PracticeOptions.data = JSON.stringify({ Practice: $("#Practice").val() });
PracticeOptions.datatype = "json";
PracticeOptions.contentType = "application/json";
PracticeOptions.success = function (OpticianList) {
$("#Optician").empty();
for (var i = 0; i < OpticianList.length; i++) {
$("#Optician").append("<option>" + StatesList[i] + "</option>");
}
$("#Optician").prop("disabled", false);
};
PracticeOptions.error = function () { alert("Error in getting Practices"); };
$.ajax(PracticeOptions);
}
else {
$("#Optician").empty();
$("#Optician").prop("disabled", true);
}
});
});
#using (Html.BeginForm("TestDropDown", "Bookings1", FormMethod.Post))
{
#Html.AntiForgeryToken()
<h4>Select Practcie & Opticians</h4>
<hr />
#Html.ValidationSummary()
<div class="form-group">
#Html.Label("Select Practice :", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownList("Practice", ViewData["Practices"] as SelectList, new { #class = "form-control" })
</div>
</div><br />
<div class="form-group">
#Html.Label("Select Optician :", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<select id="Optician"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Submit" />
</div>
</div>
}
However, when I run the application the Practice Name populates but the Optician First Name does not. There are no errors and I am unsure of where I am going wrong. Any help would be greatly appreciated.
Seems like you have a few issues with your code.. Starting with your SelectList.
When you define your select list it helps if you tell it what your Value and Text properties are..
public ActionResult TestDropDown()
{
var practices = new SelectList(db.Practices, "PracticeId", "PracticeName");
ViewData["Practices"] = practices;
return View();
}
Then you should probably return more information in your Opticians json result
[HttpPost]
public JsonResult Opticians(Guid? Id)
{
var opticianList = db.Opticians.Where(a => a.PracticeId == Id).Select(a => a.User).ToList();
return Json(opticianList);
}
In your javascript once you get the names sorted out out you can reference the property FirstName of the result.
$(document).ready(function () {
$("#Optician").prop("disabled", true);
$("#Practice").change(function () {
$.ajax({
url = "#Url.Action("Opticians","Bookings1")",
type = "POST",
data = {Id : $(this).val() }
}).done(function(OpticianList){
$("#Optician").empty();
for (var i = 0; i < OpticianList.length; i++) {
$("#Optician").append("<option>" + OpticianList[i].FirstName + "</option>");
}
$("#Optician").prop("disabled", false);
});
});
});
I'm not sure why you were passing paramater Practice to an action that took a parameter Id but it should be fixed in the code above.
I have a View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="input-group">
<div class="input-group-addon">
#Html.Label("Employee number", new { #class = "control-label" })
</div>
<div class="a">
#Html.TextBoxFor(model => model.EmployeeNo, new {#class="form-control" })
#Html.ValidationMessageFor(model => model.EmployeeNo)
</div>
</div>
/*
* other fields
*/
}
and Controller:
[HttpPost]
public ActionResult Edit([Bind(Include="Id,EmployeeNo,Name,Surname,ContactInfo,RoleId")] User user)
{
ValidateRequestHeader(Request);
if (ModelState.IsValid)
{
unitOfWork.userRepository.Update(user);
unitOfWork.Save();
return Json(new { ok = true, newurl = Url.Action("Index") });
}
//ModelState.AddModelError("", "Niepoprawne dane");
ViewBag.RoleId = new SelectList(unitOfWork.roleRepository.Get(), "Id", "RoleName", user.RoleId);
return PartialView(user);
}
and model:
public partial class User
{
public User()
{
this.DeviceUsages = new HashSet<DeviceUsage>();
}
public int Id { get; set; }
[Required(ErrorMessage="Brak numeru pracownika")]
public string EmployeeNo { get; set; }
[Required(ErrorMessage = "Brak imienia")]
public string Name { get; set; }
[Required(ErrorMessage = "Brak nazwiska")]
public string Surname { get; set; }
[Required(ErrorMessage = "Brak Adresu email")]
public string ContactInfo { get; set; }
public int RoleId { get; set; }
}
Data annotations are working. If I leave eg. Name empty ModelState is not Valid in controler. But validation messages are not shown. If I uncomment this line:
ModelState.AddModelError("", "Niepoprawne dane"); this will be the only Model error shown in the View.
Where is a mistake in my code?
It's because you are using #Html.ValidationSummary(true) means excludePropertyErrors = true
I would like to know if it is even possible to combine jQuery with a #Html.DropDownListFor in a strongly typed view, as I am beginning to suspect that either it isn't, or my approach to this problem is flawed.
Model:
public class NewUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string ConfirmEmail { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public SelectListItem DOBDay { get; set; }
public SelectListItem DOBMonth { get; set; }
public SelectListItem DOBYear { get; set; }
public string Gender { get; set; }
}
View:
#model test.Models.NewUser
#using (Ajax.BeginForm("RegisterUser", "Register", new AjaxOptions { OnSuccess = "" }))
{
<div>
#Html.TextBoxFor(m => Model.FirstName, new { #class = "big_i", #watermark = "First name" })
#Html.TextBoxFor(m => Model.LastName, new { #class = "big_i", #watermark = "Last name" })
</div>
<div>
#Html.TextBoxFor(m => Model.EmailAddress, new { #class = "big_i long_i", #watermark = "E-mail address" })
</div>
<div>
#Html.TextBoxFor(m => Model.ConfirmEmail, new { #class = "big_i long_i", #watermark = "Confirm e-mail address" })
</div>
<div>
#Html.PasswordFor(m => Model.Password, new { #class = "big_i long_i", #watermark = "Password" })
</div>
<div>
#Html.PasswordFor(m => Model.ConfirmPassword, new { #class = "big_i long_i", #watermark = "Confirm password" })
</div>
<div>
<fieldset>
<h2>
Date of birth</h2>
<div id="reg_date_control" class="date_control">
#Html.DropDownListFor(m => Model.DOBDay, Enumerable.Empty<SelectListItem>(), "Day: ", new { #class = "dc-days big_i" })
#Html.DropDownListFor(m => Model.DOBMonth, Enumerable.Empty<SelectListItem>(), "Month: ", new { #class = "dc-months big_i" })
#Html.DropDownListFor(m => Model.DOBYear, Enumerable.Empty<SelectListItem>(), "Year: ", new { #class = "dc-years big_i" })
</div>
</fieldset>
</div>
}
Controller action for form submit:
[HttpPost]
public ActionResult RegisterUser(Models.NewUser model)
{
string firstName = model.FirstName;
string lastName = model.LastName;
string email = model.EmailAddress;
string confirm_email = model.ConfirmEmail;
string password = model.Password;
string confirm_password = model.ConfirmPassword;
string dob_month = model.DOBMonth.Value; // an error is raised here
return View();
}
I am trying to initially bind the #Html.DropDownListFor with an empty list, which the jQuery will then populate. I won't paste the jQuery code here, it is basically populating each DOB drop down with the valid number of days in a selected month.
The lists populate fine. However, DOBDay, DOBMonth, and DOBYear are always null. I expect that using Enumerable.Empty() is my problem, but having said that, I have tried populating the dropdowns like so:
#model gs_mvc.Models.NewUser
#{
string[] months = new[]{"January", "February", "March", "April", "etc"};
var items = new List<SelectListItem>();
for (int i = 0; i < months.Length; i++) {
items.Add(new SelectListItem { Value = i.ToString(), Text = months[i] });
}
}
...
#Html.DropDownListFor(m => Model.DOBMonth, items, "Month: ", new { #class = "big_i" })
which also gives a null value.
At this point, I believe that my best bet would be to move the functionality of my jQuery script to C#, and do an AJAX call each time the dropdowns are changed. However, I wanted to check here first that I'm not missing something blindingly obvious that would allow me to do what I'm trying.
I think your problem is that the values on the model for month, day, and year should probably be int not SelectListItem. SelectListItem is used to build the options, since it has both the Text and Value properties, but what you want to and will receive back are just the values - not Text/Value pairs. Of course, you probably want to make them nullable so that you're sure that you're receiving values from the POST rather than just having them default to zero.
public class NewUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string ConfirmEmail { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public int? DOBDay { get; set; }
public int? DOBMonth { get; set; }
public int? DOBYear { get; set; }
public string Gender { get; set; }
}