send data from jsp to controller using model attribute - spring

<body>
<jsp:useBean id="loginBean" class="com.ss.sms.bean.LoginBean"></jsp:useBean>
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">Log in</div>
<div class="panel-body">
form:form id="loginForm" method="post" action="login" modelAttribute="login">
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="UserId" name="userId" type="text" autofocus="autofocus" value=${loginBean.userName}>
</div>
<div class="form-group">
<input class="form-control" placeholder="Password" name="password" type="password" value=${loginBean.password}>
</div>
<div class="checkbox">
<label>
<input name="remember" type="checkbox" value="Remember Me">Remember Me
</label>
</div>
<input type="submit" class="btn btn-primary">
<div style="color: red">${error}</div>
</fieldset>
</form:form>
</div>
</div>
</div><!-- /.col-->
</div><!-- /.row -->
#RequestMapping(value="/login",method = RequestMethod.POST)
public ModelAndView login(Model md,#ModelAttribute("login")LoginBean loginBean) {
System.out.println("hello done");
System.out.println(loginBean.getUserName());
ModelAndView model = null;
if (loginBean != null && loginBean.getUserName() != null & loginBean.getPassword() != null) {
if (loginBean.getUserName().equals("santosh") && loginBean.getPassword().equals("Santosh#123")) {
model = new ModelAndView("hello");
return model;
} else {
model = new ModelAndView("login");
return model;
}
} else {
model = new ModelAndView("login");
return model;
}
}

if i understand correctly fromn your code you have problem seeing the page correctly.
In your ModelAndView you add just the view and not the model
So you need to add the object
Hence, the code can look something like that
#RequestMapping(value="/login",method = RequestMethod.POST) public ModelAndView login(Model md,#ModelAttribute("login")LoginBean loginBean) {
System.out.println("hello done");
System.out.println(loginBean.getUserName());
ModelAndView model = null;
if (loginBean != null && loginBean.getUserName() != null & loginBean.getPassword() != null) {
if (loginBean.getUserName().equals("santosh") && loginBean.getPassword().equals("Santosh#123")) {
//if the view hello expects an object add it here
model = new ModelAndView("hello");
return model;
} else {
model = new ModelAndView("login").addObject("login",loginBean);
return model;
}
} else {
model = new ModelAndView("login").addObject("login",loginBean);
return model;
}
}

Related

Cannot load the image from database to thymleaf

This is my editprofile.html:
<form th:action="#{/updateProfile}" method="post" class="signin-form" th:object="${editprofile}" enctype="multipart/form-data">
<div class="title-main text-center mx-auto mb-md-5 mb-4" style="max-width:500px;">
<h5 class="footer-title-29">Personal Details</h5>
<div class="col-sm-6 profile_Pic">
<img id="thumbnail" th:src="*{'data:image/jpg;base64,'+profile_pic}" width="200" />
</div>
</div>
<br><br>
<div class="input-grids">
<label class="control-label" for="name">Name:</label>
<input type="text" th:field="*{name}" id="name" class="contact-input" />
<div class="row">
<div class="col-sm-6">
<label class="control-label" for="mobileNumber">Mobile Number:</label>
<input type="text" th:field="*{mobileNumber}" id="mobileNumber" class="contact-input" />
</div>
<div class="col-sm-6">
<label class="control-label" for="email">Email:</label>
<input type="text" th:field="*{email}" id="email"
class="contact-input" />
</div>
</div>
</div>
<div class="title-main text-center mx-auto mb-md-5 mb-4" style="max-width:500px;">
<h5 class="footer-title-29">Address Details</h5>
</div>
<div class="input-grids">
<label class="control-label" for="address1">Address Line 1:</label>
<input type="text" th:field="*{address1}" id="address1" class="contact-input" />
<label for="address2">Address Line 2:</label>
<input type="text" th:field="*{address2}" id="address2" class="contact-input" />
<label class="control-label" for="city">City:</label>
<input type="text" th:field="*{city}" id="city" class="contact-input" />
<div class="row">
<div class="col-sm-6">
<label class="control-label" for="state">State:</label>
<input type="text" th:field="*{state}" id="state"
class="contact-input" />
</div>
<div class="col-sm-6">
<label class="control-label" for="zipCode">Zip Code:</label>
<input type="text" th:field="*{zipCode}" id="zipCode"
class="contact-input" />
</div>
<div class="col-sm-6">
<label class="control-label" for="fileImage">Upload image</label>
<input type="file" name="fileImage" accept="image/*" id="fileImage" />
</div>
</div>
</div>
<div class="col-md-8 login-center text-start">
<button class="btn btn-style btn-style-3 text-left" >Update</button>
<a th:href="#{/dashboard}" class="new-user text-right">
<button class="btn btn-style btn-style-3 text-left" th:formaction="#{/displayProfile}">BACK</button></a>
</div>
</form>
I did a compress and decompress when adding and retrieving the data from db
Code: ImageUtil.java
public static byte[] compressImage(byte[] data) {
Deflater deflater = new Deflater();
deflater.setLevel(Deflater.BEST_COMPRESSION);
deflater.setInput(data);
deflater.finish();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] tmp = new byte[1024];
while (!deflater.finished()) {
int size = deflater.deflate(tmp);
outputStream.write(tmp, 0, size);
}
try {
outputStream.close();
} catch (Exception e) {
}
return outputStream.toByteArray();
}
public static byte[] decompressImage(byte[] data) {
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] tmp = new byte[1024];
try {
while (!inflater.finished()) {
int count = inflater.inflate(tmp);
outputStream.write(tmp, 0, count);
}
outputStream.close();
} catch (Exception exception) {
}
return outputStream.toByteArray();
}
I upload the image like:
person.getAddress().setProfile_pic(ImageUtil.compressImage(file.getBytes()));
personRepository.save(person);
And the image is saved to db successfully
The problem is image cannot be displayed.I did this when retrieving the data from db:
byte[] decomImage = ImageUtil.decompressImage(person.getAddress().getProfile_pic());
byte[] encodeBase64 = Base64.getEncoder().encode(decomImage);
String base64Encoded = new String(encodeBase64, "UTF-8");
pojoprofile.setEncoded_image(base64Encoded);
I cannot retrieve the image and display it. I tried decompress the image and converted it into Base64 to display it in the thymleaf.
This is my controller class to upload image to database:
#RequestMapping(value = "/EditProfile")
public ModelAndView EditProfile(Model model, HttpSession httpSession){
PersonPojo person=(PersonPojo) httpSession.getAttribute("loggedInPerson");
Profile pojoprofile1=new Profile();
pojoprofile1.setName(person.getName());
pojoprofile1.setEmail(person.getEmail());
pojoprofile1.setMobileNumber(person.getMobileNumber());
if(person.getAddress()!=null&&person.getAddress().getAddressId()>0){
pojoprofile1.setAddress1(person.getAddress().getAddress1());
pojoprofile1.setAddress2(person.getAddress().getAddress2());
pojoprofile1.setCity(person.getAddress().getCity());
pojoprofile1.setState(person.getAddress().getState());
pojoprofile1.setZipCode(person.getAddress().getZip_code());
pojoprofile1.setProfile_pic(Base64.getEncoder().encode(person.getAddress().getProfile_pic()));
// pojoprofile1.setProfile_pic(person.getAddress().getProfile_pic());
}
ModelAndView editprofile=new ModelAndView("EditProfile.html");
editprofile.addObject("editprofile",pojoprofile1);
return editprofile;
}
#RequestMapping(value = "/updateProfile")
public String updateProfile(#RequestParam("fileImage") MultipartFile file, #Valid #ModelAttribute("editprofile") Profile profile, Errors errors,
HttpSession httpSession) throws IOException {
if(errors.hasErrors()){
return "EditProfile.html";
}
PersonPojo person=(PersonPojo) httpSession.getAttribute("loggedInPerson");
person.setName(profile.getName());
person.setEmail(profile.getEmail());
person.setMobileNumber(profile.getMobileNumber());
if(person.getAddress() == null || !(person.getAddress().getAddressId()>0)){
person.setAddress(new AddressPoJO());
}
person.getAddress().setAddress1(profile.getAddress1());
person.getAddress().setAddress2(profile.getAddress2());
person.getAddress().setCity(profile.getCity());
person.getAddress().setState(profile.getState());
person.getAddress().setZip_code(profile.getZipCode());
person.getAddress().setProfile_pic(ImageUtil.compressImage(file.getBytes()));
personRepository.save(person);
httpSession.setAttribute("loggedInPerson", person);
return "redirect:/dashboard";
}
Controller to display the content in Profile page:
#RequestMapping("/displayProfile")
public ModelAndView Myprofile(HttpSession httpSession) throws UnsupportedEncodingException {
Profile pojoprofile=new Profile();
PersonPojo person=(PersonPojo) httpSession.getAttribute("loggedInPerson");
pojoprofile.setName(person.getName());
pojoprofile.setEmail(person.getEmail());
pojoprofile.setMobileNumber(person.getMobileNumber());
if(person.getAddress()!=null&&person.getAddress().getAddressId()>0){
log.info("Inside the if"+new MyProfile().getClass().toString());
pojoprofile.setAddress1(person.getAddress().getAddress1());
pojoprofile.setAddress2(person.getAddress().getAddress2());
pojoprofile.setCity(person.getAddress().getCity());
pojoprofile.setState(person.getAddress().getState());
pojoprofile.setZipCode(person.getAddress().getZip_code());
byte[] encodeBase64 = Base64.getEncoder().encode(ImageUtil.decompressImage(person.getAddress().getProfile_pic()));
pojoprofile.setProfile_pic(encodeBase64);
}else {
pojoprofile.setAddress1(" Not available ");
pojoprofile.setAddress2(" Not Available");
pojoprofile.setZipCode(" Not Available");
pojoprofile.setState(" Not Available");
pojoprofile.setCity(" Not Available");
}
return new ModelAndView("profile.html").addObject("profile",pojoprofile);
}
You should return a String representation of an image, rather than a byte array. So change your code to
String encodeBase64 = Base64.getEncoder().encodeToString(person.getAddress().getProfilePic());
pojoprofile.setProfilePic(encodeBase64);
This means that Profile.profilePic is also a String. ( person.getAddress().getProfilePic()should return a valid byte array)
EDIT:
If you just want to make sure that this works without changing much of your code, I suggest adding a String field to Profile.java and setting that field with a hardcoded base64 image in your controller.
private String testImg; //in Profile.java
//in your controller
String picbase64 = "iVBORw0KGgoAAAANSUhEUgAAACEAAAAgCAYAAACcuBHKAAAACXBIWXMAABJ0AAASdAHeZh94AAAIgklEQVR42o1YCXAUxxXdMqZiynGAuJIyOI4hpIgxxAVxDkxSsZ2T4MRO4gOcA0MK4zikXDJHuCywJC6BAHEoWAgQAklcQpxCEAzCRoC4DwkBQhKX0bm72mtmd7Xb/fJ6Zo8RshBd9atnZn/3f/3+79+/14ZOmpRxCQvAHzJFPVub9beQaDuus2brzLhqQpoT39sCNOgNmobvbUpfyPZzPTAI6wDril1+iYLLEv/cA/x0rcRTSySeWGT2w9ZIvLcb2FQuYddk2/Gy/bz3BSEtA0Jh89muS6SUSDyZxgGTJWxTKEkSjxNAryVm/1By5PskAksFZh2SaPDJGCvyPqzYOgQQYWDfdYm+S6j4ocRj8yVeKwDmnQLWXQHyqoEttUA++/XXgNTTwBuFQM9Uaej3WggUVEqDCiuQDploD0BiJY3ZplFmSYzeK7GJxjZUhzHluI4Ru1wYkufEwA12PJ/vxO93uzHthB+51QJbCWz8AYmuSYodIOUzc75wFMg9bLRjImwFQOr7pEusuEhf1wqMLPai9+omPJxej66ULkvrYUurxyPLGvAQnx9Ob+DvzXiLenk1AqsvAwMyCGSiRNKROBDxZe6I+inqguLrigGJ/sulQXnaxSAG5Njx6IoGPL6qEb2zmtDjv40YvLEZfy1y4GsZjQa4b2Y2oSd/70a972bbMedswGBlSKYw4iW/HG1cE2UjxoSIIHTqwFNpEj3nCeRUAXPPBfDtNU3otboR31nXbEgvgng2pxmnvvBxkB8Jh1rwdRrvs7YJT69tRh+lQ1BPENR/6LrNNcCTiwW6z5G441Z2ZJtdZ2vLgsRHh/hxikDiceCTKyEas6P/+mbD90r6ZTdjcK4dZXdMAOGgjlCrjmmftxjgBhDc9zhmQGRcXwJSjCw6q9gVmFAkY1s3atsWZUFGWOgxT2II9/y2GwLDd7owkJQ/n+8wZNBGO4ZuduCkYkD6EfJrEAEdkiBESEdiqQv9aHgIdQfn2Y1+EAH/cJMD66+H8VKuxCMfC9xxyRj7MSai1GyuYBBNFZh7Ekg642f02/GzbU5D1EQvFThw6i4BgACUcbKAVr8BBARCVJhT5sKgPAde2KrEiWGU5wjk3cNeLD0vjVhbVia5aGnkIYMJK4jRhQKPkomNzA0j93vwcxr9zY4WvFjgJCtOnFYApE67XHkEQBSIAqW+STKy6LQbP9riwC93OPGLQifH85n96qsh9FoKjMgV8Tik2OK+kRjE7fTjbGANlUfsasEf9rRgOPs/7m3BmTozBlrpAoRpOBwHYIiKDwuQ5ec8eJGGX9ndYsz18nYnFlwI4LebmOYXSwTDMnYu2aKp2R0AupOFkTsllpYH8BoN/6nIhbf3u3CuXjNiIKizh46LdRrKbmsxID5Nx5bLmuEOFagGS3zOvOTB73a78Po+lwFmepmGsftMOw5NxPKSrTXChMrzX50r8Y9iYNFFP94sdmHMp24yYBpTLlAAyhs1Rr4bWefN2FDxENB1DMn1YEFZJGD5zYgZMrK23IvXi91MYC7MOOnDB9x9XZhJb0eCU5FgiwZHM0++x4hwDJEuvuTH6INukwH4zaBjLBy5oWHETg/97UZ+hcmOCGrw+nS8WeTB0K1uLDttAlH6EKbbMglk1AE3ks9qmPAp0C1Fot4rY4ekLRqUyke9maRe5QG16koA7xz0YOIRH2aU+jCJ/bgDXvyq0IuEY14M3+1BziUToNqebq+GN4q8+KDUg1f2ePFhiQ/JJzj2qBeTP2d/3IvxJR6kXtDxFx733+AB5wmIWL6wCUsufzlb4tlPJNZVhTCJxv7FCd77zIfxlHGceMoJL5LPaIahDeURluj/Fq+OtwhiMg1PP2nqjj3sw7sE/z7nSChV4uXignhhvcTgVeYWVUyI6BY1XSIx67BA12Qgs1JgzjkNKWd9TNuaIfMoH5/xYcF5DX8ujoOQ3BkOj45R/JZ4WsNsglS0pyjhmCS+z+b3RLppzdUwui8A3t9ryZrCkjFVO1/PZDJTIuEwt+m1oGF8ISlUNKpeAVhWQYP/82HDpXi8NLtJ834f5imdCxrmn9cNWXDBFAUoozKAmcc4/3SJg9WizdEeOztEJFcMzRL4FouY/Jowllf4DVlx2RQFIOuaH+8c0hgTPuqbWbPRpeHvBzSkV5g66eV65Nlv9Esu6SwFwuifAQxcKdDK+BP3nqLRA0z1h2rN1Kq26rZbrfSjn4YDZCbAjMeipSbAGNGRWxFlwo8ml44xBzVkRnQyDeEz3zMq/dh8oxUJJTQ2VWJ7ZXxrwnqAxYGYCmOZsGwzJOafkSi804qc6gCNB7GBAApvBzHhqB8ZjI8wt6BKTlXMHaOKNeTVBg3dnGrqUrKvB1BwO4T0i6xBWZ29mi8Nw8qOkLH6t21RY1Q9Qm0f4Dmm8K/MlkjjoVNUF8b2W0FsvRnEjtutXGEQ4+iSqcc0TKf8u0QFYgA7CXgLdbbcbDV099wNYQWr7x5zVZ0q0eQzXW7Ewv0KXRGpK2pbgGdY2nXhCiay0i66K3CwIcSeUhfCXsp2rlKtdOcXIRTzfRd7Zbi4XvWCOUaiG7NjX1bjVY72dWbHha7lrlHnBX6dbZbxP8iSSKV7iusESh1hHHeGcYJyvMV8Vt+OUor4u2JvWLZ5BfgJ885Nl6WsQ9zOfUt+WApeddgtLGUZP0cagfX0cuBtZr0k1gQZpHrNFbNP5vvf9gL9VprbUDEwuyR6O5OxOww6u3fE4sNSd8oIdw30Z+pRie+r6nmWMsTBMykfRfoZlESJZ1gcJ7OyvuWKW4w"
+ "yKzu4hdk6u4dai57INKhxSOy6ymvBSQYuE9CKMvO9yi6NIja6jHAnN69OL8QdXYof5JZtvQzjAW7mNjxAs17zo8wEw+atPCrq/d6/BKyuvV/7P1DzhMUXazLGAAAAAElFTkSuQmCC";
pojoprofile.setTestImg(picbase64);
You will have adjust profile.html as well to include this new field. (anyway I tested this and it's working as expected)
The fastest way to test your current code would be to call setProfilePic with a base64 hardcoded image
pojoprofile.setProfilePic( "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" );
The Profile class should be changed as well, since we're now using a String instead of a byte[]
class Profile {
//base64 encoded image
private String profilePic;//private byte[] profilePic;
....
}

How can I get full info on update page

I have an ASP.NET Core MVC project without Entity Framework.
When I click on the "update" button, I want to update page and make it does not become empty.
This is my view:
<div class="form-group">
<form asp-action="OdemeTurGuncelle">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
ID
<input asp-for="odemetur_id" class="form-control" />
<span asp-validation-for="odemetur_id" class="text-danger"></span>
</div>
<div class="form-group">
Ödeme Türü
<input asp-for="odemetur_adi" class="form-control" />
<span asp-validation-for="odemetur_adi" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
And my controller :
[HttpGet]
public IActionResult OdemeTurGuncelle()
{
return View();
}
[HttpPost]
public IActionResult OdemeTurGuncelle(OdemeTur odemeTur)
{
string constr = Genel.conString;
using (NpgsqlConnection con = new NpgsqlConnection(constr))
{
string query = "UPDATE odemeturleri SET odemetur_adi=#odemetur_adi WHERE odemetur_id=#odemetur_id";
using (NpgsqlCommand cmd = new NpgsqlCommand(query))
{
cmd.Connection = con;
con.Open();
cmd.Parameters.AddWithValue("#odemetur_id", odemeTur.odemetur_id);
cmd.Parameters.AddWithValue("#odemetur_adi", odemeTur.odemetur_adi);
cmd.ExecuteNonQuery();
con.Close();
}
}
// return View(ders);
return RedirectToAction("Index");
}
I can do it with Entity Framework, but I want to do it without EF

How to show Validation Summary in a modal form with ajax post method?

I'm beginner in ASP.NET Core MVC. I have a problem in my website code.
My model is User that has some fields, and I wrote a view model based on these fields.
I've written the following code:
My view model: RegisterViewModel:
public class RegisterViewModel
{
[Display(Name = "Username")]
[Required(ErrorMessage = "Enter {0} value please.")]
[MaxLength(20, ErrorMessage = "{0} Shouldn't have more than {1} Characters")]
public string Username { get; set; }
[Display(Name = "Password")]
[Required(ErrorMessage = "Enter {0} value please.")]
[MaxLength(50, ErrorMessage = "{0} Shouldn't have more than {1} Characters")]
public string Password { get; set; }
}
My controller: AccountController:
public class AccountController : Controller
{
private IUser _iuser;
public AccountController(IUser iuser)
{
_iuser = iuser;
}
public IActionResult Register()
{
return View();
}
[HttpPost]
public IActionResult Register(RegisterViewModel register)
{
if (ModelState.IsValid)
{
if (_iuser.isUsernameExist(register.Username))
{
ModelState.AddModelError("UserName", "This User Exists!");
return PartialView(register);
}
else
{
User user = new User()
{
Username = register.Username,
Password = HashGenerators.EncodingPassWithMD5(register.Password),
RoleId = 2,
};
_iuser.AddUser(user);
string TabName = "UserTab";
return Json(new { redirectToUrl = Url.Action("Index", "Profile", new {TabName}) });
}
}
else
{
return PartialView(register);
}
}
}
Register action has a view that has displayed as a modal.
View Register.cshtml:
<div class="row">
<div class="col-md-8 col-md-offset-2">
<hr />
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>
<div class="form-group">
<input asp-for="Username" class="form-control" , placeholder="username" id="txtUsername"/>
<span asp-validation-for="Username" class="text-danger" id="ValidationSummery"></span>
</div>
<div class="form-group">
<input asp-for="Password" class="form-control" , placeholder="password" id="txtPassword"/>
<span asp-validation-for="Password" class="text-danger text-right" id="ValidationSummery"></span>
</div>
<div class="form-group">
<input type="button" value="Create" onclick='AddUser()' class="btn-red pull-left" />
<button href="#" type="button" onclick='ClearForm()' class="btn-red pull-right"> Clear Form </button>
</div>
</form>
</div>
</div>
Modal code (at the end of above code):
<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div id="bodyModal" class="modal-body">
</div>
</div>
</div>
</div>
and at the end of view, I have these Ajax scripts:
<script>
function ClearForm() {
$.ajax({
url: "/Account/Register/",
type: "Get",
data: {}
}).done(function (result) {
$('#myModal').modal('show');
$('#bodyModal').html(result);
});
$('#myModal').modal('dispose'); }
</script>
<script>
function AddUser() {
$.ajax({
url: "/Account/Register/",
type: "Post",
data: {
Username: $("#txtUsername").val(),
Password: $("#txtPassword").val(),
},
success: function (response) {
window.location.href = response.redirectToUrl;
}
}).done(function (result) {
$('#myModal').modal('show');
$('#bodyModal').html(result);
});}
</script>
When program is running, the ClearForm button works well, the Create button works well when modelstate is valid. But when modelstate is not valid, it goes to an error page (Hello world!), I see validation errors for 1 second but browser opens an wrong page and doesn't stay on modal for showing validation error.
NOTE: When I delete: ( window.location.href = response.redirectToUrl;) from ajax AddUser function at success part, modal stays open and validation errors displays. But if modelstate is valid, modal stays open but it was empty and destination page(Index/Profile#UserTab) doesn't display.
Please help me, how can I change above code to solve this problem?
I think you can have a new partial view to show the validation message.
Add a hidden input field to the partial view:
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
Then in ajax success function determine whether to show the modal or redirect by judging the value of IsValid
A simple demo based on your codes.
Register.cshtml:
#model RegisterViewModel
#{
ViewData["Title"] = "Register";
}
<h1>Register</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<hr />
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>
<div class="form-group">
<input asp-for="Username" class="form-control" , placeholder="username" id="txtUsername" />
<span asp-validation-for="Username" class="text-danger" id="ValidationSummery"></span>
</div>
<div class="form-group">
<input asp-for="Password" class="form-control" , placeholder="password" id="txtPassword" />
<span asp-validation-for="Password" class="text-danger text-right" id="ValidationSummery"></span>
</div>
<div class="form-group">
<input type="button" value="Create" onclick='AddUser()' class="btn-red pull-left" />
<button href="#" type="button" onclick='ClearForm()' class="btn-red pull-right"> Clear Form </button>
</div>
</form>
</div>
</div>
<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div id="bodyModal" class="modal-body">
</div>
</div>
</div>
</div>
#section scripts{
<script>
function AddUser() {
$.ajax({
url: "/Account/Register/",
type: "Post",
data: {
Username: $("#txtUsername").val(),
Password: $("#txtPassword").val(),
},
success: function (response) {
$('#bodyModal').html(response);
var isValid = $('body').find('[name="IsValid"]').val() == 'True';
if (!isValid) {
$('#myModal').modal('show');
} else {
window.location.href = "#Url.Action("Index", "Profile")";
}
}
});
}
</script>
}
_Register.cshtml(Partial View):
#model RegisterViewModel
<form asp-action="Register">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>
<div class="form-group">
<input asp-for="Username" class="form-control" , placeholder="username" id="txtUsername" readonly />
<span asp-validation-for="Username" class="text-danger" id="ValidationSummery"></span>
</div>
<div class="form-group">
<input asp-for="Password" class="form-control" , placeholder="password" id="txtPassword" readonly />
<span asp-validation-for="Password" class="text-danger text-right" id="ValidationSummery"></span>
</div>
</form>
Controller:
public class AccountController : Controller
{
public IActionResult Register()
{
return View();
}
[HttpPost]
public IActionResult Register(RegisterViewModel register)
{
if (ModelState.IsValid)
{
// do some stuff
}
return PartialView("_Register",register);
}
}
Result:
With inspiring help of https://stackoverflow.com/users/11965297/mj1313, I Changed my code like following and my problem is solved entirely...
In controller, I send a parameter(Valid) by ViewBag to my view, to specify ModelState validity status.
[HttpPost]
public IActionResult Register(RegisterViewModel register)
{
if (ModelState.IsValid)
{
if (_iuser.isUsernameExist(register.Username))
{
ViewBag.Valid= "1"; // It's part of my change
ModelState.AddModelError("UserName", "This User Exists!");
return PartialView(register);
}
else
{
User user = new User()
{
Username = register.Username,
Password = HashGenerators.EncodingPassWithMD5(register.Password),
RoleId = 2,
};
_iuser.AddUser(user);
ViewBag.Valid= "0"; // It's part of my change
string TabName = "UserTab";
return Json(new { redirectToUrl = Url.Action("Index", "Profile", new {TabName}) });
}
}
else
{
ViewBag.Valid= "1"; // It's part of my change
return PartialView(register);
}
}
And in My view, I use a hidden input for save ViewBag.
<form asp-action="Register">
<input name="IsValid" type="hidden" value="#ViewBag.Valid" /> #*It's part of my change*#
<div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>
<div class="form-group">
<input asp-for="Username" class="form-control" , placeholder="username"
</div>
.....
</form>
At the end, I change Ajax function, success part:
function AddUser() {
$.ajax({
url: "/Account/Register/",
type: "Post",
data: {
Username: $("#txtUsername").val(),
Password: $("#txtPassword").val(),
},
success: function (response) {
$('#bodyModal').html(response);
var isValid = $('body').find('[name="IsValid"]').val();
if (isValid) {
$('#myModal').modal('show');
} else {
window.location.href = response.redirectToUrl;
}
}
}).done(function (result) {
$('#myModal').modal('show');
$('#bodyModal').html(result);
});}

form:error not showing error

When validating object controller just refreshes the page, instead showing errors via form:errors, can you tell me where is the problem. I guest it needs to get error from binding result and insert it into the page, instead controller is just refreshing page
Controller :
#PreAuthorize("hasRole('ROLE_ADMIN')")
#RequestMapping(value = "/create", method = RequestMethod.POST)
public String createProduct(MultipartFile image, Model model,#ModelAttribute #Valid ProductDto product, BindingResult bindingResult) throws IOException {
productValidator.validate(product,bindingResult);
if (bindingResult.hasErrors()){
return "admin/create";
} else {
return "index";
}
}
#PreAuthorize("hasRole('ROLE_ADMIN')")
#RequestMapping(value = "/create", method = RequestMethod.GET)
public String createProduct(Model model) {
model.addAttribute("product", new ProductDto());
model.addAttribute("categories", categoryService.findAll());
return "admin/create";
}
Validator :
#Override
public boolean supports(Class<?> aClass) {
return ProductDto.class.equals(aClass);
}
#Override
public void validate(Object o, Errors errors) {
ProductDto product = (ProductDto) o;
if (product.getTitle().isEmpty() || product.getTitle() == null) {
errors.rejectValue("title", "product.title", "Product title cant be empty");
}
if (product.getDescription().isEmpty() || product.getDescription() == null) {
errors.rejectValue("description", "product.description", "Product description cant be empty");
}
if (product.getPrice() == null || product.getPrice()<=0) {
errors.rejectValue("price", "product.price", "Product price is not valid");
}
if (product.getCategoryId()==null) {
errors.rejectValue("category", "product.category", "Product category is not valid");
}
}
jstl page :
<spring:url value="/product/create" var="formUrl"/>
<form:form modelAttribute="product" action="${formUrl }" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>Title</label>
<form:input id="title"
cssClass="form-control" path="title"/>
<form:errors path="title"/>
</div>
<div class="form-group">
<label>Description</label>
<form:textarea id="description" rows="10"
cssClass="form-control" path="description"/>
</div>
<div class="form-group">
<label>Price</label>
<form:input id="price" type="number"
cssClass="form-control" path="price"/>
<form:errors path="description"/>
</div>
<div class="form-group">
<label for="sel1">Select category</label>
<form:select id="sel1" cssClass="form-control" path="categoryId">
<form:options items="${categories}" itemValue="id" itemLabel="title"/>
</form:select>
</div>
<label class="btn btn-default btn-file">
Image <input type="file" multiple accept='image/*' ng-file-select="onFileSelect($files)" name="image" style="display: block;">
</label>
<br><br>
<div class="text-center">
<button type="submit" class="btn btn-lg btn-success text-center"><span
class="fa fa-check"></span> Submit
</button>
<a href="/" class="btn btn-danger btn-lg text-center"><span
class="fa fa-times"></span> Cancel
</a>
</div>
</form:form>
I think your product model attribute has different name in your POST-handling method.
According to documentation:
The default model attribute name is inferred from the declared
attribute type (i.e. the method parameter type or method return type),
based on the non-qualified class name: e.g. "orderAddress" for class
"mypackage.OrderAddress", or "orderAddressList" for
"List<mypackage.OrderAddress>".
So your ProductDto product attribute will have name productDto in resulting model. But you referring the product in your template.
Try to explicitly set the name attribute of #ModelAttribute annotation
public String createProduct(MultipartFile image, Model model, #ModelAttribute(name = "product") #Valid ProductDto product, BindingResult bindingResult)
And to make sure that bidning and validation actually works, try to log it:
if (bindingResult.hasErrors()) {
System.err.println("Form has errors!");
}

ApplicationDbContext.Update() doesn't update but saves it as a new record

I am playing in the new APS.NET 5 RC1 environment but the default edit action creates a new entity of the object. I am searched the whole day finding where it goes wrong but I can't find out why it goes wrong.
Controller:
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using SSTv5.Models;
using SSTv5.Models.Organisations;
using SSTv5.Models.Views;
using System.Collections.Generic;
using SSTv5.Models.Global;
namespace SSTv5.Controllers
{
public class OrganisationTypesController : Controller
{
private ApplicationDbContext _context;
private List<Breadcrumb> _bcList = new List<Breadcrumb>();
public OrganisationTypesController(ApplicationDbContext context)
{
_context = context;
}
#region Edit
// GET: OrganisationTypes/Edit/5
public async Task<IActionResult> Edit(int? id)
{
_bcList.Add(new Breadcrumb("OrganisationTypes", true, "Index", "Index"));
_bcList.Add(new Breadcrumb("Edit", false));
ViewBag.BcList = _bcList;
if (id == null)
{
return HttpNotFound();
}
OrganisationType organisationType = await _context.OrganisationType.SingleAsync(m => m.OrganisationTypeId == id);
if (organisationType == null)
{
return HttpNotFound();
}
return View(organisationType);
}
// POST: OrganisationTypes/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(OrganisationType organisationType)
{
if (ModelState.IsValid)
{
_context.Update(organisationType);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(organisationType);
}
#endregion
}
}
Form:
#model SSTv5.Models.Organisations.OrganisationType
#{
ViewData["Title"] = "Edit";
}
<h2>Edit</h2>
<form asp-action="Edit">
<div class="form-horizontal">
<h4>OrganisationType</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrganisationTypeName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="OrganisationTypeName" class="form-control" />
<span asp-validation-for="OrganisationTypeName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ClassIcon" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ClassIcon" id="classIcon" />
<span asp-validation-for="ClassIcon" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Edit" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
For anyone else who has this problem the answer is quite simple.
The form doesn't send the ID of the object with it. The only thing you need to do is put the id in a hidden field in the form. Then it will work fine.

Resources