Form Submit Not Work in MVC 5 Project - asp.net-mvc

My Submit Form Button Not Working ..
When I press on Login Button Nothing Happens ...
I had set breakpoint in my code and Login Post Action not Called after Submit Button Click .
I can fix my problem with JQuery ajax codes but I don't want use JQuery Ajax for submitting Form ..I want to understand and resolve this MVC problem
thank you ...
User Model :
namespace Models
{
public class User : BaseEntity
{
public User() : base()
{
}
[System.ComponentModel.DataAnnotations.Required]
public string Username { get; set; }
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.DataType(System.ComponentModel.DataAnnotations.DataType.Password)]
public string Password { get; set; }
}
}
BaseEntity Class has only Id (System.Guid) Property
Controller :
public class AdminController : Infrastructure.BaseController
{
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult Index()
{
return View();
}
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult Login()
{
return View();
}
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult Edit()
{
return View();
}
[System.Web.Mvc.HttpPost]
[System.Web.Mvc.ValidateAntiForgeryToken]
public System.Web.Mvc.ActionResult Login([System.Web.Mvc.Bind(Include = "Id,Username,Password")] Models.User user)
{
string password = AAk.Security.Hashing.GetMD5(user.Password);
Models.User oUser = MyDatabaseContext.Users
.Where(current => current.Username.Contains(user.Username))
.Where(current => current.Password == password)
.FirstOrDefault();
if(oUser != null)
{
System.Web.Security.FormsAuthentication.SetAuthCookie(user.Username, false);
Session["AdminUserId"] = user.Id;
return (RedirectToAction("Edit", "Admin"));
}
else
{
//ModelState.AddModelError(string.Empty, "Login Failed!");
PageMessages.Add(new Infrastructure.PageMessage(Infrastructure.PageMessage.Types.Error, "Login Failed!"));
}
return (View(model: user));
}
}
Login.cshtml
#model Models.User
#{
ViewBag.Title = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
#using (Html.BeginForm("Login", "Admin", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.Partial(partialViewName: "~/Views/Shared/_PageMessages.cshtml")
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.Username, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", #id = "username" } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control", #id = "password" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" id="login-button" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>

Related

Another [Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Cannot perform runtime binding on a null reference'] in ASP.NET MVC

I tried to have a file upload into another folder, it works fine when it directly add to the database, but if I try to use it with MultipleDocumentCreateClass for the stored procedure, I get this error:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Cannot perform runtime binding on a null reference'
Controller
// GET: Activity/DocumentNew
public ActionResult DocumentNew(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Hoạt_động hoạt_động = db.Hoạt_động.Find(id); ;
ViewBag.act = hoạt_động;
if (hoạt_động == null)
{
return HttpNotFound();
}
MultipleDocumentCreateClass mtd = new MultipleDocumentCreateClass();
mtd.Mã_Hoạt_động = hoạt_động.Mã_Hoạt_động;
Dropdownlist2();
return View(mtd);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DocumentNew([Bind(Include = "Mã_Hoạt_động, Tên, Loại,Thông_tin, Nội_dung")]MultipleDocumentCreateClass mt)
{
if (ModelState.IsValid)
{
if (Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
//Save into folder
file.SaveAs(Server.MapPath("/App_Data/Video/" + fileName));
mt.Nội_dung = "~/App_Data/Video/" + fileName;
mt.Tên = Path.GetFileNameWithoutExtension(file.FileName);
}
db.MultipleDocCr(mt.Mã_Hoạt_động, mt.Tên, mt.Loại, mt.Thông_tin, mt.Nội_dung);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(mt);
}
MultipleDocumentUseClass:
public class MultipleDocumentCreateClass
{
public Nullable<int> Mã_Hoạt_động { get; set; }
public string Tên { get; set; }
public string Loại { get; set; }
public string Thông_tin { get; set; }
public string Nội_dung { get; set; }
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Hoạt động: #Model.Mã_Hoạt_động</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Mã_Hoạt_động, new { value = ViewBag.act.Mã_Hoạt_động })
<dt>
Hoạt động:
#ViewBag.act.Tên
</dt>
<div class="form-group">
#Html.LabelFor(model => model.Loại, "Thể loại", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Loại, new SelectList(ViewBag.doc, "Value", "Text"), new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Loại, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Thông_tin, "Thông tin", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Thông_tin, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Thông_tin, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Nội_dung, "Chọn File", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Nội_dung, new { htmlAttributes = new { Type = "file" } })
#Html.ValidationMessageFor(model => model.Nội_dung, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Lưu" class="btn btn-default" />
</div>
</div>
</div>
}
The error points to this line
#Html.HiddenFor(model => model.Mã_Hoạt_động, new { value = ViewBag.act.Mã_Hoạt_động })
but when I add value manually without uploading, it works fine.
So the answer at the #using (Html.BeginForm()) in View
Change it into this #using (Html.BeginForm("DocumentNew", "Activity", FormMethod.Post, new { enctype = "multipart/form-data" }))

One model for two submit buttons in ASP.NET MVC

I have a form on my view:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.DateFrom, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateFrom, new { htmlAttributes = new { #class = "form-control date-picker" } })
#Html.ValidationMessageFor(model => model.DateFrom, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DateTo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateTo, new { htmlAttributes = new { #class = "form-control date-picker" } })
#Html.ValidationMessageFor(model => model.DateTo, "", 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" formAction=#Url.Action("CreateReport") />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EMail, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EMail, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EMail, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Send to email" class="btn btn-default" formAction=#Url.Action("SendEmail") />
</div>
</div>
</div>
}
As you can see I have two butons, first button call CreateReport action and than Send button call SendEmail action. I want to create report and then send this report by e-mail.
Here is my controller actions:
public ActionResult Index()
{
Report
report=ReportRepository.GetReport(DateTime.Parse("02.08.1996"), DateTime.Parse("07.08.1996"));
return View(report);
}
public ActionResult CreateReport(Report report)
{
report = ReportRepository.GetReport(report);
return View("Index", report);
}
public ActionResult SendEmail(Report report)
{
return View("Index", report);
}
And my model class:
public class Report
{
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<OrderDetails> Orders { get; set; }
[Display(Name = "Email address")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string EMail { get; set; }
}
So I mean that I fill Orders list in CreateReport action and display it and after it I press "Send to email" button, that's call "SendEmail" action, where I save Orders list to file and send it.
The problem is that in "SendEmail" action List is null.
How can I fix it?
The simplest way that I could think of is to remove your submit action for create report and handle this with ajax call. So that you will have only one submit action.
Or else you can try with 2 forms in your View.
Personally, I prefer the 1st option.
I'v found a solution. The solution is not to pass model to controller but store my List in Session. Like this:
public ActionResult Index()
{
Report report=ReportRepository.GetReport(DateTime.Parse("02.08.1996"), DateTime.Parse("07.08.1996"));
Session["Orders"] = report.Orders;
return View(report);
}
public ActionResult CreateReport(Report report)
{
report = ReportRepository.GetReport(report);
Session["Orders"] = report.Orders;
return View("Index", report);
}
public ActionResult SendEmail(Report report)
{
List<OrderDetails> orders = (List<OrderDetails>)Session["Orders"];
report.Orders = orders;
return View("Index", report);
}

Asp.net mvc connect to webApi by httpClient

I have mvc application and webApi application. I need sign in in asp.net mvc through webApi. When i use this method:
public static string GetToken(LoginModelView login)
{
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password" ),
new KeyValuePair<string, string>( "username", login.Login ),
new KeyValuePair<string, string> ( "Password", login.Password )
};
var content = new FormUrlEncodedContent(pairs);
using (var client = new HttpClient())
{
var response =
client.PostAsync(URL + "/Token", content).Result;
var responseJson = response.Content.ReadAsStringAsync().Result;
var dictionaryToken = JsonConvert.DeserializeObject<Dictionary<string,string>>(responseJson);
string token = dictionaryToken["access_token"];
return token;
}
}
My mvc don't bind model from view.
Action methods
[HttpGet]
public ActionResult SignIn()
{
var login = new LoginModelView();
return View("SignIn",login);
}
[HttpPost]
public ActionResult SignIn(LoginModelView login)
{
string token = DirService.GetToken(login);
Session["token"] = token;
return RedirectToAction("success");
}
It's model
public class LoginModelView
{
public string Login { get; set; }
public string Password { get; set; }
}
It's my view
#model AdminTool.Models.LoginModelView
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>LoginModelView</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Login, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Login, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Login, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" />
</div>
</div>
</div>
}
when i don't use that method, everything is ok.
The same code works in another application.
Somebody can help me, please..
I noticed that in LoginModelView class has Login Property and you create same object name LoginModelView login in controller.I change that code and its Work For Me.
Model:-
[HttpGet]
public ActionResult SignIn()
{
var loginModelView = new LoginModelView();
return View("SignIn", loginModelView);
}
[HttpPost]
public ActionResult SignIn(LoginModelView loginModelView)
{
string token = DirService.GetToken(loginModelView);
Session["token"] = token;
return RedirectToAction("success");
}
Hope Its Work !!!
Happy Coding !!
I think you posting from data to get method(GetToken).

The current request for action ... on controller type ... is ambiguous between the following action methods

When I run the application on browser with ~/Person/New the result is
The current request for action 'New' on controller type 'PersonController' is ambiguous between the following action method System.Web.Mvc.ActionResult New() on type PersonMVC.Controllers.PersonController System.Web.Mvc.ActionResult New(PersonMVC.Models.Person) on type PersonMVC.Controllers.PersonController
Model
namespace PersonMVC.Models
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
[Required]
[DisplayName("Social Sequrity Number")]
[MinLength(11, ErrorMessage ="Social Security Number Must be 11 digit.")]
[MaxLength(11, ErrorMessage ="")]
public string SocialSecurityNumber { get; set; }
[DisplayFormat(DataFormatString ="{0:dd.MM.yyyy}")]
public DateTime BirthDay { get; set; }
}
}
-View
#model PersonMVC.Models.Person
#{
ViewBag.Title = "New";
}
<h2>New</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SocialSecurityNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SocialSecurityNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SocialSecurityNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BirthDay, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BirthDay, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BirthDay, "", 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")
}
Controller
namespace PersonMVC.Controllers
{
public class PersonController : Controller
{
public ActionResult New()
{
return View();
}
[HttpPost]
public ActionResult New(Person newPerson)
{
bool isTrue = ModelState.IsValid;
return View();
}
}
}
you need to decorate the method with appropriate http verb. Otherwise it will be considered as HttpPost usually.
i think adding [HttpPost] to the controller method would solve the problem

ViewBag message is changed even when a form has errors

I have a simple contact form that is using a model for it's fields, everything seems to work but the ViewBag message gets changed regardless if there are validation errors or not, user validation prevents this but I also need the HttpPost action to set the message based on if the the form was filled correctly.
I tried using if(ModelState.IsValid) but it doesn't seem to work. I realize I can probably manually check each variable in the home to see if it's empty, but that won't really tell me if it's valid or the post was returned with errors, is there a build in method for this?
ContactFormModel.cs
namespace TestApplication.Models
{
public class ContactFormModel
{
[Required]
[Display(Name = "Name")]
public string name { get; set; }
[Required]
[Display(Name = "Phone")]
public string phone { get; set; }
[Required]
[Display(Name = "Message")]
public string message { get; set; }
}
}
HomeController.cs
[HttpPost]
public ActionResult Contact(ContactFormModel contactForm)
{
ViewBag.Message = "Thank you. Your message has been sent.";
return View();
}
Contact.cshtml
#model TestApplication.Models.ContactFormModel
#{
ViewBag.Title = "Contact";
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<p>Use this area to provide additional information.</p>
#*#if (!IsPost)
{
#Html.EditorForModel(Model)
}*#
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.name, "", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.phone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.phone, "", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.phone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.message, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.message, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.message, "", 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>
}
The pattern for doing what you want is to check ModelState.IsValid. If it's valid continue processing, if not return the view with the existing model contents to give the user a chance to correct their error(s).
[HttpPost]
public ActionResult Contact(ContactFormModel contactForm)
{
if (ModelState.IsValid)
{
ViewBag.Message = "Thank you. Your message has been sent.";
return View();
}
else
{
return View(contactForm);
}
}
Having said that, you should consider using a PRG (post-redirect-get) pattern. By returning the same view in the HttpPost version of the method you open yourself up to repeated posting of the data. If the user hits Refresh in their browser it will repost the data they just posted (after popping up a dialog that most non-technical users will never understand). You must have a HttpGet version that delivers the view in the first place, you should redirect to that on success. You'll have to switch to using TempData instead of ViewBag because the ViewBag won't survive the redirect.
[HttpPost]
public ActionResult Contact(ContactFormModel contactForm)
{
if (ModelState.IsValid)
{
TempData.Message = "Thank you. Your message has been sent.";
// Assumes there is a Get version of the Contact action method
return RedirectToAction("Contact");
}
else
{
return View(contactForm);
}
}

Resources