Modify dynamically a rdlc report (c#) - report

I have a font stored in a database, and I have to set all my fileds with that font.
I set bind my report like this :
FormBudgReelReport form = new FormBudgReelReport();
form.Viewer.LocalReport.ReportEmbeddedResource = _NomRessourceRpt;
form.Viewer.LocalReport.DataSources.Add(source);
form.ShowDialog();
If I could load my rdlc as an XmlDocument, I know how to do this, but is there a way to do this?
I can't use a formula like =Parameters!Police.Value because I have a lot of reports to change.

Ok !
I could load my rdlc as a xmlDocument by this code :
Stream st = this.GetType().Assembly.GetManifestResourceStream(_NomRessourceRpt);
// convert stream to string
StreamReader reader = new StreamReader(st);
string reportDef = reader.ReadToEnd();
XmlDocument document = new XmlDocument();
document.LoadXml(reportDef);
Thanks for the help :)

If I could load my rdlc as an XmlDocument, I know how to do this, but is there a way to do this?
In the Solution Explorer you can right-click the .rdlc file and select <Open With...> to choose the editor .
Update:
I am seeking for a way to load my rdlc in a xmlDocument object and then edit xml nodes in runtime.
The following code snippet helps you to load the .rdlc report file from the resources folder to an Xml document:
using System;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Resources;
private void LoadRDLCFromResources()
{
//Declare variables
XmlDocument objXmlDocument = new XmlDocument();
Byte[] byteArray;
Stream objStream = null;
ResourceManager resourceManager = null;
try
{
// Initialize ResourceManager object
resourceManager = new ResourceManager("your_namespace_name.Properties.Resources", GetType().Assembly);
if (resourceManager != null)
{
//Load the resource file "Sample.rdlc" into ByteArray
byteArray = (Byte[])resourceManager.GetObject("Sample");
if (byteArray != null)
{
//Load this bytearray into MemoryStream
objStream = new MemoryStream(byteArray);
if (byteArray.Length > 0)
{
//Load this stream object into XML document and
//thus you get the rdlc file loaded as an XML
//document.
objXmlDocument.Load(objStream);
// Code for using this xml document as per your use
}
}
}
}
//MissingManifestResourceException is an exception thrown when the resource manager fails to initialize appropriately. In such case, please check the namespace name.
catch (MissingManifestResourceException ex)
{
MessageBox.Show("Exception -> " + ex.Message,
"Sample Demo", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Exception -> " + ex.Message,
"Sample Demo", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
// Clear the objects in finally block. This is required for memory management issues.
// If xml document is not required further then clear it in the following manner
if (objXmlDocument != null)
{
objXmlDocument.DocumentElement.RemoveAllAttributes();
objXmlDocument.DocumentElement.RemoveAll();
objXmlDocument.RemoveAll();
}
//Clear the memory stream object
if (objStream != null)
{
objStream.Flush();
objStream.Close();
objStream.Dispose();
}
// Clear resource manager
resourceManager.ReleaseAllResources();
}
}
Source: How to load a rdlc file from resources folder into an XML document dynamically?

Related

Async await to save file causes "Process cannot access file because it is being used by another process" error

I have the following code to save an excel file on the server and then read its content:
if (file.Length > 0)
{
string path = _hostingEnvironment.ContentRootPath + "/CSV-import-students/";
FileStream fs = new FileStream(Path.Combine(path, file.FileName), FileMode.Create);
await file.CopyToAsync(fs);
FileInfo fileUploaded = new FileInfo(Path.Combine(path, file.FileName));
using (ExcelPackage package = new ExcelPackage(fileUploaded))
{
StringBuilder sb = new StringBuilder();
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
int rowCount = worksheet.Dimension.Rows;
int ColCount = worksheet.Dimension.Columns;
bool bHeaderRow = true;
}
The file is saved fine on the server. But, then when I try to access it, I receive "Process cannot access file because it is being used by another process" error. How can I prevent this error? Any ideas?
Almost invariably, when newing up a class that implements IDisposable (such as FileStream), you should do so with a using statement:
using (var fs = new FileStream(Path.Combine(path, file.FileName), FileMode.Create))
{
await file.CopyToAsync(fs);
}
This will automatically dispose of the resource when the using statement goes out of scope, and in the case of FileStream, will flush the write and close the file. That's the source of your issue, so this will solve your problem.
However, you might also need to contend with concurrency. It's possible for two requests to be processed simultaneously that both need to work with the same file. You should plan for concurrency, by catching file access violation exceptions and responding via a retry policy. The Polly exception handling library can help here.

File Upload : ApiController

I have a file being uploaded using http post request using multipart/form-data to my class that is extending from ApiController.
In a dummy project, I am able to use:
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase
to get the file inside my controller method where my Request is of type System.Web.HttpRequestWrapper.
But inside another production app where I have constraints of not adding any libraries/dlls, I don't see anything inside System.Web.HttpRequestWrapper.
My simple requirement is to get the posted file and convert it to a byte array to be able to store that into a database.
Any thoughts?
This code sample is from a ASP.NET Web API project I did sometime ago. It allowed uploading of an image file. I removed parts that were not relevant to your question.
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
try
{
var provider = await Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider());
var firstImage = provider.Contents.FirstOrDefault();
if (firstImage == null || firstImage.Headers.ContentDisposition.FileName == null)
return Request.CreateResponse(HttpStatusCode.BadRequest);
using (var ms = new MemoryStream())
{
await firstImage.CopyToAsync(ms);
var byteArray = ms.ToArray();
}
return Request.CreateResponse(HttpStatusCode.Created);
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
}

Spring MVC to open PDF as the view

Which is the appropriate View class to render existing PDF? AbstractView?
I am fetching PDF via a webservice ,so I'm not looking to subclass AbstractPdfView to render PDF.
I'd like to stay with the Spring controller classes which return a ModelAndView which means writing my own subclass of AbstractView to just write the PDF to a ServletOutputStream. Any other built in support available in Spring MVC?
Thanks
I agree with #Biju Kunjummen's answer but using iText would be also nice to generate the PDF.
here is the code snippet of the controller method.
#RequestMapping(value = "/common/reportgenerator/generatePDF")
public void generatePdf(HttpServletRequest req,HttpServletResponse res)
{
res.setContentType("text/html;charset=UTF-8");
ServletOutputStream outStream=null;
try
{
String calledFrom = req.getHeader("referer");
calledFrom=req.getRequestURL().substring(0,req.getRequestURL().lastIndexOf("/"))+"/ReportGenerator.egp";
calledFrom += "?isPdf=yes&"+req.getQueryString();
System.out.println(calledFrom+"?isPdf=yes&"+req.getQueryString());
InputStream input = new URL(calledFrom).openStream();
StringWriter writer = new StringWriter();
CopyUtils.copy(input, writer);
//System.out.println(writer.toString());
res.setContentType("application/pdf");
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
outStream = res.getOutputStream();
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(calledFrom);
renderer.layout();
renderer.createPDF(outStream);
}
catch (Exception e)
{
new AbcException(e,exceptionHandlerService);
}
finally
{
try
{
outStream.flush();
outStream.close();
}
catch(Exception ex)
{
new AbcException(ex,exceptionHandlerService);
}
}
}
Hope this helps you. Cheers.
I think the best way is to simply stream it out using HttpServletResponse:
OutputStream out = response.getOutputStream();
out.write(..); //buffer and write..
There is no such class.
You have to manually write that file.
Please see answer here:
Display the PDF file stored on the webserver on Browser new window using Spring MVC
I have changed that code to:
// get absolute path of the application
ServletContext context = request.getSession().getServletContext();
String appPath = context.getRealPath("/");
// construct the complete absolute path of the file
String fullPath = appPath + "WEB-INF/pdfs/201507.pdf";
Also, see the answer for not downloading the pdf
and putting the inputStream in the finally block.

Upload a file to S3 bucket's folder using ASP.NET SDK

How do I use AWS SDK for ASP.NET to upload a file to a specific folder? - I was able to upload files by specifying the bucket name (request.WithBucketName), but I want to be able to upload a file to a specific folder within the bucket itself.
This is the code that I use to upload a file to a single bucket:
public bool UploadFileToS3(string uploadAsFileName, Stream ImageStream, S3CannedACL filePermission, S3StorageClass storageType, string toWhichBucketName)
{
try
{
client = Amazon.AWSClientFactory.CreateAmazonS3Client(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY);
PutObjectRequest request = new PutObjectRequest();
request.WithKey(uploadAsFileName);
request.WithInputStream(ImageStream);
request.WithBucketName(toWhichBucketName);
request.CannedACL = filePermission;
request.StorageClass = storageType;
client.PutObject(request);
client.Dispose();
}
catch
{
return false;
}
return true;
}
Hope that this code will help you out.
To add a file to a folder in a bucket, you need to update the Key of the PutObjectRequest to include the folder before the file name.
public bool UploadFileToS3(string uploadAsFileName, Stream ImageStream, S3CannedACL filePermission, S3StorageClass storageType, string toWhichBucketName)
{
try
{
using(client = Amazon.AWSClientFactory.CreateAmazonS3Client(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY))
{
PutObjectRequest request = new PutObjectRequest();
request.WithKey( "folder" + "/" + uploadAsFileName );
request.WithInputStream(ImageStream);
request.WithBucketName(toWhichBucketName);
request.CannedACL = filePermission;
request.StorageClass = storageType;
client.PutObject(request);
}
}
catch
{
return false;
}
return true;
}
This post that talks about uploading files to folder. They are using a TransferUtilityUploadRequest though, but it should work with the PutObjectRequest. Scroll to the bottom for the relevant example.
This post shows how to create a folder without uploading a file to it.
Hope this is helpful
Edit:
Updated the code to use a using block instead of calling Dispose per best practices.
Look Like Following functionlity
1.Create an AmazonS3 object
2.Create a bucket
3.Add a new file to Amazon S3
4.Get a file from Amazon S3
5.Delete a file from Amazon S3
Amazon
super easy way:
using System;
using System.Web;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System.Configuration;
/// <summary>
/// Summary description for AWShandler
/// </summary>
public static class AWSHandler
{
public static void sendFileToS3(string fileName, string storeLocation)
{
try
{
AmazonS3Client client = new AmazonS3Client(RegionEndpoint.EUWest1);
PutObjectRequest request = new PutObjectRequest();
request.BucketName = ConfigurationManager.AppSettings["AWSBucket"].ToString();
request.FilePath = fileName;
request.Key = storeLocation + fileName;
request.ContentType = MimeMapping.GetMimeMapping(fileName);
PutObjectResponse response = client.PutObject(request);
}
catch (Exception ex)
{
// use a logger and handle it
}
}
}
you just need to put your keys in the web/app.config file:
<add key="AWSAccessKey" Value="yourKey" />
<add key="AWSSecretKey" Value="yourSecret" />
These can be obtained from you account page in the AWS console. They must use the names quoted here too, as they are pre-defined by the AWS library.

How to Download A file stored in SQL DB in Binary Format

I am simply storing uploaded file into a binary field in SQL Server but I also need to allow users to download it with Asp.NET. How can I do that ?
Thanks in advance.
Here's a Microsoft Knowledge Base article on this.
How to retrieve the file from your database depends on the data access technology you use; I will just assume that you have some Byte array data containing the file (e.g. by filling a DataSet and accessing the field) and some string filename.
Response.Clear()
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment;filename=""" & filename & """")
Response.BinaryWrite(data)
Response.End()
Put the above code in some download.aspx and link to this file. You probably want to pass some query string information to your download.aspx, so that your code knows which file to get from the database.
Read the data into a filestream object with the appropriate extension tacked on to it, and have the user download the resulting file.
You'll want to use the System.IO BinaryWriter object on the filestream to create the file...something like this:
FileStream fs = new FileStream("thisfile.bin", FileMode.Create);
binWriter= new BinaryWriter(fs);
binWriter.Write(varHoldingSqlRetrievedBinaryData);
Add a Generic Handler (.ashx) page to your web site. The ashx code body below demonstrates how to read an arbitrary stream (in this case a PNG file from disk) and write it out in the response:
using System;
using System.Web;
using System.IO;
namespace ASHXTest
{
public class GetLetter : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Get letter parameter from query string.
string fileName = context.Request.MapPath(string.Format("{0}.png",
context.Request.QueryString["letter"]));
// Load file from disk/database/ether.
FileStream stream = new FileStream(fileName, FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
// Write response headers and content.
context.Response.ContentType = "image/png";
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
If desired, you can also set the Content-Disposition header as demonstrated in Heinzi's answer:
context.Response.AddHeader("Content-Disposition",
"attachment;filename=\"letter.png\"");

Resources