Spring Required request part 'file' is not present - spring

I'm trying to upload an image with a form, it's going to be the profile picture, but I get the error:
Required request part 'file' is not present
I'm really new with spring, so I don't know what's wrong here's part of the code:
This is the form
<form th:action="#{/form}" th:object="${cliente}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>Nombre</label>
<input class="form-control" type="text" th:field="*{nombre}" placeholder="Nombre"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('nombre')}" th:errors="*{nombre}"></small>
</div>
<div class="form-group">
<label>Apellido</label>
<input class="form-control" type="text" th:field="*{apellido}" placeholder="Apellido"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('apellido')}" th:errors="*{apellido}"></small>
</div>
<div class="form-group">
<label>Email</label>
<input class="form-control" type="text" th:field="*{email}" placeholder="correo#ejemplo.com"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></small>
</div>
<div class="form-group">
<label>Fecha</label>
<input class="form-control" type="text" th:field="*{createAt}" placeholder="DD/MM/YYYY"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('createAt')}" th:errors="*{createAt}"></small>
</div>
<div class="form-group">
<label>Imagen</label>
<input type="file" name="file" class="form-control" th:field="*{foto}">
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value="Guardar Cambios" />
</div>
<input type="hidden" th:field="*{id}" />
</form>
This is the controller function
#RequestMapping(value="/form", method=RequestMethod.POST)
public String guardar(#Valid Cliente cliente, BindingResult result,
#RequestParam("file") MultipartFile foto, RedirectAttributes flash) {
String mensaje;
if(result.hasErrors()) {
return "form";
}
if(!foto.isEmpty()) {
Path directorioRecursos = Paths.get("src//main//resources//static/uploads");
String pathRoot = directorioRecursos.toFile().getAbsolutePath();
try {
byte[] bytes = foto.getBytes();
Path rutaCompleta = Paths.get(pathRoot + "//" + foto.getOriginalFilename());
Files.write(rutaCompleta, bytes);
flash.addFlashAttribute("info", "Foto subida correctamente");
cliente.setFoto(foto.getOriginalFilename());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(cliente.getId() != null) {
mensaje = "Cliente actualizado correctamente";
}
else {
mensaje = "Cliente creado correctamente";
}
clienteservice.save(cliente);
flash.addFlashAttribute("success", mensaje);
return "redirect:listar";
}
This is my application properties
spring.http.multipart.file-size=10MB
spring.http.multipart.max-request-size=10MB
spring.http.multipart.enabled=true
Can you see what's wrong?

you're attaching a file to a string field with the th:field="*{foto}" ,
remove the th:field part in the input , should be like this:
<input type="file" name="file" class="form-control" />

Related

Upload file with Boostrap Modal on Asp.net core 2.1

I want to upload a file and send to email. But I don't see how to do this with Bootsrap Modal.
If you want any other information, tell me.
I would like to send the attached file by email then also integrate it in my database and be able to download it.
/[...]/ ==> Code that I didn't add, not useful.
Edit : Otherwise how to do with Ajax ?
My View :
<form name="contact" method="post" asp-action="Validation">
#if (ViewBag.Alert != null && ViewBag.Alert != "")
{
<div class="alert role="alert">
#ViewBag.Alert
</div>
}
<div class="details">
<h3 class="title">Demande</h3>
<label for="card">Type *</label>
<select required onchange="contact()" class=" form-control" disabled="true" name="type" value="#ViewBag.Form.Type">
<option value="1">Choose 1</option>
<option value="2">Choose 2</option>
</select>
<label for="card">Origine *</label>
<select required class="form-control" name="origine" value="#ViewBag.Form.Origine">
<option value="1">Origine 1</option>
<option value="2">Origine 2</option>
<option value="3">Origine 3</option>
</select>
/*[...]*/
<input type="hidden" name="Id" value="#ViewBag.Form.Id" />
<input type="hidden" name="Price" value="#ViewBag.Form.Price" />
/*[...]*/
<textarea class="form-control" name="Response" placeholder="Response..."></textarea>
<button required class="btn" onclick="modal_response()" data-whatever="getbootstrap" data-toggle="modal" data-target="#modal_contact" type="button">Response</button>
<label for="card" class="right">Response send</label><br />
<button required class="btn_second" onclick="modal_save()" data-whatever="getbootstrap" data-toggle="modal" data-target="#modal_contact_save" type="button">Save</button>
<label for="card-holder" class="right">Save Ok!</label>
/*[...]*/
<div class="form-row">
<button class="btn-primary" onclick="form_confirmation()" type="submit">Save All</button>
<button class="btn-secondary" type="reset" onclick="location.href = '#Url.Action("List", "Control", new { id = ViewBag.Id })';">Close</button>
</div>
</div>
</form>
/* When I click on "Response" a new window open */
<div class="modal fade" id="modal_contact" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<h5 class="modal-title" id="modal_label">Send email to : #ViewBag.Form.Name</h5>
<button type="button" class="close" data-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="modal_contact_form" enctype = "multipart/form-data" method="post" action="#Url.Action("Modal_contact", "Control")">
<div class="form-group">
<input type="file" name="file" accept="application/pdf" /><br /><br />
<textarea class="form-control" name="Description" required placeholder="Content">#ViewBag.Response</textarea>
</div>
<input type="hidden" name="Id" value="ID" hidden />
<input type="hidden" name="Price" value="#ViewBag.Form.Price" hidden />
<input type="hidden" name="Type" value="#ViewBag.Form.Type" hidden />
/*[...]*/
<input type="submit" hidden />
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" data-dismiss="modal" onclick="$('#modal_contact_form').submit();" class="btn-primary">Send Email</button>
</div>
</div>
My Controller :
public class MyController : BaseEntity
{
[Required]
public string Id { get; set; }
public string Price { get; set; }
public string Type { get; set; }
/*[...]*/
/* For File I don't know if it's good?? */
public IformFile File { get; set; }
}
My Model :
public ActionResult Modal_contact(MyController model)
{
/* How to retrieve file ?? */
bool ok = false;
OtherController OC = new OtherController();
/*[...]*/
if (ModelState.IsValid)
{
OC = othercontrollerRepository.Find(model.Id);
OC.Email = this.Session_get("Email");
OC.Description = "";
model.Email = this.Session_get("Email");
model.Status = "1";
model.View = "response";
/*[...]*/
if (mycontrollerRepository.Add(model) && othercontrollerRepository.Update(OC))
{
/* How to send file to email and save file to folder in my project to add in my database ? */
MailManager mail = new MailManager();
Modele modele = new Modele();
modele= modeleRepository.Find("response");
ok = mail.send(modele.Objet, model.Description, OC.Email);
}
return Json(new { Json_result = ok, Redirect = "" });
}
return Json(new { Json_result = false, Redirect = "" });
}
I found my error :
Form before <div>
I tried your code and reproduced your issue. I noticed that you named the IFormFile object as File.
public IFormFile File { get; set; }
But input file you are getting is named file.
<input type="file" name="file" accept="application/pdf"/><br /><br />
Asp.net core model binding will bind the property according to the input name. This is the reason why you couldn't get the IFormFile value in controller.
To solve this issue, you should change the name of the input to File so that they could match each other.
Like below:
<input type="file" name="File" accept="application/pdf"/><br /><br />
Result:

Vue.js Asp.NET core Form validation

I am currently learning vuejs with asp .net core right now.
I am doing some form validation and adding some error messages.
The error messages are from the Server side here is my sample code:
[HttpPost]
public async Task<IActionResult> AddUser([FromBody] UserModel user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (_context.Users.Any(u => u.UserName == user.UserName))
{
ModelState.AddModelError("UserName", "Username is already in used");
return BadRequest(ModelState);
}
try
{
var userDto = new User
{
FirstName = user.FirstName,
LastName = user.LastName,
Password = user.Password,
UserName = user.UserName
};
_context.Users.Add(userDto);
await _context.SaveChangesAsync();
}
catch(Exception e)
{
ModelState.AddModelError("Saving Error", string.Format("Error in saving user. \nDetails:\n {0}", e.Message));
return BadRequest(ModelState);
}
return Ok();
}
And in the view:
<form v-on:submit.prevent="SaveUser()">
<div class="form-group">
<label for="userName">User Name</label>
<input class="form-control" type="text" id="userName" placeholder="Username" v-model="userName" required :disabled="isEditMode" />
</div>
<div class="form-group">
<label for="userName">First Name</label>
<input class="form-control" type="text" id="firstName" placeholder="First Name" v-model="firstName" required />
</div>
<div class="form-group">
<label for="userName">Last Name</label>
<input class="form-control" type="text" id="lastName" placeholder="Lastname" v-model="lastName" required />
</div>
<div v-if="!isEditMode">
<div class="form-group">
<label for="userName">Password</label>
<input class="form-control" type="password" id="password" placeholder="Password" v-model="password" required />
</div>
</div>
<!--TODO: Distribute to each control-->
<div v-if="hasError">
<ul v-for="error in errors">
<li style="color: red;" v-for="detail in error">{{detail}}</li>
</ul>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<button type="button" #click="backToList()" class="btn btn-danger">Cancel</button>
</form>
Basically I am doing the validations from the server-side.
Currently the error messages are displayed below the controls
And I need to distribute all the error message inline with the inputs.
Can you help me with this?
Thanks in advance.

Springboot - java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute [duplicate]

This question already has answers here:
What causes "java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute"?
(7 answers)
Closed 5 years ago.
I get the following error:
java.lang.IllegalStateException: Neither BindingResult nor plain target object
for bean name 'user' available as request attribute
When I try to call this method:
#RequestMapping(value="/invite", method = RequestMethod.GET)
public ModelAndView showInvitePage(ModelAndView modelAndView,#ModelAttribute("user") User user){
return modelAndView;
}
this is the thymeleaf page:
<div class="container">
<div class="wrapper">
<form class="form-activate" th:action="#{/invite}" method="post" th:object="${user}">
<h2 class="form-activate-heading">Nodig een student uit</h2>
<p>Vul hier het e-mailadres in van de student die je wil uitnodigen:</p>
<div class="form-group">
<input type="text" th:field="*{username}" class="form-control input-lg"
placeholder="Username" tabindex="1"/>
</div>
<div class="form-group">
<input type="text" th:field="*{email}" class="form-control input-lg"
placeholder="Username" tabindex="2"/>
</div>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<input type="submit" class="btn btn-secondary" value="Invite"/>
</div>
</div>
</form>
</div>
It's odd because I have another method which is almost a copy of this one and it works perfectly fine here:
#RequestMapping(value="/register", method = RequestMethod.GET)
public ModelAndView showRegistrationPage(ModelAndView modelAndView, #ModelAttribute User user){
return modelAndView;
}
and the thymeleaf page:
<div class="wrapper">
<form class="form-signin" th:action="#{/register}" method="post" th:object="${user}">
<h2 class="form-signin-heading">Registratie</h2>
<div class="form-group">
<input type="text" th:field="*{username}" class="form-control input-lg"
placeholder="Username" tabindex="1"/>
</div>
<div class="form-group">
<input type="text" th:field="*{email}" class="form-control input-lg"
placeholder="Email" tabindex="2"/>
</div>
<div class="form-group">
<input type="password" th:field="*{encryptedPassword}" id="password" class="form-control input-lg"
placeholder="Password" tabindex="3"/>
</div>
<div class="form-group">
<input type="password" name="password_confirmation" id="password_confirmation"
class="form-control input-lg" placeholder="Confirm Password" tabindex="4"/>
</div>
The only thing I might think of is that when you call the invite method, a user is already logged in and is doing the actual inviting. When registering, no user is logged in yet.
EDIT:
I removed the thymeleaf th:field from the input fields and used the classic way and it works fine now.
<div class="form-group">
<input type="text" name="username" id="username" class="form-control input-lg"
placeholder="Username" tabindex="2"/>
</div>
<div class="form-group">
<input type="text" name="email" id="email" class="form-control input-lg"
placeholder="Email" tabindex="2"/>
</div>
You are getting this exception because there is no user object to which Spring can bind. So add one to the model in your GET method:
#GetMapping("/invite") //use shorthand
public String showInvitePage(Model model) {
model.addAttribute("user", new User()); //or however you are creating them
return "theFormNameWithoutTheExtension";
}
Then your POST would have the processing:
#PostMapping("/register")
public String showRegistrationPage(#ModelAttribute("user") User user) {
//do your processing
return "someConfirmationPage";
}

Spring MVC :- Form Submission (HTTP Status 400 - The request sent by the client was syntactically incorrect.)

There are two forms each having one submit button in my jsp page ... I want to send form 1 to my controller which consists of two images and few form fields.
Controller.java
#RequestMapping(value="/schoolDetails",method=RequestMethod.GET)
public ModelAndView getschoolDetails(){
ModelAndView model = new ModelAndView();
School schools=new School();
Map referenceData = new HashMap();
referenceData.put("schoolObject", schools);
ModelAndView mav = new ModelAndView("schoolDetails", referenceData);
return mav;
}
#RequestMapping(value="/addSchoolDetails",method=RequestMethod.POST)
public String addSchoolDetails(#ModelAttribute("schoolObject") School school,
#RequestParam("image") MultipartFile image,#RequestParam("logo") MultipartFile logo){
if(result.hasErrors()){
return "schoolDetails"; }
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
CustomUser user=null;
if (principal instanceof CustomUser) {
user = ((CustomUser)principal);
}
return "schoolDetails";
}
schoolDetails.jsp
<form:form method="POST" role="form" action="/GenericApp/addSchoolDetails" enctype="multipart/form-data" modelAttribute="schoolObject">
<div class="col s3" id="sName">School Name :</div>
<input id="form_text" name="schoolname" type="text" placeholder="School Name"/>
<div class="col s3" id="sName">Email ID :</div>
<input id="form_text" name="email" type="email" placeholder="Email ID"/>
<div class="col s3" id="sName">State :</div>
<select name="state" id="state_id" >
<option>State</option>
<option>Karnataka</option>
</select>
<div class="col s12 m4 l4" id="sName">Upload School Logo :</div>
<input type="file" name="logo" id="fileUpload" accept="image/x-png, image/gif, image/jpeg"/>
<span class="button teal ">Choose a Image</span>
<button class="waves-effect waves-light btn" type="submit" name="action">Submit</button>
</form:form>
As your jsp does not contain any tag having name image correct your jsp file by adding tag with name image also , as below
<form:form method="POST" role="form" action="/GenericApp/addSchoolDetails" enctype="multipart/form-data" modelAttribute="schoolObject">
<div class="col s3" id="sName">School Name :</div>
<input id="form_text" name="schoolname" type="text" placeholder="School Name"/>
<div class="col s3" id="sName">Email ID :</div>
<input id="form_text" name="email" type="email" placeholder="Email ID"/>
<div class="col s3" id="sName">State :</div>
<select name="state" id="state_id" >
<option>State</option>
<option>Karnataka</option>
</select>
<div class="col s12 m4 l4" id="sName">Upload School Logo :</div>
<input type="file" name="logo" id="fileUpload" accept="image/x-png, image/gif, image/jpeg"/>
<span class="button teal ">Choose a Image</span>
<input type="file" name="image" id="image" accept="image/x-png, image/gif, image/jpeg"/>
<button class="waves-effect waves-light btn" type="submit" name="action">Submit</button>
</form:form>

Cannot submit a form on SpringMVC

I am fairly new to SpringMVC and have a form that can not submit to the back-end. I created the form as following and when I submit it error 404 will be returned. I changed action to /MyProject/contact but did not work.
<form class="form-horizontal" role="form" method="post"
action="/contact">
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Name
</label> <input type="text" class="form-control" id="name"
name="name" placeholder="Your name" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Email
Address</label> <input type="email" class="form-control" id="email"
name="email" placeholder="Your email" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Phone
Number</label> <input type="number" class="form-control" id="phone"
name="phone" placeholder="Phone number" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Enquiry</label>
<textarea class="form-control" rows="4" name="message"
placeholder="Please enter your enquiry"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-2 " style="float: right;">
<input id="submit" name="submit" type="submit" value="Send"
class="btn btn-primary">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<! Will be used to display an alert to the user>
</div>
</div>
</form>
Controller
#Controller
public class ContactController {
#RequestMapping(value="/contact", method=RequestMethod.POST)
public String processForm(Contact contact, Model model){
System.err.println("Contact Name is:" + contact.getName());
return null;
}
}
Error
HTTP Status 404 - /contact
type Status report
message /contact
description The requested resource is not available.
Its beacuse spring does not know how to pass the param Contact contact to your controller method. You need to do couple of things to make it work. Change your form to like below.
<form class="form-horizontal" role="form" method="post" modelAttribute="contact" action="/contact">
Your controller to take contact as model attribute.
#Controller
public class ContactController {
#RequestMapping(value="/contact", method=RequestMethod.POST)
public String processForm(#ModelAttribute Contact contact, Model model){
System.err.println("Contact Name is:" + contact.getName());
return null;
}
}
For a better understanding of what a model attribute does, there are plenty of samples and explanation online. Hope this helps.
I could solve the problem by help of minion's answer, following this tutorial and adding following link
#RequestMapping(value = "/contact", method = RequestMethod.GET)
public ModelAndView contactForm() {
System.err.println("here in GET");
return new ModelAndView("contact", "command", new Contact());
}

Resources