JsReport .NET Core - Generate PDF from url - pdf

Trying to use JsReport to generate a pdf from a url but can't find any documentation or examples in their github repo.
Basically I need to generate the pdf and attach it to an email and I've managed to get data back as a byte[], but I can't seem to figure out how to use an existing View/Action.
This is the action that generates the PDF for viewing...
[MiddlewareFilter(typeof(JsReportPipeline))]
public async Task<IActionResult> Pdf(Guid id)
{
var serviceOrder = await _serviceOrderService.Get(id);
if (serviceOrder == null) return new NotFoundResult();
var model = _mapper.Map<ServiceOrderModel>(serviceOrder);
HttpContext.JsReportFeature().Recipe(Recipe.PhantomPdf);
return View(model);
}
This action should take the pdf view from "Details" and generate a PDF that I can attach. Below I can generate it with static content like "Hello from pdf" but I can't figure out how to use my "Details" view in ASPNET Core.
public async Task<IActionResult> Email(Guid id)
{
var rs = new LocalReporting().UseBinary(JsReportBinary.GetBinary()).AsUtility().Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.PhantomPdf,
Engine = Engine.None,
Content = "Hello from pdf",
}
});
var memoryStream = new MemoryStream();
await report.Content.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream, "application/pdf") { FileDownloadName = "out.pdf" };
}

Taken From the JsReport Github Dotnet Example,
[MiddlewareFilter(typeof(JsReportPipeline))]
public IActionResult InvoiceDownload()
{
HttpContext.JsReportFeature().Recipe(Recipe.ChromePdf)
.OnAfterRender((r) => HttpContext.Response.Headers["Content-Disposition"] = "attachment; filename=\"myReport.pdf\"");
return View("Invoice", InvoiceModel.Example());
}
If you want to return a file from Asp.net Core Controller Action method then try the following
[MiddlewareFilter(typeof(JsReportPipeline))]
public async Task<IActionResult> Pdf(Guid id)
{
var serviceOrder = await _serviceOrderService.Get(id);
if (serviceOrder == null) return new NotFoundResult();
var model = _mapper.Map<ServiceOrderModel>(serviceOrder);
HttpContext.JsReportFeature().Recipe(Recipe.PhantomPdf).OnAfterRender((r) =>
HttpContext.Response.Headers["Content-Disposition"] = "attachment; filename=\"out.pdf\"");
return View(model);
}

Related

Net core api to upload 1GB size csv file

I have following code segment it works for small file. But if the file is larger then application is loading for long and recieves No 'Access-Control-Allow-Origin' header is present on the requested resource.
[HttpPost]
[ScopeAuthorize(Constants.ClaimScopeSGCanManageAll, Constants.ClaimScopeUserCanManage)]
[DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = int.MaxValue, ValueLengthLimit = int.MaxValue)]
public async Task<IActionResult> UploadFile()
{
if (!Request.Form.Files.Any())
{
throw new Common.Exceptions.ValidationException("Empty file");
}
IFormFile formFile = Request.Form.Files[0];
var csvDatas = new List<PatientsCSVItem>();
using (var reader = new StreamReader(formFile.OpenReadStream()))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
//process csv rows
}
}
PatientCsvLog executionLog = _patientCsvManager.AddOrUpdatePatientsByCsvData(csvDatas, _userManager.GetLoggedUserId(User));
if (executionLog == null)
{
throw new ArgumentNullException(nameof(executionLog));
}
var response = new
{
NumberRecordImported = executionLog.NumberRecordImported,
NumberRecordUpdated = executionLog.NumberRecordUpdated,
NumberRecordDiscarded = executionLog.NumberRecordDiscarded,
DiscardedRecordList = executionLog.DiscardedRecordList
};
return Ok(response);
}

without view model file upload is possible or not in database by using asp .net core?

How I will upload a file in the database without using ViewModel in asp .net core? Is it possible or not? ***
Advance thanks
public async Task<IActionResult> Create([Bind("Id,CategoriesId,Product_Name,Image_path,Add_Date,Price,Quantity,Description")]Product product, IFormFile file)
{
if (ModelState.IsValid)
{
if (file == null || file.Length == 0)
{
return RedirectToAction(nameof(Create));
}
else
{
string filename = System.Guid.NewGuid().ToString() + ".jpg";
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot", "Images", filename);
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
byte[] filenamee = Encoding.ASCII.GetBytes(filename);
p.Image_path = filenamee;
}
_context.Products.Add(p);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CategoriesId"] = new SelectList(_context.Category, "Id", "Category_Name", product.CategoriesId);
return View(product);
}

Error reading JToken from JsonReader in ASP.NET CORE 3.1 WebApi

I'm using Cloudinary to upload the images in my ASP.NET CORE 3.1 application and when I call _cloudinary.Upload(uploadParams), it throws an exception as following:
System.Exception: Failed to deserialize response with status code: Redirect --->
Newtonsoft.Json.JsonReaderException: Error reading JToken from JsonReader. Path '', line 0, position 0.
at Newtonsoft.Json.Linq.JToken.ReadFrom(JsonReader reader, JsonLoadSettings settings)
at Newtonsoft.Json.Linq.JToken
.Parse(String json, JsonLoadSettings settings) at Newtonsoft.Json.Linq.JToken.Parse(String json)
at CloudinaryDotNet.ApiShared.CreateResultFromString[T](String s, HttpStatusCode statusCode)
--- End of inner exception stack trace
Following is the code of my controller:
[HttpPost]
public async Task<IActionResult> AddPhotoForUser(int userId, [FromForm]PhotoForCreationDto photoForCreationDto)
{
if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
{
return Unauthorized();
}
var userFromRepo = await _repo.GetUser(userId);
var file = photoForCreationDto.File;
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using(var stream = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(file.Name, stream),
Transformation = new Transformation().Width(500).Height(500).Crop("fill").Gravity("face")
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
photoForCreationDto.Url = uploadResult.Uri.ToString();
photoForCreationDto.PublicId = uploadResult.PublicId;
var photo = _mapper.Map<Photo>(photoForCreationDto);
if (!userFromRepo.Photos.Any(u => u.IsMain))
{
photo.IsMain = true;
}
userFromRepo.Photos.Add(photo);
if (await _repo.SaveAll())
{
var photoToReturn = _mapper.Map<PhotoForReturnDto>(photo);
return CreatedAtRoute("GetPhoto", new { userId = userId, id = photo.Id }, photoToReturn);
}
return BadRequest("Could not add the photo");
}
I have similar issue, but the error is Foribidden, only happens when i run the app from the cli, in the debugger everything goes fine.
https://github.com/cloudinary/CloudinaryDotNet/issues/223

Need a web API action method to implement removeUrl of kendo angular upload component

I need a full working example for implementing the remove functionality in telerik kendo angular with Angular 8 and a backend web API in ASP.net core 2.2
In kendo Angular I'm trying to implement the functionality of upload files and removing it when user clicks the x small buttons
I've already implemented the upload so perfectly but when providing the removeUrl it gives error 404 or 415
The other strange thing is when I provide the same url for the upload and download it binds and code could go well but i need a separate action for the remove functionality
[HttpPost("upload"), DisableRequestSizeLimit]
public async Task<IActionResult> Post(IFormFileCollection files)
{
long size = files.Sum(f => f.Length);
//var reqFiles = Request.Form.Files;
var uploads = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
if (!Directory.Exists(uploads))
{
Directory.CreateDirectory(uploads);
}
List<string> paths = new List<string>();
foreach (var file in files)
{
if (file.Length > 0)
{
string fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
var filePath = Path.Combine(uploads, fileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
paths.Add(filePath);
}
}
// process uploaded files
// Don't rely on or trust the FileName property without validation.
return Ok(new { count = files.Count, size, paths });
}
and for delete
[HttpPost]
private IActionResult Delete(IList<string> files)
{
// var reqFiles = Request.Form.Files;
var uploads = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
foreach (var item in files)
{
var filePath = Path.Combine(uploads, item);
System.IO.File.Delete(filePath);
}
return Ok(new { files });
}
Error 404 is raised when trying to name the action in web api and provide this name in the url (although the same thing is working when uploadling) and 415 is being raised when using post request without naming the action in the back end

How to implement the await keyword?

I have written a code to get the projects from the TFS 2013 server using the tfs web api. As the methord is taking too long to execute i.e like 1.5 minutes, so i wanted to make this methord as async. So i added the async and task in the return type. When i see in visual studio is shows a message that the methord does not have await keyword. where should i add the await keyword. I am very new to async programming.
public override async Task<List<Project>> GetProjects()
{
List<Project> retunResult = new List<Project>();
using (var http = new HttpClient(GetHttpHandler()))
{
var response = http.GetAsync(_baseUrl + "_apis/projectCollections?" + tfsWebApiVersionSring).Result;
if (response.IsSuccessStatusCode)
{
response.EnsureSuccessStatusCode();
TFS2013TeamProjectCollection.Rootobject obj = JsonConvert.DeserializeObject<TFS2013TeamProjectCollection.Rootobject>(response.Content.ReadAsStringAsync().Result);
if (obj != null)
{
foreach (TFS2013TeamProjectCollection.Value projColl in obj.value)
{
if (projColl.state == "Started")
{
var responseProj = http.GetAsync(_baseUrl + projColl.name + "/_apis/projects?" + tfsWebApiVersionSring).Result;
if (responseProj.IsSuccessStatusCode)
{
responseProj.EnsureSuccessStatusCode();
TFS2013TeamProject.Rootobject obj1 = JsonConvert.DeserializeObject<TFS2013TeamProject.Rootobject>(responseProj.Content.ReadAsStringAsync().Result);
if (obj1 != null)
{
Project p;
foreach (TFS2013TeamProject.Value TeamProj in obj1.value)
{
p = new Project();
p.collectionName = TeamProj.collection.name;
p.description = TeamProj.description;
p.id = TeamProj.id;
p.name = TeamProj.name;
p.collectionName = TeamProj.collection.name;
p.url = TeamProj.url;
retunResult.Add(p);
}
}
}
}
}
return retunResult;
}
}
}
return null;
}
You could refer to this code snippet about using TFS REST API to get something in async way.
public static async void RESTAPIMethod()
{
HttpClientHandler authtHandler = new HttpClientHandler()
{
Credentials = CredentialCache.DefaultNetworkCredentials
};
using (HttpClient client = new HttpClient(authtHandler))
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
using (HttpResponseMessage response = client.GetAsync(
"Put the REST API URL here").Result)
{
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
}
}
}
Another method about using TFS REST API:
You could also install this Nuget package for your project. Then using these assemblies in this package to run a REST API with C#. This is different with the method above, it's much more convenient. Here is an example about get a build information using Microsoft.TeamFoundation.Build.WebApi assembly in Async method.
Example:
What object returns from TFS2015 RestAPI
You shouldn't use Result at all. Every place in your code where you have:
var resp = http.GetAsync(url).Result;
you should have:
var resp = await http.GetAsync(url);