Hidden input data is not passed from view component to post action method in controller - ASP.NET Core 6 MVC - asp.net-core-mvc

I am trying to pass parameters value from a view component to a post action method, but the hidden input is not received in the controller.
I know how to pass from view to controller and it works fine, but in the view component it is not passed to action.
This is component for show images in Edit view:
public class EditPostImageComponent: ViewComponent
{
private IPostService _postService;
public EditPostImageComponent(IPostService postService)
{
_postService = postService;
}
public async Task<IViewComponentResult> InvokeAsync(ShowPostListItemViewModel showPostListItemViewModel)
{
return await Task.FromResult((IViewComponentResult)View("EditPostImage", _postService.GetPostGallary(showPostListItemViewModel.PostId)));
}
}
This is view component for displaying images:
#model List<DataLayer.Models.ViewModels.Post.ShowPostListItemViewModel>
#foreach (var item in Model)
{
<div class="col-lg-4 mb-4">
#if (item.ImageName != null)
{
<form method="post" asp-area="Admin" asp-controller="Post" asp-action="DeletePostImg">
<input type="hidden" asp-for="#item.PostId" />
<input type="hidden" asp-for="#item.Title" />
<input type="hidden" asp-for="#item.Description" />
<input type="hidden" asp-for="#item.ImageName" />
<div class="blog-item position-relative overflow-hidden rounded mb-2">
<img id="imgPost" class="img-fluid thumbnail" src="/img/post/#item.Title/#item.ImageName" alt="">
<br />
<br />
#*<a asp-controller="Post" asp-action="DeletePostImg"
asp-route-id="#item.PostId" class="btn btn-danger btn-sm">Delete</a>*#
<input type="submit" class="btn btn-danger btn-sm" value="Delete" />
</div>
</form>
}
else
{
<div class="blog-item position-relative overflow-hidden rounded mb-2">
<img id="imgAvatar" class="thumbnail" src="/UserAvatar/Defult.jpg" />
</div>
}
</div>
This is action method for delete images from database directly.
[HttpPost]
public void DeletePostImg(ShowPostListItemViewModel showPostListItemViewModel)
{
_postService.DeletePostImage(showPostListItemViewModel);
}
When I debug, I get a null or zero value for input hidden fields. in view,in similar circumstances these parameters is sent to the controller correctly.
Where is the problem from? Please help me
Thanks a lot

You could press F12 to check the name attribute of the input box,in your case,the name was item.PostId but in your controller the name of the parameter is showPostListItemViewModel ,the name don't match,so it bind failed
You could try as below in your view component:
#foreach (var showPostListItemViewModel in Model)
{
<form method="post" asp-controller="Home" asp-action="Post">
<input type="hidden" asp-for="#showPostListItemViewModel.PostId">
<br />
<input type="hidden" asp-for="#showPostListItemViewModel.Description">
<div class="blog-item position-relative overflow-hidden rounded mb-2">
<input type="submit" value="Submit" />
</div>
</form>
}
The Result:

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:

using route resource form did not post to store function

I have a form which upon successful validation should show the desired result. But on button press the browser displays The page has expired due to inactivity. Please refresh and try again.
view page
<form class="form-horizontal" method="POST" action="{{action('BookController#store')}}">
<div class="row" style="padding-left: 1%;">
<div class="col-md-4">
<div class="form-group">
<label>Book Name</label><span class="required">*</span>
<input type="text" maxlength="100" minlength="3" required="required" runat="server" id="txtBookName" class="form-control" autocomplete="off" autofocus="autofocus" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>
Route code
//web.php
Route::resource('book','BookController');
controller code
class BookController extends Controller
{
public function index()
{
//
}
public function create()
{
return view('pages.book');
}
public function store(Request $request)
{
$validatedInput = $request -> validate([
'txtBookName' => 'required|string|min:3|max:100'
]);
return $validatedInput;
}
}
Form url
http://127.0.0.1:8000/book/create
on submit button press, the page is redirected to
http://127.0.0.1:8000/book and it displays The page has expired due to inactivity. Please refresh and try again.
You can either post a CSRF token in your form by calling:
{{ csrf_field() }}
Or exclude your route in app/Http/Middleware/VerifyCsrfToken.php:
protected $except = [
'your/route'
];
Implement like this to avoid Expired message.
<form action="{{ action('ContactController#store') }}" method="POST">
#csrf <!-- this is the magic line, works on laravel 8 -->
<!--input components-->
<!--input components-->
<!--input components-->
</form>
you should use {{ csrf_field() }} in your form.
Please do this after the form class, because the resource take the #method('PUT')
<form class="form-horizontal" method="POST" action="{{action('BookController#store')}}">
{{csrf_field()}}
#method('PUT')
<div class="row" style="padding-left: 1%;">
<div class="col-md-4">
<div class="form-group">
<label>Book Name</label><span class="required">*</span>
<input type="text" maxlength="100" minlength="3" required="required" runat="server" id="txtBookName" class="form-control" autocomplete="off" autofocus="autofocus" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>

Form submit with a file in Spring mvc + bootstrap

Its a two part question.
I am trying to submit a pop up form with a file and textarea. I am not able to receive file in my controller code.
Part 1 - How do I receive the file at the controller.
Part 2 - Once I submit the form, how do I close the popup and remain on the same page so that URL does not change.
Popup code-
<form name="eperform">
<div class="modal fade" id="export" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<span class="glyphicon glyphicon-remove" aria-hidden="true" style="padding-top: 10px;"></span>
</button>
<h4 class="modal-title custom_align" id="Heading">Provide ID's here:</h4>
</div>
<div class="form-group">
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">File Upload</legend>
<input id="fileUpload" name="fileUpload" type="file" style="margin-left: 20px"/>
</fieldset>
</div>
<br/>
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">Ids</legend>
<label for="envIds"></label>
<textarea class="form-control noresize" rows="4" style="width:98% " name="ids" id="ids" value="">
</textarea>
<input type="hidden" id="server" name="server" value="${server}">
<input type="hidden" id="port" name="port" value="${port}">
<input type="hidden" id="queuename1" name='queuename1' value="">
<input type="hidden" id="environment" name="environment" value="${environment}">
</fieldset>
</div>
</div>
<div class="modal-footer ">
<button type="button" class="btn btn-success" id="eid"
onclick="exportObjects(document.getElementById('ids').value,document.getElementById('queuename1').value,'${port}','${server}','${environment}',document.getElementById('fileUpload').value)">
<span class="glyphicon glyphicon-ok-sign"></span>Export
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
<span class="glyphicon glyphicon-remove"></span> Cancel
</button>
</div>
</div>
</div>
</div>
</form>
Javascript code-
function exportObjects(ids, queueName, port, server, environment, fileUpload) {
var strHREF = "/exportObjects?ids=" + ids
+ "&queueName=" + queueName + "&port=" + port + "&server="
+ server + "&environment=" + environment +"&fileUpload=" + fileUpload;
document.eperform.action = strHREF;
document.eperform.submit();
}
Controller code-
#RequestMapping(value="/exportObjects", method = RequestMethod.GET)
public ModelAndView exportObjects(HttpServletRequest request) throws Exception{
String server =request.getParameter("server");
String port =request.getParameter("port");
String environment = request.getParameter("environment");
String type =request.getParameter("queueName");
String ids = request.getParameter("ids");
CommonsMultipartFile file = (CommonsMultipartFile) request.getAttribute("fileUpload");
if(file != null && file.getSize() != 0){
String path=request.getServletContext().getRealPath("/");
String filename=file.getOriginalFilename();
System.out.println(path+" "+filename);
try{
InputStream in = file.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
System.out.println(out.toString());
}catch(Exception e){System.out.println(e);}
}
// Perform action on ids and file data
ModelAndView model = new ModelAndView();
// I do not know what to do here.
return model;
}
It seems that you are not familiar with web developement,I recommend you take some time to review the java web development knowledge.
Below are the answer for your two questions:
If you want to upload a file to the server,you must add enctype="multipart/form-data" to your form
<form name="eperform" enctype="multipart/form-data">
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">File Upload</legend>
<input id="fileUpload" name="fileUpload" type="file" style="margin-left: 20px"/>
</fieldset>
</div>
</form>
If you want to stay on the same page,you should using an asynchronous method to submit your action,and Ajax is your best choice.You need to submit your request and in the success callback method close the popup dialog.
$.ajax({
url:"exportObjects",
type:"post",
data:{
queueName:queueName,
port:port,
server:server,
environment:environment
},
success:function(data){
//if the request submit success,invoke 'close' method to close the dialog
$("#dialog_div").dialog("close");
}
});
In your springmvc code,you should not use ModelAndView because it will forward to a new page,you need to return an original string,like the code listed below,after that you can use MultipartFile to get your upload file:
#RequestMapping(value="eperform",method=RequestMethod.POST)
#ResponseBody
public String updateNodeRelation(#RequestParam(value="fileUpload")
MultipartFile file,HttpServletRequest request) {
System.out.println(file.getOriginalFilename());
return "success";
}
UPDATED
If you want to submit a file and then stay on the same page,then you need to use iframe and not use Ajax,as below:
<!-- using iframe to stay on the same page-->
<form id="eperform"name="eperform" action="exportObjects" enctype="multipart/form-data"
target="hidden_frame">
<div>
<fieldset style="margin-left: 10px;">
<legend style="font-size: medium;">File Upload</legend>
<input id="fileUpload" name="fileUpload" type="file"
style="margin-left: 20px"/>
</fieldset>
</div>
<iframe id="hidden_frame" name="hidden_frame"
style="display:none"/>
<button type="button" onclick="submitFile()">Submit</button>
</form>
And using the below Javascript code to submit the form and close popup dialog**
function submitFile(){
$("#eperform").submit();
$("#dialog_div").dialog("close");
}

Thymeleaf Binding list of objects

Here's my Object that I've retrieved from the DB:
#RequestMapping("/category/edit/{id}")
#org.springframework.transaction.annotation.Transactional
public ModelAndView displayCategoryList(#PathVariable("id")Integer id){
ModelAndView mav = new ModelAndView("category-form");
List<CatFeatGroup> catFeatGroupList = catFeatGroupService.findGroupsForCategory(id);
mav.addObject("catFeatGroupList",catFeatGroupList);
return mav;
}
Here's my form.
<form class="form-horizontal">
<div th:each="catFeatGroup,status : ${catFeatGroupList}" class="form-group">
<label>Position</label><input th:field="catFeatGroupList[${status.index}].position" th:value="${catFeatGroup.position}" />
<label>Name</label> <input name="catGroupList[${status.index}].name" th:value="${catFeatGroup.name}" />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
I need to use th:field to bind that object however this error shows up:
Could not parse as expression: "catFeatGroupList[${status.index}].position"
Add the "__" notation like this
<form class="form-horizontal">
<div th:each="catFeatGroup,status : ${catFeatGroupList}" class="form-group">
<label>Position</label><input th:field="*{catFeatGroupList[__${status.index}__].position}" th:value="${catFeatGroup.position}" />
<label>Name</label> <input data-th-name="*{catFeatGroupList[__${status.index}__].name}" th:value="${catFeatGroup.name}" />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>

While form submitting using ajax..getting Post not supported error ...don't know what is the error?

I am using form submission using AJAX in Spring MVC and Thymeleaf. When I try to submit it it shows
Post method is not supported
I can't figure out the mistake in my code:
<form class="form-horizontal" action="#" th:action="#{/teacher/teacherProfileUpdation}" th:object="${teacherProfileDetailsList}"
id="saveTeacherForm" method="POST" >
<br />
<div class="row">
<div class="col-lg-14 col-md-12">
<br />
<h5 style="margin-left: 15%;">Personal Details</h5>
<hr />
<div class="form-group">
<label class="col-sm-3 control-label">Name</label>
<div class="col-md-3 col-sm-4 col-xs-4">
<input placeholder="Teacher first name" id="txtTeacherFname" th:field="*{firstName}" type="text" class="form-control" />
</div>
<div class="col-md-3 col-sm-4 col-xs-4">
<input placeholder="Teacher middle name" id="txtTeacherMname" th:field="*{middleName}" type="text" class="form-control" />
</div>
<div class="col-md-3 col-sm-4 col-xs-4">
<input placeholder="Teacher last name" id="txtTeacherLname" th:field="*{lastName}" type="text" class="form-control" />
</div>
</div>
</div>
<div class="col-lg-14 col-md-12">
<div class="form-actions">
<input type="hidden" id="hdnStudentByIdInSchoolAdmin" value="0" />
<input type="button" class="btn btn-info pull-right" id="btnUpdateTeacherProfile" value="Save" />
</div>
</div>
</div>
JS:
saveTeacherProfile :function(){
$("#saveTeacherForm").ajaxForm({
success : function(status) {
alert("success");
},
}).submit();
}
Controller:
#RequestMapping(value = "/updateTeacherProfile", method = RequestMethod.POST)
public String updateTeacherProfile( TeacherProfileDetails teacherProfileDetails){
System.out.println("-----------"+teacherProfileDetails.getFirstName()+"-------------");
System.out.println("-----------"+teacherProfileDetails.getLastName()+"-------------");
System.out.println("-----------"+teacherProfileDetails.getMiddleName()+"-------------");
return "success";
}
You are posting the form, but most likely your Spring controller is not configured to accept POST requests. Try this in your server-side Controller class for this page:
#RequestMapping(..., method = { RequestMethod.GET, RequestMethod.POST }, ...)
public void myControllerMethod()
{
#RequestMapping(..., method = { RequestMethod.GET, RequestMethod.POST }, ...)
public String updateTeacherProfile( TeacherProfileDetails teacherProfileDetails){
//ur Logic
}

Resources