SSRS get meta data of remote report - asp.net

How can I retrieve the meta data such as Description, Modified/Create Dates etc from a Remote SSRS report. The report itself displays no problems in the ReportViewer control on the aspx page so I can access the report...
there doesn't seem to be any properties for those values in the .ServerReport object...
thanks heaps!

There are a couple of ways, one way is to add a web reference to the web services interface of your reporting server and call the GetReportDefinition method. more information here:
http://msdn.microsoft.com/en-us/library/aa258101(SQL.80).aspx
The code could look like this:
ReportingService reportingService = new ReportingService();
XmlDocument xmlDocument = null;
byte[] reportDefinition = reportingService.GetReportDefinition(ReportName);
using (MemoryStream memoryStream = new MemoryStream(reportDefinition))
{
xmlDocument = new XmlDocument();
xmlDocument.Load(memoryStream);
}
This gets your .rdl file that you can parse using the XML tools. You can also call the tables in the SSRS database via SQL/ADO/Linq to get the information you are after:
Some good examples of T-SQL against the reporting service database:
http://www.purplefrogsystems.com/blog/?p=13
All of the information you are after might not be in a single spot, for example, some might be in the .rdl, and some in the SQL Server database.
{6230289B-5BEE-409e-932A-2F01FA407A92}

Related

Display Word and excel files in web page from database in asp.net c#

I have a database where i have saved documents like pdf, word(docx) and excel. I want to display them on web page on view button click. I am able to display pdf file using the below approach.
string embed = "<object data=\"{0}{1}\" type=\"application/pdf\" width=\"500px\"
height=\"600px\">";
ltEmbed.Text = string.Format(embed, ResolveUrl("~/Handler1.ashx?
id="+id+"&Name="+Name+""), temp);// literal control
in Handler1.ashx i have the below
string constr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "select pdfdoc from repository;
cmd.Connection = con;
con.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
sdr.Read();
bytes = (byte[])sdr["BPM_Doc"];
}
}
con.Close();
}
context.Response.Buffer = true;
context.Response.Charset = "";
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.ContentType = "application/pdf";
context.Response.BinaryWrite(bytes);
context.Response.End();
How can i use the same approach to display word and excel. My word document has images too.
You can not directly view the Word documents and Excel spreadsheets within your ASP.NET web application. You will have to first render the documents in the form (i.e. HTML or image) that can be displayed on your web page. You can have a look at the following article that shows how to create a universal document viewer application in ASP.NET MVC using GroupDocs.Viewer for .NET API.
Document Viewer in ASP.NET Core MVC for 140+ File Formats
Disclosure: I work as a developer evangelist at GroupDocs.
The short answer is you can't - at least not the way your going about it even if you have the Office suite installed on your own machine.
PDF documents are handled by most browsers with their own implementation of Adobe's PDF reader - what I suspect your browser is doing, but Microsoft Office documents use a multitude of mimetypes, ranging from application/ms-word for the older Word files, to application/vnd.openxmlformats-officedocument.wordprocessingml.document for the newer generations of Office, so built-in browser support for even displaying them is either going to be technically unviable, or restricted by license.
Checkout this document viewer to build the reader/viewer into your project directly:
ASP.NET Document Viewer from GroupDocs
Note: This is not free by any means, it's actually quite expensive and I wish anyone luck trying to find one that will be cheap.
Also, don't be content with simply providing your user with the file itself unless you're happy they should have the means to open it.
In my line of work, the end users we deal with don't have Microsoft Office installed on their machines by design (licensing really), so providing information through PDF documents is the only way to go.

How to pass custom sql command to fastreport.net through application using c#?

I start using fastreport.net to generate report in c# since Crystal reports is not compatible with .net4. Its so simple but it is so complicated also.
I try to pass an sql command to my report through my applicate but it doesnt work.Can anyone help me with that ? Here is the Code :
Report rpt = new Report();
rpt.Load("H:\\MyReport.frx");
rpt.SetParameterValue("Parameter", "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Confictionary");
FastReport.Data.TableDataSource data = rpt.GetDataSource("Contact") as FastReport.Data.TableDataSource;
data.SelectCommand = "SELECT * from contact";
rpt.Prepare();
rpt.ShowPrepared();
It throws an exception in line 5 : "Object reference not set to an instance of an object."
Please sb help me.
tnx a lot
I think SQL command should be in report template set, not dynamically, unless this would be used only for the first time for creating report file.
i use this:
FReport.SetParameterValue("SQL_rysys", ConnectionString);
if (FReport.Dictionary.Connections.Count > 0)
{
FReport.Dictionary.Connections[0].ConnectionString = ConnectionString;
FReport.Dictionary.Connections[0].ConnectionStringExpression = "[SQL_rysys]";
FReport.Dictionary.Connections[0].CommandTimeout = 60;
}
This code assigns value for Parameter "SQL_rysys" (SQL_connection in english), i pass SQL connection string. Also if there is any connections in datasource dictionary-i assign connection string to the first one.
So my reports always gets the correct connection string, BUT the SQL query is already included IN REPORT. Cause there is no other way of creating report in designer without using query to get data, and that query is saved in XML report file (frx).
I was asking in fastreport support how to assign query, but their support is AWFUL and noobs works there.

Merging/filling pdf form file with xml data

Let's say I have a pdf form file available at website which is filled by the users and submitted to the server. On the server side (Asp.Net) I would like to merge the data that I receive in xml format with the empty pdf form that was filled and save it.
As I have found there are several possible ways of doing it:
Using pdf form created by adobe acrobat and filling it with itextsharp.
Using pdf form created by adobe acrobat and filling it with FDF Toolkit .net (which seems to be using itextsharp internally)
Usd pdfkt to fill the form.
Use pdf form file created with adobe livecycle and merge the data by using Form Data Integration Service
As I have no experience with this kind of task can you advise which option would be better/easier and give some additional tips?
Thank you in advance.
I would suggest using the 4th approach if possible because it would be cleaner. You would be using solutions specifically tailored for what you are asking to do, but if you don't have the available resources for such a solution I would suggest using the 1st option.
The 1st option is what I have recently dove into. I have found it relatively painless to implement.
Option 1 is possible if the following applies:
You have control of development of PDF forms.
You have control of formating xml data
You have can live with having uncompressed (fastweb=false) PDF files
Example of implementation:
Using Adobe Acrobat to generate a PDF form. Tip: Use Adobe Native Fonts when generating the forms. For each control you add that is not a native font it will import the font used and bloat the file when it is not compressed, and to my knowledge ITextSharp currently does not produce compressed PDFs.
Using ITextSharp Library to combine XML data with the PDF form to generate a populated document. Tip: to manually populate a PDF form from xml you must map xml values to control names in the PDF form and match them by page as shown in the example below.
using (MemoryStream stream = GeneratePDF(m_FormsPath, oXmlData))
{
byte[] bytes = stream.ToArray();
Response.ContentType = "application/pdf";
Response.BinaryWrite(bytes);
Response.End();
}
// <summary>
// This method combines pdf forms with xml data
// </summary>
// <param name="m_FormName">pdf form file path</param>
// <param name="oData">xml dataset</param>
// <returns>memory stream containing the pdf data</returns>
private MemoryStream GeneratePDF(string m_FormName, XmlDocument oData)
{
PdfReader pdfTemplate;
PdfStamper stamper;
PdfReader tempPDF;
Document doc;
MemoryStream msTemp;
PdfWriter pCopy;
MemoryStream msOutput = new MemoryStream();
pdfTemplate = new PdfReader(m_FormName);
doc = new Document();
pCopy = new PdfCopy(doc, msOutput);
pCopy.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, new PdfBoolean(true));
pCopy.AddViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
doc.Open();
for (int i = 1; i < pdfTemplate.NumberOfPages + 1; i++)
{
msTemp = new MemoryStream();
pdfTemplate = new PdfReader(m_FormName);
stamper = new PdfStamper(pdfTemplate, msTemp);
// map xml values to pdf form controls (element name = control name)
foreach (XmlElement oElem in oData.SelectNodes("/form/page" + i + "/*"))
{
stamper.AcroFields.SetField(oElem.Name, oElem.InnerText);
}
stamper.FormFlattening = true;
stamper.Close();
tempPDF = new PdfReader(msTemp.ToArray());
((PdfCopy)pCopy).AddPage(pCopy.GetImportedPage(tempPDF, i));
pCopy.FreeReader(tempPDF);
}
doc.Close();
return msOutput;
}
Save the File or post the file to the response of your ASP.Net page
Since you tagged this 'LiveCycle', I take it you have an installation of Adobe LiveCycle running somewhere (optionally, can install it somewhere).
In that case, I'd go for number 4 (with the modification of using the Adobe LiveCycle Forms ES module). The other three will undoubtedly yield compatibility issues in the long run. With the LiveCycle server (running the Forms module), you'll be able to handle any PDF, whether it's old, new, static, dynamic, compressed, Acrobat-based or LiveCycle-based.
You should be able to set things up, have the form send its data to the LiveCycle server, and use that data to populate the form. The fill can then be stored in the server's database, or routed into the PDF form (or any other form) and streamed back to the client.
Create the form using LiveCycle Designer.
The quick-and-dirty-option would be the following: Set the form to http-post (as for example an xfdf, see Acrobat for more info) to your ASP-server and publish it on the server (make sure your users don't download the form before opening it, otherwise this won't work. The form has to be opened in the web browser). Then simply capture the submissions as you would capture a http-post from a web page. Optionally, save the fill to a database. Then send the captured xfdf stream fill back to the client (could also be invoked at a later stage via a http-link). The xfdf stream will contain the URL of the form used to fill it out. The client web browser will ask the Acrobat/Adobe reader plug to handle the xfdf stream, and the plug will locate, download and populate the form pointed to by the xfdf.
The user should now be able to save the form AND it's fill - no Reader Extension needed!
You can also use iTextSharp to fill xml data into a Reader Extension enabled form. There are two things you need to set correctly:
Set PdfReader.unethicalreading = true to prevent BadPasswordException.
Set append mode in PdfStamper's constructor, otherwise the Adobe Reader Extensions signature becomes broken and Adobe Reader will display following message: "This document contained certain rights to enable special features in Adobe Reader. The document has been changed since it was created and these rights are no longer valid. Please contact the author for the original version of this document."
So all you need to do is this:
PdfReader.unethicalreading = true;
using (var pdfReader = new PdfReader("form.pdf"))
{
using (var outputStream = new FileStream("filled.pdf", FileMode.Create, FileAccess.Write))
{
using (var stamper = new iTextSharp.text.pdf.PdfStamper(pdfReader, outputStream, '\0', true))
{
stamper.AcroFields.Xfa.FillXfaForm("data.xml");
}
}
}
See How to fill XFA form using iText?

What's the most simple way to retrieve all data from a table and save it back in .NET 3.5?

I have a number of tables containing some basic (business related) mapping data.
What's the most simple way to load the data from those tables, then save the modified values back. (all data should be replaced in the tables)
An ORM is out of question as I would like to avoid creating domain objects for each table.
The actual editing of the data is not an issue. (it is exported into Excel where the data is edited, then the file is uploaded with the modified data)
The technology is .NET 3.5 (ASP.NET MVC) and SQL Server 2005.
Thanks.
An SSIS package would be pretty efficient for what you are doing.
Since everything is being done outside the application in and Excel spreadsheet anyway, this would be easier than doing something in MVC.
If you really want to make it "end user" friendly, then provide a way for them to upload the file, drop it into a folder somewhere, and make sure you schedule a File Watcher Task in SSIS.
As you use SQL Server 2005, I suggest to return results as XML instead of standard rowsets.
Use FOR XML clause. Than modify this XML and apply to SQL Server back.
Please, see for more details
ADDED:
About excel..hm..use dataConnection (OLEDB provider for excel) to open this xls file and then convert it to XML. XML apply to SQL Server
You can write some simple code like this. http://davidhayden.com/blog/dave/archive/2006/03/08/2877.aspx
// Get data in a DataTable
DataTable table = new DataTable();
string northwindConnectionString = "...Northwind...";
using (SqlConnection connection =
new SqlConnection(northwindConnectionString))
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM Categories";
connection.Open();
using (IDataReader dr = command.ExecuteReader
(CommandBehavior.CloseConnection))
{
table.Load(dr);
}
}
}
// Upload DataTable to a Database Table
string destinationConnectionString = "...";
using (SqlBulkCopy copy =
new SqlBulkCopy(destinationConnectionString))
{
copy.DestinationTableName = "Categories";
copy.WriteToServer(table);
}

What's the best way to display an image from a sql server database in asp.net?

I have a sql server database that returns byte for the image. If I use the tableadapter wizard and set it to my stored procedure and preview data, it pulls back an image. It automatically turns it into an image in the preview data. I don't see it as a string of Ints or anything.
How can I display it on my asp.net webpage with a gridview and objectdatasource?
I have searched and foudn where the imagefield can point to a url on another page that does the byte transformation but I'm not sure it's the best. I found another way that creates a temp file.
Just trying to see the best way to do it.
edit - I am trying not to use a temp file. If I cannot use a gridview a regular image field is ok.
asp.net 2.0, c#.
Thank you for any help.
edit
ended up with:
protected void Page_Load(object sender, EventArgs e)
{
string id = Request["id"];
string connstr = "DSN=myserver";
OdbcConnection conn = new OdbcConnection(connstr);
OdbcCommand cmd = new OdbcCommand("{call mySP (?)}", conn);
cmd.CommandType = CommandType.StoredProcedure;
// Add the input parameter and set its properties.
OdbcParameter parameter = new OdbcParameter();
parameter.ParameterName = "#MyParam";
parameter.OdbcType = OdbcType.VarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = id;
// Add the parameter to the Parameters collection.
cmd.Parameters.Add(parameter);
conn.Open();
OdbcDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
byte[] buffer = (byte[])dr[0];
Response.ContentType = "image/jpg";
Response.BinaryWrite(buffer);
Response.Flush();
}
}
and this on the calling page:
<asp:Image ID="Image1" ImageAlign="Middle" ImageUrl="show.aspx?id=123" Runat="server" />
Two options:
Create a temp file - The problem with this approach is that you have to create the file, which means your web must have write access to a directory which is not a great thing. You also need to have a way to clean up the images.
Serve it from another URL - This is my preferred method, as you have no disk access required. A simple http handler (ashx) is a great method to serve up the image.
Edit
If you need session state in the ashx, check out: Asp.net System.Web.HttpContext.Current.Session null in global.asax.
Edit
Couple more thoughts. There are some cases where using a temp file might be better. For example if your images are requested frequently by a lot of users. Then storing the images on the disk would make sense, since you could write the file once, this does increase the maintance complexity but depending on traffic it might be worth it since this would let you avoid calling back into the .net stack and leverage IIS caching of static content.
I wrote the SqlReader plugin for open-source ImageResizing.Net library to allow you to serve and display images from a SQL database in the most performance-optimal way.
Even if you don't need to do any image processing whatsoever, it's still (a) the easiest, and (b) the most efficient way to do it. You can combine it with disk caching (which provides automatic cleanup) to get the best performance that is possible.
Installation is easy - 2 nuget commands, or copy & paste into Web.Config, your pick.
If you need help, support is free and fast.
The sample code you added is good but you should move it to a .ashx file which is meant for such things.
Here is some example code on how to do this.

Resources