Controller Void Method On Button Click Using Ajax. ASP.NET - html

So I have a .ASP MVC Web Application project. I want to run a void method from the controller class when I press a button using AJAX. No variable input or output data needed. I just want to create a pdf file and save it on my local machine.
Right now, nothing at all happens when I click the button. I don't think the ajax script works, 0 connection.
This is my Controller method:
[HttpPost]
public void Test()
{
string dok = System.IO.File.ReadAllText("C:\\Users\\axel\\Desktop\\Repo\\Cert\\employee_regular.html");
var Renderer = new IronPdf.HtmlToPdf();
var HtmlTemplate = dok;
var Pdf = Renderer.RenderHtmlAsPdf(HtmlTemplate);
Pdf.SaveAs("C:\\Users\\axel\\Desktop\\Repo\\Cert\\Arbetsgivarintyg_vanlig_heltid.pdf");
}
This is my Index.cshtml file
#{
ViewBag.Title = "Home Page";
}
<div class="row">
<div class="col-md-12">
<h2>Request employement certificate</h2>
<input type="button" onclick="BtnClick()" value="Click me" />
</div>
</div>
<script>
function BtnClick() {
$ajax({
url: "/Home/Test",
method: "POST",
success: function () {
alert("ok");
},
error: function () {
alert("not ok")
}
})
}
</script>
Really happy for any help

Well there can be several reasons why your code is not working.
First Make sure you are actually able to make a call to a function, Just simply add simple alert message before calling the ajax and see if the alert triggers.
The second thing is to validate url replace the hardcoded url and add url using URL helper.
I would recommend you to make a function as JsonResult Instead of Void, because an exception can happen when creating pdf. [This change is optional but I do recommend it]
So after all the changes your code would look something like this
#{
ViewBag.Title = "Home Page";
}
<div class="row">
<div class="col-md-12">
<h2>Request employement certificate</h2>
<input type="button" onclick="BtnClick()" value="Click me" />
</div>
</div>
<script>
function BtnClick() {
$ajax({
alert("Funciton is working"); // change confirm function is working
url: "#Url.Action("Test","Home")", // change using Url Helper to create valid URL
method: "POST",
success: function (data) {
if (data == true)
{
alert("pdf created sucessfully ok");
}
else
{
alert("exception happend when creating pdf not ok");
}
},
error: function () {
alert("not ok")
}
})
}
</script>
Your Back End would look something like this
[HttpPost]
public JsonResult Test()
{
try {
string dok = System.IO.File.ReadAllText("C:\\Users\\axel\\Desktop\\Repo\\Cert\\employee_regular.html");
var Renderer = new IronPdf.HtmlToPdf();
var HtmlTemplate = dok;
var Pdf = Renderer.RenderHtmlAsPdf(HtmlTemplate);
Pdf.SaveAs("C:\\Users\\axel\\Desktop\\Repo\\Cert\\Arbetsgivarintyg_vanlig_heltid.pdf");
return Json(true, JsonRequestBehavior.AllowGet);
}
catch(Exception ex) {
return Json(false, JsonRequestBehavior.AllowGet);
}
}

Related

click to download Jquery HTML dynamic page to PDF in asp.net core

I have a page that is dynamically populated with AJAX once the page is loaded in asp.net core.
I have to use AJAX because I am populating the page from different sources using id parameter to get value and the page is populated. The HTML pages are working fine and the data are properly displayed.
So I tried using Rotativa base on this tutorial, I was able to get the pdf working but the PDF is empty because the page has not loaded before the PDF is generated.
The idea now is that if I could have a button on the page to convert the page to pdf and users can download.
Is there a way to achieve this?
The idea now is that if I could have a button on the page to convert the page to pdf and users can download.
Is there a way to achieve this?
You can use PDF.Core package to implement it, you can find it in Nuget.
Below is a working demo:
View:
<h1>Test</h1>
<input id="download" type="button" value="download" />
<script src="~/lib/jquery/dist/jquery.js"></script>
<script>
$(function () {
$("#download").on("click", function () {
var markup = document.documentElement.innerHTML;
$.ajax({
type: "post",
url: "/Home/Download",
data: { "htmlContent": markup },
success: function () {
window.location = '#Url.Action("Download", "Home")';
}
})
})
});
</script>
Controller
public IActionResult Download(String htmlContent)
{
if (!string.IsNullOrEmpty(htmlContent))
{
IronPdf.HtmlToPdf Renderer = new IronPdf.HtmlToPdf();
Renderer.RenderHtmlAsPdf(htmlContent).SaveAs("html-string.pdf");
return Ok();
}
else
{
var stream = new FileStream(Path.Combine(_hostingEnvironment.ContentRootPath, "html-string.pdf"), FileMode.Open);
return new FileStreamResult(stream, "application/pdf");
}
}
Our team Chose IronPDF and it worked based on the MVC tutorial posted:
https://ironpdf.com/docs/questions/asp-net-mvc-pdf-binary/
public FileResult GetHTMLPageAsPDF(long id) {
//Create a PDF Document
var PDF = Renderer.RenderHtmlAsPdf("<h1>html as required</h1>");
//return a pdf document from a view
var content = PDF.BinaryData;
Response.AppendHeader("Content-Length", content.Length.ToString());
Response.AppendHeader("Content-Disposition", "inline; filename=Document_" + id + ".pdf");
return File(content, "application/pdf;");
}
I later went for pugpdf because I couldnt afford IronPDF. Its a good package though.
Pugpdf did the job for me
public async Task<IActionResult> Download(String htmlContent)
{
if (!string.IsNullOrEmpty(htmlContent))
{
var renderer = new HtmlToPdf();
renderer.PrintOptions.Title = "Statement";
var pdf = await renderer.RenderHtmlAsPdfAsync(htmlContent);
pdf.SaveAs(Path.Combine(_webHostEnvironment.ContentRootPath, "html-string.pdf"));
return Ok();
}
else
{
var stream = new FileStream(Path.Combine(_webHostEnvironment.ContentRootPath, "html-string.pdf"), FileMode.Open);
return new FileStreamResult(stream, "application/pdf");
}
}

get html 5 date input field and pass to .net controller

On my razor page, I have a simple date picker that looks like this:
<input type="date" name="lessonsStart">
How would I go about getting the value of that and sending it to my controller?
Whenever I send data to my controller from a razor page, the format always looks something like this:
<a asp-action="LessonIndex" asp-route-id="#item.Id">#Html.DisplayFor(modelItem => item.Name)</a>
which sends an "item.Id" to my controller called LessonIndex().
So I'm not sure how I'd get the date value and send it.
The controller looks like this:
public IActionResult LessonIndex(datetime startDate) {
var response = getLessons(startDate);
return response.Results;
}
Is there a specific format I need to use?
Note that the date is not used in a model, it just needs to be sent to a controller.
Thanks!
Assuming this is related to mvc the controller would have a method associated with the post that you would perform to get the data from the form back to the controller. This uses javascript to post data to your LessonIndex() method.
<!--top of your page.-->
#inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
#functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
<input type="date" id="lessonStart" name="lessonStart" />
<input type="Submit" id="PostButton" name="PostButton" Value="Go" />
#section Scripts{ // razor section at the bottom of mvc page 'cshtml'.
<script type="javascript">
$(function(){
$("#PostButton").click(function(){
var url = '#Url.Action("LessonIndex", "Lesson")'; //assuming controller is named Lesson
var date= new Date(this.value).ToDateString();
$.ajax({
url: url,
type: "POST",
data: "lessonStart=" + date,
headers:{
"RequestVerificationToken": '#GetAntiXsrfRequestToken()'
},
success: function(response){
console.log(response);
},
error: function(e){
console.log(e.error);
}
});
});
}
</script>
}
this also assumes that the method looks like this
public class LessonController : Controller{
[HttpPost]
[AutoValidateAntiforgeryToken]
public IActionResult LessonIndex(DateTime lessonStart){
var response = getLessons(lessonStart);
return View(response.results);
}
}
" Note that the date is not used in a model, it just needs to be sent to a controller. "
You could use the ajax to pass the date as QueryString to the method in the controller.
Here is the test example
<input type="date" name="lessonsStart" id="lessonsStart">
#section Scripts
{
<script type="text/javascript">
$("#lessonsStart").change(function () {
var inputDate = new Date(this.value).toDateString();
$.ajax({
type: "post",
url: "/ControllerName/lessonindex?startdate=" + inputDate,
success: function () { }
});
});
</script>
}
The method in controller
[HttpPost]
public IActionResult LessonIndex(DateTime startDate)
{
return Json(startDate);
}
<div class="demo-section k-content">
<h4>Remind me on</h4>
#(Html.Kendo().DateTimePicker()
.Name("datetimepicker")
.Value(DateTime.Now)
.HtmlAttributes(new { style = "width: 100%", title = "datetimepicker" })
.DateInput()
)
</div>

MVC5 controller not getting file from HTML file input

I'm trying to simply allow a user to upload a file.
I have a simple begin form that contains a file element as shown below:
#using (Html.BeginForm("LoadData", "Input", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div style="width:23%; display:inline-block;">
<label>Select Type:</label>
<select name="UploadType">
<option value="First">First</option>
<option value="Second">Second</option>
</select>
</div>
<div style="width:43%; display:inline-block;">
<input type="file" name="files1" id="files1" />
</div>
<div style="width:33%; display:inline-block;">
<input type="submit" value="Upload"/>
</div>
}
The controller is :
[HttpPost]
public ActionResult LoadData(string UploadType, HttpPostedFileBase file1)
{
if(file1 != null && UploadType != null)
{
Console.WriteLine(file1.FileName);
Console.WriteLine(UploadType);
}
}
Everything displays and works on the site but when it posts back the file is null. I've looked at many google results including:
Binding HttpPostedFileBase using Ajax.BeginForm
MVC 4 Razor File Upload
http://www.aurigma.com/upload-suite/developers/aspnet-mvc/how-to-upload-files-in-aspnet-mvc
and more. they all say my stuff is correct. As long as the names match on the file input and the controller param, it should work. But it's not.
I've tried naming it file, files, and now file1 but no mater what I call it, it comes back null.
What am I doing wrong? I even tried checking the Request.Files but that says it has a count of 0.
I ended up using javascript to handle the files instead. Here's the working code:
Javascript (it allows multiple files now):
function SendData() {
var formData = new FormData(document.querySelector('UploadForm'));
for(var i = 0; i < $('#file')[0].files.length; i++)
{
formData.append('files', $('#file')[0].files[i]);
}
formData.append('samplevalue', $('#samplevalue').val());
var url = $('#baseUrl').val() + 'Input/LoadData';
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success: function (data) {
// your logic....
},
error: function(data)
{
// logic....
}
});
}
The controller then accepts
public string LoadData(string samplevalue, HttpPostedFileBase[] files)
{
}
Of course the trick is the javascript. I still don't know why the form doesn't work normally but this works perfectly. :)
Your file input is named files1, but your action param is file1 (no s).
#using (Html.BeginForm("MethodName", "ControllerName", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<input type="file" name="ImgUploader" id="ImgUploader" />
<input type="submit" value="Create" class="btn btn-default" />
}
**Your Controller**`[HttpPost]
public ActionResult Create()
{
HttpPostedFileBase file = Request.Files["ImgUploader"];
}

Send an image to an api controller with angularjs

I have this on my html page
<div class="form-group col-xs-7 col-lg-6">
<label>Background image</label>
<input type="file" name="background_image" id="background_image" ng-model="selectedLayout.background_image" class="form-control" />
<button class="btn btn-primary" ng-click="save(selectedLayout)">Change background image</button>
</div>
This is what I have in controller
$scope.save = function (selectedLayout) {
$http({
method: 'POST',
url: 'api/LayoutSettings/PostImage',
data: selectedLayout.background_image,
headers: {
'Content-Type':'image/jpeg'
}
});
};
And this is my method in the api controller named LayoutSettings
public async Task<HttpResponseMessage> PostImage()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
await Request.Content.ReadAsMultipartAsync(provider);
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
I don't know why when i actual press the change background image I send an empty object. Someone have some idea how i can actual pass the image there? Thanks.
ng-model is not supported by input[file] type, there is a note in the Angular docs about it:
Note: Not every feature offered is available for all input types.
Specifically, data binding and event handling via ng-model is
unsupported for input[file].
Try this instead.

MVC3 Partial View : Not able to see html in View Source for Partial View render using Json object

This is the first time I am working with ASP.NET MVC and I am stuck.
In my code I am doing an Ajax call by using JQuery/json, passing an array of selected options on button click to the controller side and performing some operations there.
Then I return a Partial View which is containing a table so I can see the contents of the Partial View (i.e., Grid) on the page.
Now I want go through the grid but when I try to inspect it I realize that there is no HTML code created in the browser's View Source.
Am I missing any basic thing over here? Can anyone help on this?
Controller - Main action method for View :
public ActionResult AssignCalculationToSC()
{
//Some Oprations performed
return View();
}
Action method called from Ajax to return Partial View :
public ActionResult AddSelectedList(string selectedList, string calculationPurpose)
{
List<AssignCalculationsSourceDataModel> lstAssignCalculationsSourceDataModel = new List<AssignCalculationsSourceDataModel>();
AssignCalculationsSourceDataModel assignCalculationsSourceDataModel = new AssignCalculationsSourceDataModel();
return PartialView("AssignCalculationToSC", lstAssignCalculationsSourceDataModel);
}
JQuery code for Ajax call :
$(function () {
$('#btnAdd').click(function () {
var selectedList = [];
$("#ddlSupplementalCalculationList option:selected").each(function (i, selected) {
var $this = $(this);
selectedList.push({ Id: $this.val(), Value: $this.text() });
});
getCalculationListGrid(selectedList, calculationPurpose);
});
function getCalculationListGrid(selectedList, calculationPurpose) {
$.ajax(
{
url: "AddSelectedList/SupplementalPricing",
type: "POST",
dataType: "html",
traditional: true,
data: { selectedList: JSON.stringify(selectedList), calculationPurpose: calculationPurpose },
success: function (response)
{
$("#dvGrid").html(response);
}
});
}
});
Main View :
#{
ViewBag.Title = "Assign Price Values";
}
#model IList<Bnym.Equinox.Accounting.Web.Portal.Models.Pricing.AssignCalculationsSourceDataModel>
#{Html.RenderPartial("PartialAssignCalculationGrid", Model);}
Partial View :
#model IList<Bnym.Equinox.Accounting.Web.Portal.Models.Pricing.AssignCalculationsSourceDataModel>
#if (Model != null)
{
<div id="dvGrid">
<table id="grid" style="table-layout: fixed;">
</table>
</div>
}
Q1) Now I want go through the grid but when I try to inspect it I realize that there is no HTML code created in the browser's View Source.
The HTML from your partial view will never appear in the page's source because it is not present in the initial HTTP GET. The View Source command in browsers displays the HTML received before any javascript is executed.
Download and install fiddler and inspect the Ajax call in order to see the HTML that is returned from your controller.
Q2 (implicit) Why is the partial view never displayed on screen?
Your main view needs a div#dvgrid and your partial view needs to hosts the grid's content, like this:
Main View :
#{
ViewBag.Title = "Assign Price Values";
}
#model IList<Bnym.Equinox.Accounting.Web.Portal.Models.Pricing.AssignCalculationsSourceDataModel>
<div id="dvGrid">
</div>
Partial View :
#model IList<Bnym.Equinox.Accounting.Web.Portal.Models.Pricing.AssignCalculationsSourceDataModel>
#if (Model != null)
{
<table id="grid" style="table-layout: fixed;">
#foreach(var item in Model){
<tr>
<td>
DATA <!-- render data here -->
</td>
<!-- ... -->
</tr>
}
</table>
}
Edit
You need to decorate your AddSelectedList action with an [HttpPost] attribute in your controller:
[HttpPost]
public ActionResult AddSelectedList(string selectedList, string calculationPurpose)
{
List<AssignCalculationsSourceDataModel> lstAssignCalculationsSourceDataModel = new List<AssignCalculationsSourceDataModel>();
AssignCalculationsSourceDataModel assignCalculationsSourceDataModel = new AssignCalculationsSourceDataModel();
return PartialView("AssignCalculationToSC", lstAssignCalculationsSourceDataModel);
}
And you need to fix your ajax call. Note the JSON.stringify() method has to wrap your whole javascript object.
$.ajax(
{
url: "#Url.Action("GetData")",
type: "POST",
dataType: "json",
traditional: true,
data: JSON.stringify({ selectedList: selectedList, calculationPurpose: calculationPurpose }),
success: function (response)
{
$("#dvGrid").html(response);
}
});