I have a return File that is offering to download a file but is also downloading the file to another location, I would just like it to offer to download to the user one file, i.e. it reads the initial data from memory, so the first argument in the return File is a MemoryStream of some sort, but I can't figure out how to do it
[HttpPost]
public FilePathResult FileToFasta(F2FModel model)
{
string FullText = new StreamReader(model.File.InputStream).ReadToEnd();
TextLayer layer = new TextLayer(FullText);
string outputFile = layer.WriteToFasta();
String mydatetime = DateTime.Now.ToString("MMddyyyy");
string FileName = String.Format("TextFile{0}.txt", mydatetime);
string FilePath = #"F:\test\" + FileName;
FileInfo info = new FileInfo(FilePath);
if (!info.Exists)
{
using (StreamWriter writer = info.CreateText())
{
writer.Write(outputFile);
}
}
return File(FilePath, "text/plain", FileName);
}
Thanks
MemoryStream can be used with FileStreamResult, for example like this:
[HttpPost]
public FilePathResult FileToFasta(F2FModel model)
{
string FullText = new StreamReader(model.File.InputStream).ReadToEnd();
TextLayer layer = new TextLayer(FullText);
string outputFile = layer.WriteToFasta();
string mydatetime = DateTime.Now.ToString("MMddyyyy");
string FileName = String.Format("TextFile{0}.txt", mydatetime);
//Use different encoding if needed
byte[] outputArray = Encoding.Unicode.GetBytes(outputFile);
MemoryStream outputStream = new MemoryStream(outputArray);
//FileStreamResult will close the stream for you so don't worry
return new FileStreamResult(outputStream, "text/plain") { FileDownloadName = FileName };
}
Related
I want to open a filestream from a sharepoint file (Microsoft.SharePoint.Client.File) but I don't seem to find out how.
I only have access to Microsoft.SharePoint.Client because the Microsoft.SharePoint package can't be installed due to some errors.
This is the code I have so far:
ClientContext ctx = new ClientContext("https://factionxyz0.sharepoint.com/sites/faktion-devs");
ctx.Credentials = CredentialCache.DefaultCredentials;
Microsoft.SharePoint.Client.File temp = ctx.Web.GetFileByServerRelativeUrl(filePath);
FileStream fs = new FileStream(???);
You can only create a System.IO.FileStream if the file exists on a physical disk (or is mapped to a disk via the Operating System).
Workaround: Are you able to access the raw URL of the file? In which case, download the file to disk (if the size is appropriate) and then read from there.
For example:
var httpClient = new HttpClient();
// HTTP GET Request
var response = await httpClient.GetAsync(... SharePoint URL ...);
// Get the Content Stream
var stream = await response.Content.ReadAsSteamAsync();
// Create a temporary file
var tempFile = Path.GetTempFileName();
using (var fs = File.OpenWrite(tempFile))
{
await stream.CopyToAsync(fs);
}
// tempFile now contains your file locally, you can access it like
var fileStream = File.OpenRead(tempFile);
// Make sure you delete the temporary file after using it
File.Delete(tempFile);
FileStream must map to a file. The following code demonstrates how to get a stream via CSOM, then we can convert it to FileStream by using a temp file.
ResourcePath filepath = ResourcePath.FromDecodedUrl(filename);
Microsoft.SharePoint.Client.File temp = context.Web.GetFileByServerRelativePath(filepath);
ClientResult<System.IO.Stream> crstream = temp.OpenBinaryStream();
context.Load(temp);
context.ExecuteQuery();
var tempFile = Path.GetTempFileName();
FileStream fs = System.IO.File.OpenWrite(tempFile);
if (crstream.Value != null){
crstream.Value.CopyTo(fs);
}
As for Azure function temp storage, you may take a reference of following thread:
Azure Functions Temp storage
Or you can store data to Azure storage:
Upload data to blob storage with Azure Functions
Best Regards,
Baker Kong
Been a while since the question was asked, however, this is how I solved this while I was working on a project. Obviously passing in the credentials directly like this isn't the best way, but due to timing constraints I was not able to convert this project into a newer version of .NET and use Azure AD.
Note that the class is implementing an interface.
public void SetServer(string domainName) {
if (string.IsNullOrEmpty(domainName)) throw new Exception("Invalid domain name. Name cannot be null");
_server = domainName.Trim('/').Trim('\\');
}
private string MapPath(string urlPath) {
var url = string.Join("/", _server, urlPath);
return url.Trim('/');
}
public ISharePointDocument GetDocument(string path, string fileName) {
var serverPath = MapPath(path);
var filePath = string.Join("/", serverPath, TemplateLibrary, fileName).Trim('/');
var document = new SharePointDocument();
var data = GetClientStream(path, fileName);
using(var memoryStream = new MemoryStream()) {
if (data == null) return document;
data.CopyTo(memoryStream);
var byteArray = memoryStream.ToArray();
document = new SharePointDocument {
FullPath = filePath,
Bytes = byteArray
};
}
return document;
}
public Stream GetClientStream(string path, string fileName) {
var serverPath = MapPath(path);
var filePath = string.Join("/", serverPath, TemplateLibrary, fileName).Trim('/');
var context = GetClientContext(serverPath);
var web = context.Web;
context.Load(web);
context.ExecuteQuery();
var file = web.GetListItem(filePath).File;
var data = file.OpenBinaryStream();
context.Load(file);
context.ExecuteQuery();
return data.Value;
}
private static ClientContext GetClientContext(string serverPath) {
var context = new ClientContext(serverPath) {
Credentials = new SharePointOnlineCredentials("example#example.com", GetPassword())
};
return context;
}
private static SecureString GetPassword() {
const string password = "XYZ";
var securePassword = new SecureString();
foreach(var c in password.ToCharArray()) securePassword.AppendChar(c);
return securePassword;
}
How can I get a file from external path same as "file://A/B/C/D/"
In local machine I have access to the path of "file://" but the user has not access.
Now I want to read some files from "file://A/B/C/D/" and make downloadable for user.
How can I do it?
(current directory is "https://localhost:44331/")
public async Task<IActionResult> DownloadDocument(string berichtsnummer)
{
var constantPath = "file://A/B/C/D/";
using (FileStream fileStream = System.IO.File.OpenRead(constantPath))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
return File(fileStream, "application/octet-stream");
}
}
when I click to download link, I get this error:
"IOException: The syntax for filename, directory name, or volume label
is incorrect:"
[
A view of path "file://A/B/C/D/":
A local file path is not "file://". You can read the file normally using the local file path as
var path = "C:\\...";
and then send to content to the client browser.
If the file is not on the local machine, the only way is to access it using a network share. You can then use UNC paths, like
var path = #"\\Server\Path\...";
That's important to change the constantPath to "\\\\A\\B\\C\\D\\"
private string[] GetListOfDocumentLink()
{
string path = string.Empty;
string constantPath = "\\\\A\\B\\C\\D\\";
string folderName = string.Empty;
string year = string.Empty;
// determine folderName and year.
path = constantPath
+ Path.DirectorySeparatorChar.ToString()
+ folderName
+ Path.DirectorySeparatorChar.ToString()
+ year;
var filter = Berichtsnummer + "*.pdf";
string[] allFiles = Directory.GetFiles(path, filter);
return allFiles;
}
Now you can send the path to DownloadDocument method:
public async Task<IActionResult> DownloadDocument(string path)
{
byte[] berichtData = null;
FileInfo fileInfo = new FileInfo(path);
long berichtFileLength = fileInfo.Length;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
berichtData = br.ReadBytes((int)berichtFileLength);
return File(berichtData, MimeTypeHelper.GetMimeType("pdf"));
}
so I made an uploader in my web API by using multipart form data but the problem is when I save my pictures from the file stream it also gave me the content here
-----------------------------7e1e364095c
Content-Disposition: form-data; name="file"; filename="C:\Users\kewin\Downloads\windows 10 pro.jpg"
Content-Type: image/jpeg
the binary starts from here
and if i remove thoose 4 lines i can watch my picture so are there any way to remove that so I am only left with the picture
public async Task<IHttpActionResult> UploadImage(string fileName = "")
{
if (fileName == "")
{
fileName = Guid.NewGuid().ToString();
}
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
return BadRequest("Could not find file to upload");
}
var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
var files = provider.Files;
var uploadedFile = files[0];
var extension = ExtractExtension(uploadedFile);
var contentType = uploadedFile.Headers.ContentType.ToString();
var savePath = ConfigurationManager.AppSettings["savePath"];
var file = string.Concat(savePath, fileName, extension);
try
{
var request = HttpContext.Current.Request;
var fileDir = file + request.Headers[""];
using (var fs = new FileStream(fileDir, FileMode.Create))
{
request.InputStream.CopyTo(fs);
}
return Ok();
}
catch (StorageException e)
{
return BadRequest(e.Message);
}
try
{
var fileInfo = new UploadedFileInfo
{
FileName = fileName,
FileExtension = extension,
ContentType = contentType,
FilePath = savePath + imageFile
};
return Ok(fileInfo);
}
Currently you read picture data from request.InputStream, which contains whole unparsed multipart content, including headers you don't need. Instead, you should read picture data from InMemoryMultipartFormDataStreamProvider you created, which parses input stream and provides you simple access to headers and data stream of individual uploaded file(s).
....
var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
var files = provider.Files;
var uploadedFile = files[0];
var extension = ExtractExtension(uploadedFile);
var contentType = uploadedFile.Headers.ContentType.ToString();
var savePath = ConfigurationManager.AppSettings["savePath"];
var file = string.Concat(savePath, fileName, extension);
try
{
using (var fs = new FileStream(file, FileMode.Create))
{
await uploadedFile.CopyToAsync(fs);
}
return Ok();
}
....
I have this code:
public void OpenFile(string fileName)
{
var url = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
using (var fileStream = new FileStream(url, FileMode.Open))
{
byte[] bytes = new byte[fileStream.Length];
int numBytesToRead = (int)fileStream.Length;
int numBytesRead = 0;
fileStream.Read(bytes,numBytesRead, numBytesToRead);
}
}
That code is working fine, but I want to show that file in the browser, I'm executing this method on click in the name of the file, parameters are working great, which is the other code that I need to put to show the file in the browser? Mostly the files are going to be .doc and .pdf. How can I show the documents in the browser??
You can return a FileStreamResult from your action method. Change the method return type from void to ActionResult
public ActionResult OpenFile(string fileName)
{
var pathToTheFile = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
var fileStream = new FileStream(pathToTheFile,
FileMode.Open,
FileAccess.Read
);
return new FileStreamResult(fileStream, MimeMapping.GetMimeMapping(fileName));
}
hey guys, m using an api of "Bits on the Run" following is the code of upload API
public string Upload(string uploadUrl, NameValueCollection args, string filePath)
{
_queryString = args; //no required args
WebClient client = createWebClient();
_queryString["api_format"] = APIFormat ?? "xml"; //xml if not specified - normally set in required args routine
queryStringToArgs();
string callUrl = _apiURL + uploadUrl + "?" + _args;
callUrl = uploadUrl + "?" + _args;
try {
byte[] response = client.UploadFile(callUrl, filePath);
return Encoding.UTF8.GetString(response);
} catch {
return "";
}
}
and below is my code to upload a file, m using FileUpload control to get the full path of a file(but m not succeeded in that)...
botr = new BotR.API.BotRAPI("key", "secret_code");
var response = doc.Descendants("link").FirstOrDefault();
string url = string.Format("{0}://{1}{2}", response.Element("protocol").Value, response.Element("address").Value, response.Element("path").Value);
//here i want fullpath of the file, how can i achieve that here
string filePath = fileUpload.PostedFile.FileName;//"C://Documents and Settings//rkrishna//My Documents//Visual Studio 2008//Projects//BitsOnTheRun//BitsOnTheRun//rough_test.mp4";
col = new NameValueCollection();
FileStream fs = new FileStream(filePath, FileMode.Open);
col["file_size"] = fs.Length.ToString();
col["file_md5"] = BitConverter.ToString(HashAlgorithm.Create("MD5").ComputeHash(fs)).Replace("-", "").ToLower();
col["key"] = response.Element("query").Element("key").Value;
col["token"] = response.Element("query").Element("token").Value;
fs.Dispose();
string uploadResponse = botr.Upload(url, col, filePath);
i read in some forums saying that for some security purpose you can't get fullpath of a file from client side. If it is true then how can i achieve file upload in my scenario ?
Yes, this is true, for security reason you cannot get the fullpath of the client machine, what you can do is, try the following,
Stream stream = fileUpload.PostedFile.InputStream;
stream.Read(bytes, 0, fileUpload.PostedFile.ContentLength);
instead of creating your own FileStream use the stream provided by the FileUploadControl. Hoep it shall help.