How can I export data in pdf using MVC? - asp.net-mvc

This is My Index method by which I am getting the list of data in webgird.How can I write a method for exporting this list of data when I click on button?
public ActionResult Index(string eMailId)
{
var refEntry = _moneyReport.GetAll().Where(a => a.EmailId == eMailId).ToList();
var credittotal = _moneyReport.GetAll().Where(a => a.EmailId == eMailId && a.PromoValue < 0).Sum(a => a.PromoValue);
decimal TotalCredit = Convert.ToDecimal(credittotal * -1);
var debittotal = _moneyReport.GetAll().Where(a => a.EmailId == eMailId && a.PromoValue >0).Sum(a => a.PromoValue);
decimal TotalDebit = Convert.ToDecimal(debittotal);
ViewBag.TotDebit = TotalDebit;
ViewBag.TotCredit = TotalCredit;
if(TotalCredit>TotalDebit)
{
decimal FinalTotal = TotalCredit - TotalDebit;
ViewBag.Total = FinalTotal;
}
else
{
decimal FinalTotal = TotalDebit - TotalCredit;
ViewBag.Total = FinalTotal;
}
return View(refEntry);
}
This is my View page where I am entering an emailid,load and Export button`enter code here.
#using (Html.BeginForm())
{
<div class="container-fluid form-row">
<div class="col-md-12 no-padding">
<div class="col-md-3 no-padding">
<input type="text" name="eMailId" id="eMailId" />
<span class="highlight"></span>
<span class="bar"></span>
<label class="no-left">Enter Email Id <sup class="star">*</sup></label>
</div>
<div class="col-md-3">
<input type="text" id="gName" name="gName" readonly="readonly" />
<span class="highlight"></span>
<span class="bar"></span>
<label>Name</label>
</div>
<div class="col-md-3">
<input type="submit" id="btnLoad" class="btn btn-md pm-create" value="Load" />
<input type="submit" id="btnLoad" class="btn btn-md" value="Export To PDF" />
</div>
<input type="hidden" id="HdnEmail" value='#TempData["MailID"]' />
</div>
</div>
}
<div id="report-grid">
#{Html.RenderPartial("ImportMoneyReport", Model);}
</div>
ImPortMoneyReport is my partial page where i ve the webgrid.

To export model data to PDF you will have to use one of third party pdf export libraries such as few below. You will find sample examples on respective sites or google them. You will need to implement code to export pdf in and add that file/stream into Response.OutputStream by setting respective content type in ImportMoneyReport action. Also you will have to invoke ImportMoneyReport method on post/event you can not use Html.RenderPartial to export; otherwise you can put export code in Index action only.
PDF Sharp
iTextSharp

It you want something that's working and very easy to use. Take a look at https://github.com/andyhutch77/MvcRazorToPdf
Just read the documentation.
For sample code. Take a look at this.
https://github.com/andyhutch77/MvcRazorToPdf/tree/master/MvcRazorToPdfExample
If you encounter some issues go to their github page and click the Issues tab, maybe some of your questions are already resolved there.
P.S.
Some of the PDF libraries like Rotativa will require an executable program to run that will not work when your app is deployed to Azure because Azure doesn't support exe files (I guess for security purposes) else you'll create a webjob just for the exe file.

Related

how to change html view using binding in angular 6

I have an angular 6 project , I have a component for book like this
<div class="col-md-4 agileinfo_single_left">
<img id="BigBookView" src="public/books/images/{{book.photo}}" alt=" " class="img-responsive">
</div>
<div class="col-md-8 agileinfo_single_right">
<h1>{{book.name | uppercase}}</h1>
<h2>Series: {{book.seriesName}}</h2>
<h3>Author: {{book.author}}</h3>
<h4></h4>
<div class="w3agile_description">
<h4>Summary : {{book.summary}}</h4>
</div>
<div class="snipcart-item block">
<div class="snipcart-thumb agileinfo_single_right_snipcart">
<h4 class="m-sing">Price: {{book.price}}$</h4>
<h4 class="m-sing">Seller: {{book.seller}}</h4>
</div>
<div class="snipcart-details agileinfo_single_right_details">
<form action="#" method="post">
<fieldset>
<input type="submit" name="submit" value="Add to cart" class="button">
</fieldset>
</form>
</div>
</div>
all of this is inside a modal and every time I choose a book and the modal is opened and suppose to show the book data in this html.
This is the component type script
export class BigBookViewComponent implements OnInit {
#Input()
public book:Book = new Book();
constructor() { }
ngOnInit() {
}
public changeBook(newBook: Book) {
console.log(this.book);
this.book = newBook;
}
}
using the function changeBook I send to this component a new book to show but the html and the UI don't chagne, even though I can see in the console.log(this.book); line that the book is indeed being sent.
How can I change the html to show a diffrent book?
You should assign the book on ngOnInit method.
When assigning in the constructor the single instance of the component will keep the original book.

kendo UI asynchronous uplaod on Razor Page returns 404

I am trying to use Kendo UI async upload on Razor Page (No controller) But I get 404 error
Index.cshtml page-
<div class="row">
<div class="">
<form asp-action="" class="" id="" enctype="multipart/form-data">
<div class="form-group">
<label class="">Review Type</label>
<div class="">
<select asp-for="ReviewType" asp-items="#(new SelectList(Model.ReviewTypes, "ReviewTypeLookupId", "ReviewTypeName"))" class="form-control"></select>
</div>
</div>
<div class="form-group">
<label class=""></label>
<div class="">
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("Index?handler=Save", "UploadManagement")
.Remove("Remove", "UploadManagement/Index")
.AutoUpload(true)
)
)
</div>
</div>
<div class="form-group">
<button type="submit" id="submit-all" class="btn btn-default">Upload </button>
</div>
</form>
</div>
Index.cshtml.cs Page
[HttpPost]
public ActionResult OnPostSave(IEnumerable<IFormFile> files)
{
// The Name of the Upload component is "files"
if (files != null)
{
foreach (var file in files)
{
//var fileContent = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
//// Some browsers send file names with full path.
//// We are only interested in the file name.
//var fileName = Path.GetFileName(fileContent.FileName.Trim('"'));
//var physicalPath = Path.Combine(HostingEnvironment.WebRootPath, "App_Data", fileName);
//// The files are not actually saved in this demo
////file.SaveAs(physicalPath);
}
}
// Return an empty string to signify success
return Content("");
}
Error -
Failed to load resource: the server responded with a status of 404 (Not Found)
The easiest way to solve this, is to not use .Save(string action, string controller) or any overload of this, but .SaveUrl(string url):
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.SaveUrl("./Index?handler=Save")
.AutoUpload(true)
))
This will also work, if you are in a non-default area and the url to the page itself is acually /area-url/Index?handler=foo

ASP.NET MVC input validation to allow only two digit numbers on a model property that is string type

The input values can be any two digit numbers of the form 00, 01,...09,10,11,....19,20,...,99 etc. But following is not working. User can still enter abc and no client side validation occurs. Of course the error occurs after the form is posted since SQL Server does not except, for example, abc in a char(2) column. It needs to occur during client side validation as explained here. What I may be missing?
Note: Not using data type as number since it would force 01 to 1, 02 to 2 ,... etc. It has to be of the type 01, 02, ...,etc.
Model Snapshot:
Column[TypeName = "char(2)"]
[RegularExpression(#"^[0-9]{2,2}$", ErrorMessage = "Must be two digits numbers"), StringLength(2)]
public string TestCode { get; set; }
Views\Shared\Components\Default.cshtml
<form asp-controller="TestController" asp-action="TestAction" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
....
....
<div class="form-group">
<label asp-for="TestCode" class="col-md-2 control-label"></label>
<div class="col-md-2">
<input asp-for="TestCode" class="form-control" />
<span asp-validation-for="TestCode" class="text-danger"></span>
</div>
</div>
<button type="submit" name="submit" value="TestVal">Save</button>
</form>
UPDATE
I'm using Visual Studio 2015 with latest update -3 and ASP.NET Core 1.1. The project is created using their default Web App Core template that includes built-in JQuery, JQuery-Validation, bootstrap etc. Following is the snapshot of the html generated in Google Chrome Dev Tool.
Snapshot of Google Chrome Dev Tool:
<label class="col-md-2 control-lable" for="TestCode">TestCode<label>
<div class="col-md-2">
<input class="form-control" type="text" id="TestCode" name="TestCode" value>
<span class="text-danger field-validation-valid" data-valmsg-for="TestCode" data-valmsg-replace="true"></span>
</div>
UPDATE 2:
When user clicks on Tab2 of the Main View (with Bootstrap Tabstrip), an Ajax code (shown below) displays a Partial view in Tab2 content pane that displays a list of various buttons. When user clicks on one of those buttons, same controller (shown below) calls a ViewComponent that displays the view in question (please see this ViewComponent view before UPDATE section above).
Controller:
[HttpGet]
public IActionResult TestAction(string calledFrom, int SelectedOrderYear, int id)
{
....
return ViewComponent("Test_VC", new { id = id });
}
Main View with Bootstrap Tabs:
#model MyProj.Models.TestViewModel
....
....
<ul class="nav nav-tabs">
<li id="menu1ID" class="active"><a data-toggle="tab" href="#menu1">Menu 1</a></li>
<li id="menu2ID"><a data-toggle="tab" href="#menu2">Menu 2</a></li>
</ul>
<div class="tab-content">
<div id="menu1" class="tab-pane fade">
</div>
<div id="menu2" class="tab-pane fade">
</div>
</div>
#section scripts
$('#myTabstripID li').click(function () {
var li_id = $(this).attr("id");
$.ajax({
url: '#Url.Action("TestAction", "TestController")',
data: { calledFrom: li_id },
contentType: 'application/json',
dataType: 'html',
type: 'GET',
cache: false,
success: function (data) {
if (li_id == 'menu1ID')
$('#menu1').html(data);
else if (li_id == 'menu2ID')
$('#menu2').html(data);
}
});
});

Asp.Net MVC - Data permutator

I have searched for hours for this without finding an answer, so I'm asking your help (I'm a beginner in web development (and in Asp.Net MVC)).
I want to create a simple data permutator (for example you enter 3 datas "a, b, and c", and I give you the possible permutations between these 3 datas : "abc; acb; bac; bca; cab; cba").
I have tried the following code, but it does not work (I have an HTTP 404 error).
<form method="post">
<div class="col-md-4 input-group">
<div class="input-group-addon">1</div>
<input type="text" name="firstData" class="form-control" placeholder="First Data" maxlength="50" required />
</div>
<div class="col-md-4 input-group">
<div class="input-group-addon">2</div>
<input type="text" name="secondData" class="form-control" placeholder="Second Data" maxlength="50" required />
</div>
<div class="col-md-4 input-group">
<div class="input-group-addon">3</div>
<input type="text" name="thirdData" class="form-control" placeholder="Third Data" maxlength="50" required />
</div>
<div class="col-md-12 mainAction centerbloc">
<input type="submit" value="Permutate the data" class="btn btn-success register-button-slider" href="">
</div>
</form>
And then below, I want to display the result in the same page, like this :
#{ if (IsPost)
{
string firstdata = Request.Form["firstData"];
string seconddata = Request.Form["secondData"];
string thirddata = Request.Form["thirdData"];
<p>
#firstdata #seconddata #thirddata<br />
#seconddata #firstdata #thirddata<br />
</p>
}
}
I haven't put anything special in my controller (maybe the mistake is here?) :
namespace Blogs.Controllers
{
public class ToolsController : Controller
{
[Route("tools/datapermutator", Name = "DataPermutator"), HttpGet]
public ActionResult DataPermutator()
{
return View();
}
}
}
If you have a way to do it, it would be very helpful, thank you in advance!

Posting Textarea to Controller (currently null is being passed) - MVC

I'm creating a website where the user will fill in a textarea (in response to a question) and then press next. When they press next, the textarea will be submitted to the controller and the next question will be retrieved (I'll also store the answer in a cookie). Unfortunately, when I run the code in debug I've realized that the textarea is not being submitted b/c the parameter is null. I've tried to figure it out and I've looked around and I seem to be doing it properly. Hopefully it's an easy fix. Thanks so much for your time!
Controller:
// POST: /Question/1
[HttpPost]
public ActionResult q(string textAnswer) {
if (textAnswer != null)
ViewBag.current++;
Question q = db.Questions.Find(ViewBag.current);
if (q == null) {
return RedirectToAction("submit");
}
return View(q);
}
View:
<form class="form-horizontal" id="myForm" method="post" enctype="text/plain" name="input">
<p>
<h3>Question <span id="integer">#ViewBag.current</span></h3>
#Html.DisplayFor(model => model.Ques)
</p>
<div class="control-group">
<label class="control-label">Answer</label>
<div class="controls">
<textarea rows="20" style="width:600px" id="textAnswer"></textarea>
</div>
</div>
<div class="control-group">
<div class="controls" >
<button onclick="history.back()" type="button" class="btn">Back</button>
<input type="submit" class="btn" value="Next" />
</div>
</div>
</form>
Your textarea needs a name in order to be posted.
<textarea rows="20" style="width:600px" id="textAnswer" name="textAnswer"></textarea>
Also remove the enctype attribute from your form.
Text areas don't post strings, they post string arrays.
Your controller should have this signature:
public ActionResult q(string[] textAnswer)

Resources