passing data of image to controller fails - c#

I am making an Image from a div by html2canvas, then want to sent it back to controller. I set the result in input text file, to have the value in controller
I have this in client side:
var element = $("#chng");
html2canvas(element,{
onrendered : function(canvas){
var imageData = canvas.toDataURL("image/jpg");
var newData= imageData.replace(/^data:image\/jpg/, "data:application/octet-stream");
$("#img1").val(newData);
}
});
$("#infoForm").submit();
and
<form method="post" enctype="multipart/form-data" asp-controller="Answers" id="infoForm">
<input type="text" id="img1" name="img1" />
<input type="button" onclick="formsubmit()" value="print PDF" />
</form>
and controller
[HttpPost]
public async Task<IActionResult> PrintPDF(long wId, long cId, long pId, long aId, short no , string img1)
{
//but img1 is always null
//ToDO something here
return View();
}
but img1 is always null although the value if newData and imageData in clientside are ok
what could be the problem?

Firstly, the <form> element in your HTML does not have an asp-action attribute specifying the action method that should be called when the form is submitted. This means that the form will not be submitted to the correct action method, and the img1 parameter will not be passed to the controller.
You can fix this issue by adding an asp-action attribute to the <form> element:
<form method="post" enctype="multipart/form-data" asp-controller="Answers" asp-action="PrintPDF" id="infoForm">
Secondly, the onclick attribute of the <input> element is calling a formsubmit() function, but there is no such function defined in your code. Therefore the form will not be submitted when the button is clicked, and the img1 parameter will not be passed to the controller.
You can fix this issue by removing the onclick attribute from the<input> element, and calling the submit() method of the infoForm form in the JavaScript code:
var element = $("#chng");
html2canvas(element,{
onrendered : function(canvas){
var imageData = canvas.toDataURL("image/jpg");
var newData= imageData.replace(/^data:image\/jpg/, "data:application/octet-stream");
$("#img1").val(newData);
}
});
$("#infoForm").submit();
Third, the enctype attribute of the <form> element is set to "multipart/form-data", but the img1 parameter is not a file being uploaded. This can cause the img1 parameter to be null in the controller, because the multipart/form-data encoding is not appropriate for non-file data.
You can fix this issue by changing the enctype attribute of the <form> element to "application/x-www-form-urlencoded":
<form method="post" enctype="application/x-www-form-urlencoded" asp-controller="Answers" asp-action="PrintPDF" id="infoForm">

Related

How to pass Text instead of Value from select list to controller in Asp .Net Core

I have two <slect> list and I want to pass only Text to the controller. I don't know if its possible.
This is Html :
<form asp-action="Crea" method="post">
<select asp-for="Azienda_cliente" class="select2 form-control" id="ddlClienti" onchange="LoadSottoCliente(value)"></select>
<select asp-for="Azienda_sotto_clienti" class="select2 btn-block" id="ddlSottoClienti"></select>
<input type="submit" value="Crea" class="w-50 btn btn-success" />
</form>
And this is controller:
[HttpPost]
public async Task<IActionResult> Crea(Attiivita attivita)
{
if (ModelState.IsValid)
{
_db.Add(attivita);
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View();
}
Is it possible to post only Text from the select list?
Any suggestions how to do that?
Thanks in advance!
I have two <select> list and I want to pass only Text to the controller.
In your form, when you submit the form, the Value of the selected option would be posted to controller action method.
If you'd like to post Text of the selected option to controller action, you can try following two approaches:
Approach 1: populate your dropdown(s) with expected data as Value property.
<select asp-for="Azienda_cliente" asp-items="ViewBag.ClientItems" class="select2 form-control" id="ddlClienti" onchange="LoadSottoCliente(value)"></select>
In action method
ViewBag.ClientItems = new List<SelectListItem>
{
//normally we populate Value property with Id etc field
//in your code logic, you can populate it with your expected data (same as you set for Text property)
new SelectListItem { Value = "ClientName", Text = "ClientName" },
//...
//other items
};
For the second dynamic dropdown, you can set Value property with same data as Text of each <option>.
$("select#ddlSottoClienti").append(`<option value="${text_here}">${text_here}</option>`);
Approach 2: you can get text of the selected option(s), then submit data using jQuery Ajax etc on JavaScript client side.
$("input[type='submit']").click(function (ent) {
ent.preventDefault();
var Azienda_cliente = $("select#ddlCLienti option:selected").text();
var Azienda_sotto_clienti = $("select#ddlSottoClienti option:selected").text();
//make ajax request to your controller action
//...
})

ASP.NET MVC Post method : Model properties does not persit the value

I have 2 ASP.NET MVC action methods, I call the first method by passing and load some initial data, then I get some additional details from UI and call the second action method (Post action method from .cshtml). The data I received from the first call is missing in the post method. can anyone help me what am I doing wrong or missing here?
Action methods:
[Route("setprofile")]
public ActionResult SetProfile(string id)
{
ProfileData data = new ProfileData();
//do something
data.name= getData(id);
return this.View(data);
}
[Route("setprofile")]
[HttpPost]
public ActionResult SetProfile(ProfileData data)
{
// Here I'm not missing the data.name field value
}
View .cshtml file:
<div class="panel-body">
#using (Html.BeginForm("SetProfile", "Home", FormMethod.Post))
{
<div>
<h3> Name: #(this.Model.name)</h3>
</div>
<h3>
Comments:#Html.TextBoxFor(m => m.comments)
</h3>
}
I get the comments value but not getting the name field value from the model here.
Note: I need to display the value I received from the first action method as a label, not text box.
There are two things, Name is writen as text and in order to send back to server, you need to put it inside input element.
IF you dont want to show it #Html.HiddenFor(m => m.name) creates hidden input element.
Other than this, check ModelState for validation errors..
if (!ModelState.IsValid)
return BadRequest(ModelState);
.... your code here
if your model is not valid, the ProfileData returns result
You haven't added an input element for it to be sent back to the server when the form is submitted. If you don't want it to be visible, whilst still being posted back, add a hidden field for it:
#Html.HiddenFor(m => m.name)
Without that, all you're doing is rendering name to the markup but, once the form is submitted, it won't be sent back. Alternatively, you could render a textbox for the value whilst setting its readonly attribute. That would allow it to be visible, not changed, and still be sent back to the server.
#Html.TextBoxFor(m => m.name, new { #readonly = "readonly" })

MVC 5 Uploading file (POST) with one additional parameter

I am using this simple tutorial to upload a file in my MVC5 C# VS2015 project, and without requireing additional parameters in controllers action, file gets successfuly uploaded. Here are controllers action
[HttpPost]
public string UploadFile(HttpPostedFileBase file)
{
if (file.ContentLength <= 0)
throw new Exception("Error while uploading");
string fileName = Path.GetFileName(file.FileName);
string path = Path.Combine(Server.MapPath("~/Uploaded Files"), fileName);
file.SaveAs(path);
return "Successfuly uploaded";
}
and view's form for uploading
#using (Html.BeginForm("UploadFile", "Documents", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.TextBox("file", "", new { type = "file" })
<input type="submit" value="Dodaj fajl" />
}
In that view, I have another variable called DocumentNumber, that I need to pass on to UploadFile action. I only guess that then header of my action would look like this: public string UploadFile(HttpPostedFileBase file, int docNo) if I wanted to pass that variable on, but I also don't know how to set this value in view's form. I tried adding: new { enctype = "multipart/form-data", docNo = DocumentNumber } without success. How do I pass DocumentNumber (that needs to be hidden, not visible) from my view to controller's action with post method?
Add a parameter to your action method
[HttpPost]
public string UploadFile(HttpPostedFileBase file,int DocumentNumber)
{
}
and make sure your form has an input element with same name. It can be a hidden or visible. When you submit the form, the input value will be send with same name as of the input element name, which is matching to our action method parameter name and hence value will be mapped to that.
#using (Html.BeginForm("UploadFile", "Documents", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.TextBox("file", "", new { type = "file" })
<input type="text" name="DocumentNumber" value="123"/ >
<input type="submit" value="Dodaj fajl" />
}
If you want to use the DocumentNumber property value of your model, you may simply use one of the helper methods to generate the input element with the value (which you should set in the GET action method)
#Html.TextBoxFor(s=>s.DocumentNumber)
or for the hidden input element
#Html.HiddenFor(s=>s.DocumentNumber)

How do I save my MVC4 model if I need 2 submit buttons?

I have to allow the user to move to the next or previous form, I just need to save the model on navigation. Is there another way to pass back the model to the controller besides using submit? Since I need to redirect to other possible pages.
You could put your model object in the TempData collection on submit, redirect, then read it back out again. For example:
[HttpPost]
public ActionResult FirstForm(FirstFormModel model) {
TempData["TempModelStorage"] = model;
return RedirectToAction("SecondForm");
}
public ActionResult SecondForm() {
var firstModel = TempData["TempModelStorage"] as FirstFormModel;
// check for null, use as appropriate, etc.
return View(...);
}
More details here: http://msdn.microsoft.com/en-us/library/dd394711(v=vs.100).aspx
You may save the data asynchronously using jQuery ajax on those button click events.
Assuming your View is something like this
#using(Html.BeginForm("Save","Items"))
{
<div>
Name : #Html.TextBoxFor(s=>s.Name)
<input type="button" class="navigBtns" value="Prev" />
<input type="button" class="navigBtns" value="Next" />
</div>
}
And your script is
$(function(){
$(document).on("click",".navigBtns",function() {
e.preventDefault();
var _this=$(this);
$.post(_this.closest("form").attr("action"), _this.closest("form").serialize(),
function(res){
//check res variable value and do something as needed
// (may be redirect to another page /show/hide some widgets)
});
});
});
Assuming you have an action method called Save in your controller to handle the saving part.
Was given a neat article about this.
MVC Wizard Example
Basically this, you literally pass the name of the html button.
In the view form
<input type="submit" name="btnPrev" />
<input type="submit" name="btnNext" />
In the Controller
Controller
public ActionResult DoStuff(ModelClass mc,string btnPrev,string btnNext)
{
string actionString = "previousPage";
if(btnNext != null)
actionString = "nextPage";
return RedirectToAction(actionString,"Controller")
}

How to change the way the Url is formatted on a submit

I have a search box in a Razor template:
#{
using (Html.BeginForm("Detail", "Book", FormMethod.Get))
{
#Html.TextBox("Id")
<input type="submit" value="Search" />
}
}
When I submit a search it goes to a url like:
~/Book/Detail?Id=1234
However I want it to format the url like so, just because I think it looks cleaner:
~/Book/Detail/1234
Which works perfectly fine because the controller method signature looks like this:
// GET: /Book/Detail/id
public ActionResult Detail(string id)
Model with TextBoxFor
I've tried a Html.TextBoxFor:
#model WebApplication.Models.SearchModel
#{
using (Html.BeginForm("Detail", "Book", FormMethod.Get))
{
#Html.TextBoxFor(m => m.Id)
<input type="submit" value="Search" />
}
}
Same result.
I think you want to take a look at the #Html.BeginRouteForm method, like in this question.
You use a GET request. This means that all parameters will appear in the url box.
I can't check now, but I suppose you could use these options:
The IIS url rewrite - http://www.iis.net/downloads/microsoft/url-rewrite
Url rewrite through a web.config - http://www.hanselman.com/blog/RedirectingASPNETLegacyURLsToExtensionlessWithTheIISRewriteModule.aspx
And a batch of stupid methods:
You can change your request to POST and then modificate the Url by the JS - Modify the URL without reloading the page
You can redirect the request
Also, did you try to add a personal routing for the search url?
Try using a model for the form submit and use #Html.TextBoxFor.
The answer was to add a new search action then redirect to the detail. This is nice because I can choose to do more when searching, such as returning a different view if the query has multiple matches.
//
// GET: /Book/Search?query=
public ActionResult Search(string query)
{
return RedirectToAction("Detail", new { id = query });
}
//
// GET: /Book/Detail/id
public ActionResult Detail(string id)
Razor:
#{
using (Html.BeginForm("Search", "Book", FormMethod.Get))
{
#Html.TextBox("query")
<input type="submit" value="Search" />
}
}

Categories

Resources