I have a Web Api Application that performs a file upload to Amazon S3 when I POST a file path to it. How do I change the root directory this file path is relative to? Right now, if I send myVideo.flv as the file path, my app tries to find the file to upload at c:\windows\system32\inetsrv\myVideo.flv. I'd like it to look for the file at c:\MyApp\files\myVideo.flv. Is this something I change in the app config or iis?
Here is my controller method:
[HttpPost]
public HttpResponseMessage move([FromBody] Models.Request request)
{
string videopath = request.videopath;
try
{
PutObjectRequest putVideo = new PutObjectRequest
{
BucketName = WebApiConfig.AWSVideoBucket,
Key = videopath,
FilePath = videopath,
ContentType = "video/flv"
};
PutObjectResponse videoResponse = WebApiConfig.AWSclient.PutObject(putVideo);
if (videoResponse.HttpStatusCode == HttpStatusCode.OK)
{
return Request.CreateResponse(HttpStatusCode.OK);
}
}
catch (FileNotFoundException e)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "File not found: " + e.Message);
}
}
Open IIS, Expand Sites and find your web site, Right click on the web site and select "Add Virtual Directory". This directory can be pointed to anywhere on the machine. In your app, you would read/write to this virtual directory under the root of the application. Also be mindful of permissions, to make sure the users accessing the site have proper permissions to that virtual directory.
Related
I'm trying to upload files with WebClient on network disc.
Everything is fine until I publish my app.
Code to upload:
public IFormFile Image{ get; set; }
(...)
imagename = FileHelper.GenerateFilename(Image.FileName);
var imgsave = Path.Combine(PathHelper.NewsFilePath, imagename);
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
try
{
client.UploadFile(imgsave, Image.FileName);
}
catch (Exception e)
{
}
When I run application locally, it's working perfect, but when I publish my app, I get an error:
Error message: System.IO.FileNotFoundException: Could not find file 'C:\inetpub\wwwroot\application\test.PNG'.
File name: 'C:\inetpub\wwwroot\application\test.PNG' at (...)
Seems that published app is looking for this file somewhere within app folder. How can I indicate this file to upload it correctly?
I am trying to download files from azure to computer via an web app. It works when I run locally the project, but when uploaded to ftp server it does not download.
I have tried Environment.SpecialFolder.Peronal, Desktop, etc.
public async Task<bool> DownloadBlobAsync(string file, string fileExtension, string directory)
{
string downlaodPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
_container = _client.GetContainerReference(containerName);
_directoy = _container.GetDirectoryReference(directory);
CloudBlockBlob blockBlob = _directoy.GetBlockBlobReference(file + "." + fileExtension);
using (var fileStream = File.OpenWrite(downlaodPath + "/"+ file + "." + fileExtension))
{
await blockBlob.DownloadToStreamAsync(fileStream);
return true;
}
}
The expected output should be on the documents or desktop.
The issue that you are seeing is due to the fact that your code is executing on the webserver, not on the clients (users) machine.
In other words, when you try to save to Environment.SpecialFolder.Personal, you're trying to save it to that folder on the web server, not the users desktop computer.
What you need to do is return the content of the blob in the request, and let the browser save the file - the user is likely to be prompted (depending on their browser settings) where exactly to save it. You should not be specifying this.
Here is an example of how to do this:
public async Task<HttpResponseMessage> DownloadBlobAsync(string file, string fileExtension, string directory)
{
_container = _client.GetContainerReference(containerName);
_directoy = _container.GetDirectoryReference(directory);
CloudBlockBlob blockBlob = _directoy.GetBlockBlobReference(file + "." + fileExtension);
using (var ms = new MemoryStream())
{
await blockBlob.DownloadToStreamAsync(ms);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(ms.ToArray())
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "somefilename.ext"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue(blockBlob.Properties.ContentType);
return result;
}
}
Note that this is inefficient, as it will download the blob first to the webserver, and then return that to the client. It should be enough to get started.
When this endpoint is hit by the browser, the user will be prompted to save the file somewhere on their PC.
We're developing mobile application in Xamarin. How can next be accomplished in iOS:
user downloads file from url (http request is made to REST API, secured with Authentication Basic username:secretKey)
file is saved to iOS
user opens a file (allowed are jpg, png, pdf, doc, docx, png)
file is opened in default application (e.g. for images image viewer)
As file operations are platform specific, here's interface definition:
public interface IFileHelper
{
void DownloadFileAndSave(Models.DocumentModel document);
}
Android implementation:
public class FileHelper : IFileHelper
{
// download file and view status in download manager
public void DownloadFileAndSave(Models.DocumentModel document)
{
DownloadManager dm = (DownloadManager)Android.App.Application.Context.GetSystemService(Context.DownloadService);
string url = WebApiUtils.GetBaseUrl() + string.Format("Api/v1/Dms/{0}", document.UniqueId);
DownloadManager.Request request = new Android.App.DownloadManager.Request(Android.Net.Uri.Parse(url)));
request.AddRequestHeader("Authorization", "Basic " + WebApiUtils.GetEncodedCredentials(Auth.Users.Current));
var downloadFile = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
string path = Path.Combine(downloadFile.AbsolutePath, document.FileName);
request.SetDestinationUri(Android.Net.Uri.FromFile(new Java.IO.File(path)));
request.SetMimeType(document.ContentType);
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
dm.Enqueue(request);
}
In Android file is simply stored on the filesystem and with File Explorer which is by default installed on any Android (i.e. My Files -> device storage -> Download), the file is opened in default application for file's mime type. Everything fine on Android.
Apple iOS implementation:
public class FileHelper : IFileHelper
{
public void DownloadFileAndSave(Models.DocumentModel document)
{
WebClient webClient = new WebClient();
webClient.Headers.Add(HttpRequestHeader.Authorization, "Basic " + WebApiUtils.GetEncodedCredentials(Auth.Users.Current));
webClient.DownloadDataAsync(new System.Uri(WebApiUtils.GetBaseUrl() + string.Format(Consts.ApiUrls.GetDocument, document.UniqueId)));
webClient.DownloadDataCompleted += (sender, e) =>
{
byte[] content = e.Result;
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), document.FileName);
// doesn't throw exception therefore saved ok
File.WriteAllBytes(path, content);
Uri uri = new Uri(String.Format("file://{0}", path));
// doesn't work.
Device.OpenUri(uri);
};
}
}
Is there any other way to open downloaded file in default application. If I open url e.g. http://example.com/files/file1.png it opens the file in safari, but I can't put Authorization: Basic headers in Device.OpenUri.
I read about Load Non-Web Documents with WebView but you would have to build each file as BundleResource.
As Code Warrior commented there is one approach posted on link: https://forums.xamarin.com/discussion/36964/why-is-it-that-nothing-is-working-to-open-an-existing-local-pdf-file-in-the-ios-portion-of-my-pcl.
But Save image action doesn't work, everything else seems to work.
public void DownloadFileAndSave(Models.DocumentModel document)
{
WebClient webClient = new WebClient();
webClient.Headers.Add(HttpRequestHeader.Authorization, "Basic " + WebApiUtils.GetEncodedCredentials(Auth.Users.Current));
string tempPath = Path.GetTempPath();
string localFilename = Path.GetFileName(document.FileName);
string localPath = Path.Combine(tempPath, localFilename);
webClient.DownloadFileCompleted += (sender, e) =>
{
Device.BeginInvokeOnMainThread(() =>
{
QLPreviewItemFileSystem prevItem = new QLPreviewItemFileSystem(localFilename, localPath); // ql = quick look
QLPreviewController previewController = new QLPreviewController()
{
DataSource = new PreviewControllerDS(prevItem)
};
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(previewController, true, null);
});
};
// download file
Uri uri = new System.Uri(WebApiUtils.GetBaseUrl() + string.Format(Consts.ApiUrls.GetDocument, document.UniqueId));
webClient.DownloadFileAsync(uri, localPath);
}
When Save image is triggered I get next error:
2017-10-03 13:45:56.797 MyApp.iOS[477:61030] Video
/private/var/mobile/Containers/Data/Application/33D7139A-53E0-4A2E-8C78-D3D13A2259B0/tmp/water-h2o-md.png
cannot be saved to the saved photos album: Error
Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open"
UserInfo={NSUnderlyingError=0x1c0445d60 {Error
Domain=NSOSStatusErrorDomain Code=-12847 "(null)"},
NSLocalizedFailureReason=This media format is not supported.,
NSURL=file:///private/var/mobile/Containers/Data/Application/33D7139A-53E0-4A2E-8C78-D3D13A2259B0/tmp/water-h2o-md.png,
NSLocalizedDescription=Cannot Open}
iOS treates image as video? Is this a bug on iOS or am I something missing.
UPDATE
It turns out that next permissions was missing in Info.plist file:
<key>NSPhotoLibraryUsageDescription</key>
<string>Application needs to access photos</string>
<!-- for iOS 11 -->
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Application needs to access photos</string>
Now Save Image action is working ok. But seriously Apple could return more appropriate error than Video image.jpg cannot be saved ...
I have PDF file placed on different (FILE-Server) server machine, and the IIS machine on which my MVC application is hosted have rights to that File-Server. From IIS machine i can access the file through following URI:
file://file-server/data-folder/pdf/19450205.pdf
I want to enable my MVC app's users to download their respective files by clicking on download link or button. So probably i would have to write some Action for that link/button.
I tried to use File return type for my Action method in following way:
public ActionResult FileDownload()
{
string filePth = #"file://file-server/data-folder/pdf/19450205.pdf";
return File(filePth , "application/pdf");
}
but the above code gives exception of URI not supported.
I also tried to use FileStream to read bytes inside array return that bytes towards download, but FileStream also gives error of not proper "Virtual Path" as the file is not placed inside virtual path, its on separate server.
public ActionResult Download()
{
var document = = #"file://file-server/data-folder/pdf/19450205.pdf";
var cd = new System.Net.Mime.ContentDisposition
{
// for example foo.bak
FileName = document.FileName,
// always prompt the user for downloading, set to true if you want
// the browser to try to show the file inline
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(document.Data, document.ContentType);
}
Thanks for the replies, but both suggestion did not work.
as file needs to be accessed over URI, using FileInfo gives error: URI formats are not supported.
I managed to get this done through following mechanism:
public ActionResult FaxFileDownload()
{
string filePth = #"file://file-server/data-folder/pdf/19450205.pdf";
WebClient wc = new WebClient();
Stream s = wc.OpenRead(filePth);
return File(s, "application/pdf");
}
Thanks to All.
I want to upload an uploaded file to both where my mvc 4.0 application runs and to another server that is powered by linux based server. I want to upload file to directory under tomcat server(ex: KGS/assets/). I can upload file to local server by the following code
public ActionResult Upload(string qqfile, int id)
{
//resim ekliyor
const string path = #"C:\Temp\";
const string kgsPath =#"\\";
try
{
var stream = Request.InputStream;
string file;
if (String.IsNullOrEmpty(Request["qqfile"]))
{
// IE
HttpPostedFileBase postedFile = Request.Files[0];
stream = postedFile.InputStream;
file = Path.Combine(path, System.IO.Path.GetFileName(Request.Files[0].FileName));
}
else
{
//Webkit, Mozilla
file = Path.Combine(path, qqfile);
}
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
System.IO.File.WriteAllBytes(file, buffer);
}
catch (Exception ex)
{
return Json(new { success = false, message = ex.Message }, "application/json");
}
return Json(new { success = true }, "text/html");
}
Are there anyways or approaches to achieve this or is this impossible to be done?
You must expose some way of storing the file on the Linux server that your ASP.NET application can use. This could be a Samba or NFS share, an FTP account, a web service, etc. The storage mechanism you choose will dictate how you store the file there.
Another option would be to use something like rsync to keep files in both places synchronized. Your .NET application would be unaware of this, so no coding required.