I uploaded an image to server using form fileData:
[Route("upload")]
[HttpPost]
public async Task<HttpResponseMessage> Upload()
{
try
{
if (!Request.Content.IsMimeMultipartContent()) {
Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
var provider = GetMultipartProvider();
var result = await Request.Content.ReadAsMultipartAsync(provider);
//Get Album name from Form
var titleOfAlbum = GetTitleOfAlbum(provider);
//get path to file
var pathToCoverDecoded = result.FileData.First().LocalFileName;
//Encodeing to base 64 path
var bytes = Encoding.UTF8.GetBytes(pathToCoverDecoded);
var base64 = Convert.ToBase64String(bytes);
Album al = new Album();
al.Title = titleOfAlbum;
al.PathToCover = base64;
db.Albums.Add(al);
db.SaveChanges();
return new HttpResponseMessage(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
private string GetDesereleazedFileName(MultipartFileData fileData)
{
var fileName = GetFileName(fileData);
return JsonConvert.DeserializeObject(fileName).ToString();
}
private string GetFileName(MultipartFileData fileData)
{
return fileData.Headers.ContentDisposition.FileName;
}
private MultipartFormDataStreamProvider GetMultipartProvider()
{
var uploadFolder = HttpContext.Current.Server.MapPath("~/Files");
if (Directory.Exists(uploadFolder) == false)
{
Directory.CreateDirectory(uploadFolder);
}
return new MultipartFormDataStreamProvider(uploadFolder);
}
private string GetTitleOfAlbum(MultipartFormDataStreamProvider provider)
{
var titleOfAlbum = "";
foreach(var key in provider.FormData.GetValues(0))
{
titleOfAlbum = key;
}
return titleOfAlbum;
}
}
Path looks like:
"C:\Users\Oops\Documents\Visual Studio 2015\Projects\WebApplication1\ForMyCustomers\WebApplication1\Files\BodyPart_b40d80c5-47dc-41db-8e35-9d39d4e27939"
I getting path from FileData:
and convert it to base64, but it doesn't displays at page
I've got File not found error.
How can I resolve it? if the URL is wrong how can I get correct one?
You cannot use physical path (the one you used) on web. The physical path like "C:\something" is the path that can be used only by your OS.
The URL however, is the path that you need and to use and to do that you need to put your files somewhere that is readable by your host (IIS).
You are already writing your files in "~/Files". so you just need to add the file name at the end.
var url= "~/Files/"+filename;
you need to save the file name when you are uploading your file so when you want to fetch data from DB, fetch the file name from DB and create the url using that.
Related
I have this code to download a file in the database, but it only downloads the first user upload.
I tried using LastOrDefault and reverse to download the most recent file but I couldn't.
Does anyone have any idea how to do it?
[HttpGet]
[Route("~/DownloadFileCNPJ/{Id}")]
public async Task<IActionResult> DownloadFileCNPJ(long Id)
{
using (var context = new MyDbContext())
{
var cartaoCnpj = (from j in context.CartaoCNPJCedentes
where j.CedenteId.Equals(Id)
select j).Reverse().FirstOrDefault();
if (cartaoCnpj != null)
{
var content = new System.IO.MemoryStream(cartaoCnpj.CartaoCNPJ);
var contentType = cartaoCnpj.TipoCartãoCNPJ;
var fileName = cartaoCnpj.NomeArquivoCNPJ;
return File(content, contentType, fileName);
}
return null;
}
}
I am working on an app that plays audio using the MediaPlayer. It works when the audio file to play is already in the Assets folder. However, my goal is to use the FilePicker plugin for the user to pick a file from their device to be played.
From the FilePicker, I am able to get a path (which seems to be a Uri), like content://com.android.providers.downloads.documents/document/6531. However, attempting use the MediaPlayer with this path (both as a string and as a Uri) results in Java.IO.IOException: 'setDataSource failed.: status=0x80000000'.
I'm assuming it's not possible to use the MediaPlayer on a file outside of the Assets folder. So my question becomes is there a way to add an asset to a project's asset folder when a path is provided? Or am I wrong, and is there a way to use the MediaPlayer given the Uri?
Here is the code of the button that handles importing:
Button browse = FindViewById<Button>(Resource.Id.browse);
browse.Click += async delegate
{
var fileImp = await CrossFilePicker.Current.PickFile();
if (fileImp != null)
{
path = fileImp.FilePath;
}
};
And after sending the path to another class:
public void load()
{
player = new MediaPlayer();
player.SetDataSource(path);
player.Prepare();
}
This other attempt at setting the data source does not work either, and gets the same error:
public void load()
{
player = new MediaPlayer();
Android.Net.Uri uri = Android.Net.Uri.Parse(songFileString);
player.SetDataSource(Application.Context, uri);
player.Prepare();
}
Any help is appreciated, thanks.
content://com.android.providers.downloads.documents/document/6531
You could try to convert the uri to the file path.
string filePath = null;
Android.Net.Uri uri = Android.Net.Uri.Parse(path);
if (DocumentsContract.IsDocumentUri(this, uri))
{
string docId = DocumentsContract.GetDocumentId(uri);
if (uri.Authority.Equals("com.android.providers.media.documents"))
{
string id = docId.Split(":")[1];
string selection = MediaStore.Video.Media.InterfaceConsts.Id + "=" + id;
filePath = getfilePath(MediaStore.Video.Media.ExternalContentUri, selection);
}
else if (uri.Authority.Equals("com.android.providers.downloads.documents"))
{
Android.Net.Uri contentUri = ContentUris.WithAppendedId(Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(docId));
filePath = getfilePath(contentUri, null);
}
}
else if (uri.Scheme.Equals("content", StringComparison.OrdinalIgnoreCase))
{
filePath = getfilePath(uri, null);
}
else if (uri.Scheme.Equals("file", StringComparison.OrdinalIgnoreCase))
{
filePath = uri.Path;
}
getfilePath method:
private string getfilePath(Android.Net.Uri uri, string selection)
{
string path = null;
var cursor = ContentResolver.Query(uri, null, selection, null, null);
if (cursor != null)
{
if (cursor.MoveToFirst())
{
path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Video.Media.InterfaceConsts.Data));
}
cursor.Close();
}
return path;
}
I have a Xamarin Forms application in which I want to read a txt file. In my android project the file is placed in the assets folder with these properties :
Build action : Android Asset
Copy options : Allways copy.
And I am capabale to read the file with this code :
public string GetAppSetting(string name)
{
string retVal = "";
try
{
using (StreamReader sr = new StreamReader(AndroidHelper.Assets.Open("AppSettings.txt")))
{
var result = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in result)
{
if (line.StartsWith(name + ":"))
return line.Split(':')[1];
}
}
}
catch (Exception ex)
{
ParseError(ex, "GetConnectionString");
}
return retVal;
}
On the other hand, in the uwp project, I have allways the exception File Not Found!
I put the file in the root of the project and tried to put in the assets folder too. It doesn't change the result. File Not Found!
Build action : Content (Tried other options too).
Copy options : Allways copy.
Here is my code to read the file :
private async Task<string> ReadFileAsync(string name)
{
string retVal = "parameter not found";
try
{
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = await storageFolder.GetFileAsync("AppSettings.txt");
string str = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);
foreach (var line in str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
{
if (line.StartsWith(name + ":"))
return line.Split(':')[1];
}
}
catch (Exception ex)
{
MainHelper.ParseError(ex, "UWP readFileAsync");
}
return retVal;
}
What is wrong wiht my code ? Or where should I place the AppSettings.txt ?
For UWP,
I suggest you to set the file as an "Embedded Resource" (Build Action)
To ensure your file is loaded as an embedded resource at runtime, you can enumerate all your assembly's resources like this:
var resourceNames = anotherSameResAssemblyInstance.GetType()
.GetTypeInfo().Assembly
.GetManifestResourceNames();
Then, you can open the file as a stream like this:
string myFileResourceStream = "{YourAppNamespace}.AppSettings.txt";
var myFileResourceStream = someAssembly.GetManifestResourceStream(name);
Where 'YourAppNamespace' is the namespace in your app where is embedded the file. To get the correct full name, just check all values returned by GetManifestResourceNames() method.
Example:
var myFile = resourceNames.Where(x => x.Contains("AppSettings.txt")).FirstOrDefault();
if (myFile != null)
{
var str = this.GetType().GetTypeInfo().Assembly.GetManifestResourceStream(myFile);
}
It should now work.
In the UWP MainPage Xaml.cs change the LoadApplication:
namespace MyApp.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
LoadApplication(new MyApp.App(Windows.Storage.ApplicationData.Current.LocalFolder.Path));
}
}
}
Then in the app.Xaml.cs add:
public static string path;
public App(string paTh)
{
InitializeComponent();
path = paTh.ToString();
MainPage = new ContentPage();
}
Then use App.path as the Windows storage path.
In my app, I am using OneDrive to keep data in sync. I am successfully writing the file to OneDrive, but am having no luck replacing the local outdated data with the newer OneDrive data.
My current method, which completes without throwing an exception, does not return the same text data that the file on OneDrive contains.
Goal of the method is to compare the datemodified to the OneDrive file to the local file, and if OneDrive is newer, write the contents of the OndeDrive file to the local StorageFile, and then return it to be de-serialized.
private async Task<string> GetSavedDataFileAsync(string filename)
{
string filepath = _appFolder + #"\" + KOWGame + #"\" + filename;
StorageFile localread;
BasicProperties localprops = null;
string txt;
try
{
localread = await local.GetFileAsync(filepath);
localprops = await localread.GetBasicPropertiesAsync();
}
catch (FileNotFoundException)
{ localread = null; }
if (_userDrive != null)
{
if (_userDrive.IsAuthenticated)
{
try
{
Item item = await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Request().GetAsync();
if (item != null)
{
DateTimeOffset drivemodified = (DateTimeOffset)item.FileSystemInfo.LastModifiedDateTime;
if (localprops != null)
{
if (drivemodified > localprops.DateModified)
{
Stream stream = await localread.OpenStreamForWriteAsync();
using (stream)
{ await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Request().GetAsync(); }
}
}
}
}
catch (OneDriveException e)
{
if (e.IsMatch(OneDriveErrorCode.ActivityLimitReached.ToString()))
{ string stop; }
}
}
}
if (localread == null) return string.Empty;
txt = await FileIO.ReadTextAsync(localread);
return txt;
}
I tried to reverse engineer another answer I found on Stack regarding writing a StorageFile to OneDrive, in that I needed to open the stream of the local file, but I doesn't appear to be working properly.
To get the content of a OneDrive item, we need use following method:
var contentStream = await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Content.Request().GetAsync();
While using
await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Request().GetAsync();
you are getting the OneDrive Item not its content.
So you can change your code like following to write the content of a Onedrive item to a local file:
if (drivemodified > localprops.DateModified)
{
using (var stream = await localread.OpenStreamForWriteAsync())
{
using (var contentStream = await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Content.Request().GetAsync())
{
contentStream.CopyTo(stream);
}
}
}
How do I post a httppostedfile to a webapi?
Basically I want the user to select an excel file and I want to post it to my webapi.
The gui is made with classic asp.net and the webapi is made with new .NET apicontroller.
I have done some api coding before but then I used JSON and that doesn't seem to work very good with this kind of object.
Can someone please just point me in the right direction so that I can continue to search for info. Right now I don't even know what to search for.
I solved this by doing this:
In my controller:
using (var client = new HttpClient())
using (var content = new MultipartFormDataContent())
{
client.BaseAddress = new Uri(System.Configuration.ConfigurationManager.AppSettings["PAM_WebApi"]);
var fileContent = new ByteArrayContent(excelBytes);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
content.Add(fileContent);
var result = client.PostAsync("api/Product", content).Result;
}
And here is my ApiController:
[RoutePrefix("api/Product")]
public class ProductController : ApiController
{
public async Task<List<string>> PostAsync()
{
if (Request.Content.IsMimeMultipartContent())
{
string uploadPath = HttpContext.Current.Server.MapPath("~/uploads");
if (!System.IO.Directory.Exists(uploadPath))
{
System.IO.Directory.CreateDirectory(uploadPath);
}
MyStreamProvider streamProvider = new MyStreamProvider(uploadPath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
List<string> messages = new List<string>();
foreach (var file in streamProvider.FileData)
{
FileInfo fi = new FileInfo(file.LocalFileName);
messages.Add("File uploaded as " + fi.FullName + " (" + fi.Length + " bytes)");
}
return messages;
}
else
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid Request!");
throw new HttpResponseException(response);
}
}
}
public class MyStreamProvider : MultipartFormDataStreamProvider
{
public MyStreamProvider(string uploadPath)
: base(uploadPath)
{
}
public override string GetLocalFileName(HttpContentHeaders headers)
{
string fileName = headers.ContentDisposition.FileName;
if (string.IsNullOrWhiteSpace(fileName))
{
fileName = Guid.NewGuid().ToString() + ".xls";
}
return fileName.Replace("\"", string.Empty);
}
}
I found this code in a tutorial so i'm not the one to be credited.
So here i write the file to a folder. And because of the mysreamprovider i can get the same name of the file as the file i first added in the GUI. I also add the ending ".xls" to the file because my program is only going to handle excel files. Therefor i have added some validation to the input in my GUI to so that i know that the file added is an excel file.