Open secure Sharepoint file programmatically using c# - sharepoint

I need help opening am online Sharepoint file programmatically. These files need to be secured on Sharepoint (so that users can't wander into them), but I also need to access it somehow using my webpart (which will check for security). Normally, you can just use a hyperlink that links to the Sharepoint file, but we don't want people sharing these hyperlinks, so that won't work.
I want the user to click a link, and have them see the "Open, Save, Close" dialog menu for that file.
I have tried this
String fileName = #"file.txt";
String filePath = #"~online filePath/";
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearHeaders();
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
//or whatever file type, I can code that later
response.AddHeader("Content-Disposition", "attachment; Filename=" + fileName + ";");
response.TransmitFile(filePath + fileName);
//response.Flush();
response.End();
Unfortunately, while this works fine for local files (C://...), when I try this on my web fike, I only receive a text document that has the source code for the current page. Not sure why.
As for dealing with the permissions, I plan to use elevated priviledges to have the program gain access to the files.
I would appreciate any help, Thanks.

Here is sample code to provide a file for download with SharePoint
using (SPWeb web = SPContext.Current.Web)
{
//Get fileName and filePath here
response.AddHeader("Content-disposition", "attachment; filename=" + fileName);
response.ContentType = "application/octet-stream";
SPFile file = web.GetFile(filePath);
byte[] fileBytes = file.OpenBinary();
response.OutputStream.Write(fileBytes, 0, fileBytes.Length);
response.End();
}
Does this help or are you having problems locating the fileName and filePath?

Related

SSRS 2017 Export to XLSX shows "We found a problem with some content..." error when rendering through web forms app

We're using SSRS 2017 as our report server with ReportService2010.asmx and ReportExecution2005.asmx as the web references. When I export the report to Excel in the reporting server or project, it exports to .xlsx file and I'm able to open it without any issues but when I export the report to .xlsx (EXCELOPENXML) using a web forms app (C#), it exports the report but shows an alert "We found a problem with some content..." (see image) when opening the file. If I say, "Yes", excel repairs the file and shows the correct data. Error log is also not very helpful.
I don't know what is causing the web forms app to export an corrupted .xlsx file. Any help is appreciated. Thanks.
I had to Flush and Close the HttpResponse request for it to work.
response.OutputStream.Flush();
response.OutputStream.Close();
response.Flush();
response.Close();
This is what worked for me.
private void executeReport(String reportName, ParameterValue[] rptParams, String rptFormat, string strRptFileName, ReportExecutionService service)
{
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
string[] streamIDs = null;
string historyID = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
service.ExecutionHeaderValue = execHeader;
execInfo = service.LoadReport(reportName, historyID);
service.SetExecutionParameters(rptParams, "en-us");
String SessionId = service.ExecutionHeaderValue.ExecutionID;
byte[] result = service.Render(rptFormat, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
Response.ClearContent();
Response.Clear();
if (rptFormat == "EXCELOPENXML")
{
Response.AppendHeader("content-disposition", "attachment; filename=" + strRptFileName + ".xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
Response.BinaryWrite(result);
Response.Flush();
Response.SuppressContent = true;
try
{
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (ThreadAbortException ex)
{
//ignore
}
}

File gets downloaded from app_data folder, but in the corrupted format

My web application stores files (.png, .bmp, .jpg, .jpeg, .jpe, .jfif, .gif, .tif, .tiff, .doc, .docx, .pdf, .xls, .xlsx) in the app_data/upload folder. It gets stored on live server as it is on the local system. But when trying to download, it gets downloaded with the same file size but in the corrupted format.
Here is the code that downloads the file from the live server.
string strURL = "~/App_Data/Upload/" + fileRepository.FileName;
WebClient req = new WebClient();
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Buffer = true;
response.ContentType = "application/octet-stream";
response.AppendHeader("Content-Disposition", "attachment;filename=\"" + fileRepository.FileName + "\"");
byte[] data = req.DownloadData(Server.MapPath(strURL));
response.BinaryWrite(data);
response.TransmitFile(Server.MapPath(strURL));
FileRespository.DownloadCount(Convert.ToString(_fileID));
response.End();
Kindly find an image attached when word file is downloaded.
Please help me out.
Read the file as a blocks/buffers instead of transmit file.

How to open save as dialog box for downloading from cloud

I'm making project which includes downloading files from cloud(Azure) storage. I want to open save as dialog box but not getting it . I used following code.
enter code here // Retrieve reference to a blob named "myblob".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob1");
string FileName = "a3.jpg";
string Filename = FileName.Substring(0, FileName.LastIndexOf("."));``
Response.AppendHeader("Content-Disposition", "attachment; filename=" FileName);
Response.TransmitFile(Server.MapPath("~/blockBlob/myblob1/" + Filename));
Response.End();
/* to download file from cloud
using(var fileStream =System.IO.File.OpenWrite(#"C:\Users\prak\Pictures\ppp.JPG"))
{
blockBlob.DownloadToStream(fileStream);
Response.Write("");
Response.Write("Succefully downloaded!");
}*/
please help...
thanks in advance
You will need to redirect your form to an ashx handler that writes the file content directly into the output stream. This is not specific to Azure, although if the file is being accessed from a blob it may need to be moved temporarily to the web server so you can reference the local path in the "attachment;filename".
Response.Clear();
Response.ContentType = "image/jpeg";
Response.AddHeader( "Content-Disposition", "attachment;filename=\"myfile.jpg\"" );
// write file data to output stream here
Response.End();
Another method is to use HttpWebRequest as described in the following post:
Download/Stream file from URL - asp.net

the file you are trying to open is in a different format than specified by the file extension in Asp.Net

the file you are trying to open is in a different format than specified by the file extension c# error when trying to open file in excel.
Here is my code
public ActionResult Export(string filterBy)
{
MemoryStream output = new MemoryStream();
StreamWriter writer = new StreamWriter(output, Encoding.UTF8);
var data = City.GetAll().Select(o => new
{
CountryName = o.CountryName,
StateName = o.StateName,
o.City.Name,
Title = o.City.STDCode
}).ToList();
var grid = new GridView { DataSource = data };
grid.DataBind();
var htw = new HtmlTextWriter(writer);
grid.RenderControl(htw);
writer.Flush();
output.Position = 0;
return File(output, "application/vnd.ms-excel", "test.xls");
}
when am trying to open excel i get this error
the file you are trying to open is in a different format than
specified by the file extension
After clicking on Yes the file open properly. but i don't want this msg to appear.
I have used CloseXML to solve the problem.
public static void ExportToExcel(IEnumerable<dynamic> data, string sheetName)
{
XLWorkbook wb = new XLWorkbook();
var ws = wb.Worksheets.Add(sheetName);
ws.Cell(2, 1).InsertTable(data);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("content-disposition", String.Format(#"attachment;filename={0}.xlsx",sheetName.Replace(" ","_")));
using (MemoryStream memoryStream = new MemoryStream())
{
wb.SaveAs(memoryStream);
memoryStream.WriteTo(HttpContext.Current.Response.OutputStream);
memoryStream.Close();
}
HttpContext.Current.Response.End();
}
Installed ClosedXML in my project using Nuget Package Manager.
the file you are trying to open is in a different format than
specified by the file extension
You are constantly getting that warning message because the file that got created is not an actual excel file. If you will look into the generated file, it's just a bunch of html tags. Remember that a GridView's RenderControl will generate an html table.
To fix your issue, you need to either use a third party tool that creates a real excel file (one tool you might want to use is NPOI) or create a comma-delimited file, or simply a csv file, and return that file.
In case someone else stumbles across this... I needed to convert blobs back into files on-the-fly in C#. Pdf's worked well and excel gave me this same error as OP explains.
This is the code I wrote which handles excel differently from other file types.
Giving excel application/octet-stream with an actual filename solved my issue. Probably not the cleanest way to do it but it was good enough for my purposes.
string theExt = Path.GetExtension(theDoc.documentFileName).ToUpper();
Response.Clear();
if (theExt == ".XLS" || theExt == ".XLSX"){
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", string.Format("inline; filename={0}", theDoc.documentFileName));
}
else{
Response.ContentType = theDoc.documentMimeType;
Response.AddHeader("Content-Disposition", string.Format("inline; filename={0}", theDoc.documentTitle));
}
using (MemoryStream stream = new MemoryStream(theDoc.file))
{
stream.WriteTo(Response.OutputStream);
stream.Close();
};
Response.End();
In case someone needs to export a dataset as excel file with CloseXML.
Dataset ds = { your data from db }
var xlsx = new XLWorkbook();
var dataTable = ds.Tables[0];
xlsx.Worksheets.Add(dataTable);
xlsx.SaveAs("export.xlsx");

Temporary folder for attachments

What is the best place to put some temporary files that will become attachments later(by means of embedObject)? Are there any temporary folders for xpages that can be obtained and used for this purpose?
Or is there a way to create atachments from stream without use of intermediary files?
You can do something like this with the MIMEEntity. Then you will be able to stream an attachment right into your notesdocument. You will have to get a handle to a notesdocument and an outputstream with the file content. Then you can try to do something like I have done in the code snippet here.
MIMEEntity m = newDoc.createMIMEEntity( fieldNameForFiles );
MIMEHeader header = m.createHeader("content-disposition");
header.setHeaderVal("attachment;filename=\"" + this.getFileName() + "\"");
Stream oStream = session.createStream();
InputStream is = new ByteArrayInputStream( ((ByteArrayOutputStream)outStream).toByteArray() );
oStream.setContents(is);
m.setContentFromBytes(oStream, "application/pdf", MIMEEntity.ENC_IDENTITY_BINARY);
m.decodeContent();
newDoc.save(true, true);

Resources