Request method 'POST' not supported - SPRING - spring-mvc

login.jsp
<div id="login" class="animate form">
<form action="${loginUrl}" method="POST">
<h1>Log in</h1>
<c:url var="loginUrl" value="/login" />
<c:if test="${param.error != null}">
<input type="text" class="alert-danger" id="danger" name="danger"
placeholder="Invalid username and password." disabled />
<br />
</c:if>
<c:if test="${param.logout != null}">
<input type="text" class="alert-success" id="success"
name="success"
placeholder="You have been logged out successfully." disabled />
<br />
</c:if>
<p>
<label for="username" class="uname" data-icon="u"> Your
email </label> <input id="username" name="login" required="required"
type="text" placeholder="mymail#atos.net" />
</p>
<p>
<label for="password" class="youpasswd" data-icon="p">
Your password </label> <input id="password" name="password"
required="required" type="password" placeholder="eg. X8df!90EO" />
</p>
<p class="keeplogin">
<input type="checkbox" name="remember-me" id="rememberme"
value="rememberme" /> <label for="rememberme">Remember
Me</label>
</p>
<p class="login button">
<input type="submit" value="Login" />
</p>
<p class="change_link"></p>
</form>
</div>
userlist.jsp
<div class="generic-container">
<%#include file="authheader.jsp" %>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading"><span class="lead">List of Users </span></div>
<table class="table table-hover">
<thead>
<tr>
<th>Prenom</th>
<th>Nom</th>
<th>Matricule</th>
<th>Login</th>
<sec:authorize access="hasRole('ADMIN') or hasRole('READ')">
<th width="100"></th>
</sec:authorize>
<sec:authorize access="hasRole('ADMIN')">
<th width="100"></th>
</sec:authorize>
</tr>
</thead>
<tbody>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.prenom}</td>
<td>${user.nom}</td>
<td>${user.matricule}</td>
<td>${user.login}</td>
<sec:authorize access="hasRole('ADMIN') or hasRole('READ')">
<td>edit</td>
</sec:authorize>
<sec:authorize access="hasRole('ADMIN')">
<td>delete</td>
</sec:authorize>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<sec:authorize access="hasRole('ADMIN')">
<div class="well">
Add New User
</div>
</sec:authorize>
</div>
AppController.java
#Controller
#RequestMapping("/")
#SessionAttributes("roles")
public class AppController {
#Autowired
IService_User<USER> userService;
#Autowired
IService<COMPTE> compteService;
#Autowired
MessageSource messageSource;
#Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;
#Autowired
AuthenticationTrustResolver authenticationTrustResolver;
#RequestMapping(value = { "/", "/list" }, method = { RequestMethod.GET, RequestMethod.POST })
public String listUsers(ModelMap model) {
List<USER> users = userService.findAllOBJECTS();
model.addAttribute("users", users);
model.addAttribute("loggedinuser", getPrincipal());
return "userslist";
}
#RequestMapping(value = {"/login"}, method = { RequestMethod.GET, RequestMethod.POST })
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:/list";
}
}
}
There are 2 pages: login.jsp - start page which includes form to be populated with login and password - userlist.jsp list of results "display all users persisted in DB"..
First the login page is shown, when i click on submit button i got this error:
org.springframework.web.servlet.PageNotFound - Request method 'POST' not supported

In your login.jsp you are using http method POST
<form action="${loginUrl}" method="POST">
and in controller, you are using http method GET
#RequestMapping(value = {"/login"}, method = RequestMethod.GET)
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:/list";
}
}
Problem will be solved after changing method = RequestMethod.POST in your controller like this
#RequestMapping(value = {"/login"}, method = RequestMethod.POST)
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:/list";
}
}

In your login form you are explicitly making an POST request... and in your controller the the url is mapped to GET request.. this is the issue... Please make the controller as POST... like
#RequestMapping(value = {"/login"}, method = RequestMethod.POST)
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:/list";
}
}

Add post method in #RequestMapping annotation, like following;)
#RequestMapping(value = {"/login"}, method = {RequestMethod.GET, RequestMethod.POST})
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:/list";
}
}

if you are using spring security 4.x.x. , CSRF is enabled by default. therefore you have to provide the csrf filed in your form.
Adding the csrf token as hidden fields does the trick:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

Related

How to Edit Image in Existing Member

I Use bootstrap cards and i want picture can also edit on existing user or i Edit picture of any member
This is my Controller
This is my edit Functionality where i can edit My Member so i want i update all existing user picture
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var member = await _context.Member.FindAsync(id);
if (member == null)
{
return NotFound();
}
return View(member);
}
// POST: HomePage/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("MemberId,Name,Gender,DOB,MaritalStatus,Address,PhoneNo,Skills,Hobbies,JobTitle,Technology")] Member member)
{
if (id != member.MemberId)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(member);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MemberExists(member.MemberId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(member);
}
This is a View of my project this is same as create class
<div class="row">
<div class="form-group col-md-4">
<label class="col-md-2 control-label">MemberImage</label>
<div class="col-md-10">
<div id="chooseFile">
<input class="form-control" type="file" name="photo" accept="image/*" />
</div>
</div>
</div>
</div>
when i edit the one existing member
2.i add image
and save it will save the img but now they cannot save image
Exception Occurs when i open edit
*Edit Page Code
<div class="row">
<div class="form-group col-md-4">
<label class="col-md-2 control-label">MemberPicture</label>
<div class="col-md-10">
<img src="~/ImageName/Cover/#Model.Member.ImageName"
class="rounded-square"
height="50" width="75"
style="border:1px"
asp-append-version="true" accept="image/*" />
<span>#Model.Member.ImageName</span>
<div id="chooseFile">
<input class="form-control" type="file" name="photo" accept="image/*" />
</div>
</div>
</div>
</div>
View Model
using System;
using TeamManagement.Models;
namespace TeamManagement.ViewModel
{
public class MemberViewModel
{
public Member Member { get; set; }
public IFormFile? Photo { get; set; }
}
}
This is my edit Functionality where I can edit My Member so I want I update all existing user picture?
If you look into the Member List, it usually contains rows of users along with Id. So we have to find the particular Id and then need to retrieve the value of that Id finally we will update the existing value with the new value. As seen on the screenshot below
Algorithm
From The Member List Click On Particular Member Id
Find The Member Information By that Id
Load The Edit Page With That Id Same As Create Member Page
After Required Change Submit the Edit Page Which Containing the Member Model Data With A ID
Save the Image Into Folder First Same As Create
Search The Member Object By Id
Set New Value Into The Member Object You Have Found In Step 6
Save The Context And Redirect To Member List
Controller Action For Loading Edit Page
public async Task<IActionResult> EditMember(int memberId)
{
var memeber = await _context.Members.FindAsync(memberId); // Getting member by Id from database
return View(new MemberViewModel() { Member = memeber });
}
View Model
public class MemberViewModel
{
public Member Member { get; set; }
public IFormFile? Photo { get; set; }
}
View Edit
#model DotNet6MVCWebApp.Models.MemberViewModel
<div>
<form asp-action="EditMember" method="post" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly"></div><input type="hidden" asp-for="Member.MemberId" />
<div>
<h4><strong>Member Details</strong> </h4>
<table class="table table-sm table-bordered table-striped">
<tr>
<th> <label asp-for="Member.Name"></label></th>
<td> <input asp-for="Member.Name" class="form-control" placeholder="Enter member name" /><span asp-validation-for="Member.Name"></span></td>
</tr>
<tr>
<th> <label asp-for="Member.Gender"></label></th>
<td>
<select asp-for="Member.Gender" class="form-control">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
<span asp-validation-for="Member.Gender"></span>
</td>
</tr>
<tr>
<th> <label asp-for="Member.DOB"></label></th>
<td> <input asp-for="Member.DOB" class="form-control" placeholder="Enter animal category" /><span asp-validation-for="Member.DOB"></span></td>
</tr>
<tr>
<th> <label asp-for="Photo"></label></th>
<td>
<img src="~/ImageName/Cover/#Model.Member.ImageName"
class="rounded-square"
height="50" width="75"
style="border:1px"
asp-append-version="true" accept="image/*" />
<span>#Model.Member.ImageName</span>
<div id="chooseFile"><input type="file" name="photo" accept="image/*" /></div>
</td>
</tr>
<tr>
<th> <button type="submit" class="btn btn-primary" style="width:107px">Update</button></th>
<td> </td>
</tr>
<tr>
<th>#Html.ActionLink("Back To List", "MemberList", new { /* id=item.PrimaryKey */ }, new { #class = "btn btn-success" })</th>
<td> </td>
</tr>
</table>
</div>
</form>
</div>
Here make sure your src="~/ImageName/Cover/#Model.Member.ImageName" is correct as per your picture location. Otherwise picture will not be displayed
Controller When Submit Edit
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditMember(MemberViewModel model, IFormFile photo)
{
if (photo == null || photo.Length == 0)
{
return Content("File not selected");
}
//Save The Picture In folder
var path = Path.Combine(_environment.WebRootPath, "ImageName/Cover", photo.FileName);
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await photo.CopyToAsync(stream);
stream.Close();
}
//Bind Picture info to model
model.Member.ImageName = photo.FileName;
//Finding the member by its Id which we would update
var objMember = _context.Members.Where(mId => mId.MemberId == model.Member.MemberId).FirstOrDefault();
if (objMember != null)
{
//Update the existing member with new value
objMember!.Name = model.Member.Name;
objMember!.Gender = model.Member.Gender;
objMember!.DOB = model.Member.DOB;
objMember!.ImageName = model.Member.ImageName;
objMember!.ImageLocation = path;
await _context.SaveChangesAsync();
}
return RedirectToAction("MemberList");
}
Here we will update the _context.SaveChangesAsync() instead of adding new data. This is the key point for edit. Update the information which we have got by ID
Output

Why is my validation code for .net core 3. not working as intended?

I am trying to make a validation for my report form where the report can only be submited if the email = to "Sample#email.com". My problem is the code works perfectly without the validation but when I include the validation code if (!ModelState.IsValid){return View("Create");} into the my controller the validation works perfectly but when the email is correct it just refreshes the page without submiting it or redirecting it to the submit view
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Submit(Reports report)
{
if (!ModelState.IsValid)
{
return View("Create");
}
_reportRepository.CreateReport(report);
return View();
Validation Code:
public class EmailValidation : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var report = (Reports)validationContext.ObjectInstance;
if (report.Email == "Sample#email.com")
{
return ValidationResult.Success;
}
return new ValidationResult("Invalid email");
}
}
Report:
public class Reports
{
[Key]
public int ReportId { get; set; }
[Required(ErrorMessage = "Please enter email.")]
[Display(Name = "Email :")]
[EmailValidation(ErrorMessage ="enter valid email")]
public string Email { get; set; }
}
Create View:
#model Reports
#using Microsoft.AspNetCore.Identity
#inject UserManager<IdentityUser> UserManager
<body>
<form asp-action="Submit" method="post" role="form">
<div class="container1">
<div class=" form-group row">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-3">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group row float-right">
<div class="col-md-offset-2 col-md-5 float-md-left">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</div>

How to send a submitted email to an email

I am currently using a template in order to create a website. In the contact page I want to create a form where the user will be able to contact the company from a contact us template. The template comes with a contact_us.php file but I want to use only asp.net for the emails.
I am a beginner and I am not really sure how the controllers works in asp.net.
Heres my code:
View: Contact.cshtml
#model Gsite.Models.ContactUs
#{
Layout = "~/Views/Shared/_CustomLayout.cshtml";
}
<script src="~/Content/vendor/jquery/jquery.js"></script>
<script src="~/Content/vendor/jquery/jquery.min.js"></script>
<!-- Contact Form -->
<!-- In order to set the email address and subject line for the contact form go to the bin/contact_me.php file. -->
<div class="row">
<div class="col-lg-8 mb-4">
<h3>Send us a Message</h3>
#if (ViewBag.Message == null)
{
<form method ="post" name="sentMessage" id="contactForm" novalidate>
<div class="control-group form-group">
<div class="controls">
<label asp-for="Name">Full Name:</label>
<input asp-for="Name" type="text" class="form-control" id="name" required data-validation-required-message="Please enter your name.">
<span asp-validation-for="Name"
class="text-muted"></span>
<p class="help-block"></p>
</div>
</div>
<div class="control-group form-group">
<div class="controls">
<label asp-for="phonenumber">Phone Number:</label>
<input asp-for="phonenumber" type="tel" class="form-control" id="phone" required data-validation-required-message="Please enter your phone number.">
<span asp-validation-for="phonenumber"
class="text-muted"></span>
</div>
</div>
<div class="control-group form-group">
<div class="controls">
<label asp-for="Email">Email Address:</label>
<input asp-for="Email" type="email" class="form-control" id="email" required data-validation-required-message="Please enter your email address.">
<span asp-validation-for="Email"
class="text-muted"></span>
</div>
</div>
<div class="control-group form-group">
<div class="controls">
<label asp-for="Message">Message:</label>
<textarea asp-for="Message" rows="10" cols="100" class="form-control" id="message" required data-validation-required-message="Please enter your message" maxlength="999" style="resize:none"></textarea>
<span asp-validation-for="Message"
class="text-muted"></span>
</div>
</div>
<div id="success"></div>
<!-- For success/fail messages -->
<button type="submit" class="btn btn-primary" id="sendMessageButton">Send Message</button>
</form>
}
</div>
</div>
<!-- /.row -->
<div>
<div>
#if (ViewBag.Message != null)
{
<div>#ViewBag.Message</div>
}
</div>
</div>
</div>
<script src="~/Content/vendor/jquery/jquery.min.js"></script>
<script src="~/Scripts/jqBootstrapValidation.js"></script>
<script src="~/Scripts/contact_me.js"></script>
Controller: ContactController
namespace Gsite.Controllers
{
public class ContactController : Controller
{
// GET: Contact
public ActionResult Contact()
{
return View();
}
[HttpPost]
public ActionResult Contact(ContactUs vm)
{
if (ModelState.IsValid)
{
try
{
MailMessage msz = new MailMessage();
msz.From = new MailAddress(vm.Email);//Email which you are getting
//from contact us page
msz.To.Add("xxx#xxx.com");//Where mail will be sent
msz.Body = vm.Message;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.Credentials = new System.Net.NetworkCredential
("xxxxx#xxxxx.com", "xxxxx");
smtp.EnableSsl = true;
smtp.Send(msz);
ModelState.Clear();
ViewBag.Message = "Thank you for Contacting us ";
}
catch (Exception ex)
{
ModelState.Clear();
ViewBag.Message = $" Sorry we are facing Problem here {ex.Message}";
}
}
return View();
}
public ActionResult Error()
{
return View();
}
}
}
Model: ContactUs.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace Gsite.Models
{
public class ContactUs
{
[Required]
[StringLength(20, MinimumLength = 5)]
public string Name { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Message { get; set; }
[Required]
public int phonenumber { get; set; }
}
}
This will work in an Asp.net MVC application. Does the application has got both Asp.net MVC and Php codes? Assuming 'yes', you need to set the action property of the form element.
e.g. <form action="/Contact/Contact">
Also set the "name" property of the input boxes to match the properties of the ContactUs object.

ModelState.AddModelError not displaying error in view - ASP.NET

I have been banging my head against the wall trying to solve this issue.
I have this view controller
public class LoginController : Controller
{
public ActionResult Index(LoginClass model)
{
return View(model);
}
[HttpPost]
public ActionResult Login(LoginClass model, string ReturnUrl)
{
if (!this.ModelState.IsValid)
{
return this.View(model);
}
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl) && ReturnUrl.Length > 1 && ReturnUrl.StartsWith("/")
&& !ReturnUrl.StartsWith("//") && !ReturnUrl.StartsWith("/\\"))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError(string.Empty, "The user name or password provided is incorrect");
}
}
return RedirectToAction("Index", "Login", model);
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
}
and here is my view:
<section id="login">
<div class="container">
<form action="~/Login/Login" id="Login" method="post">
<div class="row">
<div class="col-md-12">
<p>
<label for="username">Username</label>
<input type="text" id="username" name="username" class="form-control" />
</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control" />
</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
<input type="submit" id="submit" name="submit" value="Login" class="btn btn-default" />
</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
<label for="password">Remember Me?</label>
<input type="checkbox" id="chkPersist" name="chkPersist" />
</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
#Html.ValidationSummary()
</p>
</div>
</div>
</form>
</div>
</section>
My issue is that my error message is not appearing when I enter the wrong username and password. Why is not displaying?
The problem is with the last line in your Login method. You are calling RedirectToAction instead of View. This has the consequence that you lose all your view specific state including the model state and validation errors that you built up in your Login Action. You can change your Login method like so (I simplified it a little), really the only change is replacing RedirectToAction("Index", "Login", model) with View(model) on the last line.
If you do want to redirect in the event of authentication failure and you did want to use RedirectToAction then see my other answer I posted here.
[HttpPost]
public ActionResult Login(LoginClass model, string ReturnUrl)
{
if (!this.ModelState.IsValid)
return this.View(model);
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl) && ReturnUrl.Length > 1 && ReturnUrl.StartsWith("/")
&& !ReturnUrl.StartsWith("//") && !ReturnUrl.StartsWith("/\\"))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
ModelState.AddModelError(string.Empty, "The user name or password provided is incorrect");
return this.View(model); // return to the same view to show your error message
// return RedirectToAction("Index", "Login", model); // do not redirect
}
You need to add a placeholder by using the Html Helper function to display the message.
<div>#Html.ValidationMesssage("KeyName")</div>
to your view so that you can display the validation message.
The KeyName comes from controller
ModelState.AddModelError("KeyName", "The user name or password provided is incorrect");
Also you may need to ensure client side validation is enabled in your web.config.(usually they are)
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

MVC4 Posting a form not calling Controller method

I have the following form in my View.
#using (Html.BeginForm("PostComment", "Blog")) name)
{
<fieldset id="frmTester">
<div class="formContainer">
<span><input id="username" name="username" /></span>
<input id="submit" name="submit" type="submit" value="Submit" />
</div>
</fieldset>
}
Now I have the following Method in my BlogController...
public ActionResult PostComment(string username)
{
return View();
}
I really don't get MVC very well. I dont see why I cant get the above ActionResult method to execute. I'm just trying to handle a postback. Anyone have any idea why this doesn't work or an alternative approach.
use [HttpPost] :
[HttpPost]
public ActionResult PostComment(string username)
{
string u = Request.Form["username"] ;
// return Content(u); //if you want dispaly username use this
return View();
}
Change your view code to this...
#using (Html.BeginForm("PostComment", "Blog", FormMethod.Post))
{
<fieldset id="frmTester">
<div class="formContainer">
<span><input id="username" name="username" type="text" /></span>
<input id="submit" name="submit" type="submit" value="Submit" />
</div>
</fieldset>
}
and your action method to....
[HttpPost]
public ActionResult PostComment(string username)
{
return View();
}

Resources