CRUD Functions for creating folder in wwwroot - asp.net-mvc

I want to create a function which can create folder inside wwwroot folder.
Because my client requirement is to create albums (folder). I need to save this albums in my root folder and then the pictures in those folders. For example : BirthdayAlbum, WeedingAlbum and so on..
How can i do this in ASP.NET Core MVC?

Although your question does not include what you have done so far but I hope this will help you in a way:
public async Task<IActionResult> Upload(string folder)
{
if (folder == null)
{
folder = "Uploads";
}
var file = Request.Form.Files[0];
var directory = Path.Combine(_environment.WebRootPath, $"{folder}");
var filePath = $"{Request.Scheme}://{Request.Host}/{folder}/";
var finalFileName = "";
if (file.Length > 0)
{
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
var fileName = Path.GetFileName(Guid.NewGuid().ToString().Substring(0, 12).ToLower() + file.FileName);
var path = Path.GetFullPath(directory);
using (var fileStream = new FileStream(Path.Combine(path, fileName), FileMode.Create, FileAccess.ReadWrite))
{
await file.CopyToAsync(fileStream);
}
finalFileName = fileName;
}
return Ok($"{filePath + finalFileName}");
}
NOTE: Please inject IWebHostEnvironment in your controller constructor if you are using ASP.NET Core 3.1 or its equivalent if lower.
What the above code does is to allow you create folders in the wwwroot folder with the folder name you specified and as well upload images or files.
I hope this helps you resolve the issue.

Related

PDF not loading from documents folder on App relaunch iOS

I have a pdf that I download from the server and save it. Next I open the file from the file path within a UIWebView. This works the first time I launch the app. When I relaunch the app again, even thought the file path is the same, the document does not open. Also, the document does exist in the document folder of the app.
I am doing something like :-
SaveToFolder.cs
var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), fileName);
using (FileStream destinationStream = File.Create(filePath))
{
await documentStream.CopyToAsync(destinationStream);
}
File path after saving the document first time :-
/var/mobile/Containers/Data/Application/C3EA2325-81CA-4EC9-8C03-479ACF7EE330/Documents/Insufficiency.pdf
File Path on app relaunch
/var/mobile/Containers/Data/Application/C3EA2325-81CA-4EC9-8C03-479ACF7EE330/Documents/Insufficiency.pdf
Is there something Iam doing wrong?
I have created a file in iOS for reading & writing file. Please have a look in iOS
using System;
using Xamarin.Forms;
using FileReader.iOS;
using System.IO;
using FileReader;
using Foundation;
using System.Linq;
using System.Threading.Tasks;
[assembly: Dependency(typeof(SaveAndLoadiOS))]
namespace FileReader.iOS
{
public class SaveAndLoadiOS : LoadAndSave
{
public static string DocumentPath
{
get
{
var documentURL = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User).Last();
return documentURL.Path;
}
}
public string CreatePath(string fileName)
{
return Path.Combine(DocumentPath, fileName);
}
public async Task SaveTextAsync(string fileName, string text)
{
string path = CreatePath(fileName);
if (IsFileExits(fileName))
{
File.Delete(path);
}
using (StreamWriter sw = File.CreateText(path))
await sw.WriteAsync(text);
}
public async Task<string> LaodTextAsync(string fileName)
{
string path = CreatePath(fileName);
using (StreamReader sr = File.OpenText(path))
return await sr.ReadToEndAsync();
}
public bool IsFileExits(string fileName)
{
return File.Exists (CreatePath(fileName));
}
}
}
For reading from my .CS class (subclass of ContentPage), Below is the code
var tempFileService = DependencyService.Get<LoadAndSave>();
var itemFile = await tempFileService.LaodTextAsync(tempFile.StoredFileName);
var rootobject = JsonConvert.DeserializeObject<Rootobject>(itemFile);
Where LoadAndSave is an interface as below
using System;
using System.Threading.Tasks;
namespace FileReader
{
public interface LoadAndSave
{
Task SaveTextAsync(string fileName, string text);
Task<string> LaodTextAsync(string fileName);
bool IsFileExits(string fileName);
}
}
Hope it helps.
I ran into the same issue a while ago. You can refer Can't find saved file (in device) after restarting the app
According to the answer
You shouldn't store raw file paths for persistence (or if you do, know that the root can move on you). A better practice would be to only store the relative part of the path and always attach it to the current "root" path in question (particularly if you might be sharing data across devices as with iCloud).
Maybe your root is changing as well. You can change your approach and append the filename with the default path to your documents folder like so in Xamarin:-
var docsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
filePath = docsPath +"/" + "Insuffeciency.pdf";
Also, consider changing your Personal folder to MyDocuments folder while saving the file.

How do I write FileContentResult on disk?

I am trying to use the Rotativa component to store (not to show) a copy of the invoice permanently on web server disk. Two questions:
Why I need to specify a controller action? ("Index", in this
case)
How do I write the FileContentResult on local disk without
displaying it?
Thanks.
Here is my code:
[HttpPost]
public ActionResult ValidationDone(FormCollection formCollection, int orderId, bool fromOrderDetails)
{
Order orderValidated = context.Orders.Single(no => no.orderID == orderId);
CommonUtils.SendInvoiceMail(orderValidated.customerID , orderValidated.orderID);
var filePath = Path.Combine(Server.MapPath("/Temp"), orderValidated.invoiceID + ".pdf");
var pdfResult = new ActionAsPdf("Index", new { name = orderValidated.invoiceID }) { FileName = filePath };
var binary = pdfResult.BuildPdf(ControllerContext);
FileContentResult fcr = File(binary, "application/pdf");
// how do I save 'fcr' on disk?
}
You do not need the FileContentResult to create a file. You've got the byte array which can be saved directly to the disk:
var binary = pdfResult.BuildPdf(ControllerContext);
System.IO.File.WriteAllBytes(#"c:\foobar.pdf", binary);
string FileName="YOUR FILE NAME";
//first give a name to file
string Path=Server.MapPath("YourPath in solution"+Filename+".Pdf")
//Give your path and file extention. both are required.
binary[]= YOUR DATA
//Describe your data to be save as file.
System.IO.File.WriteAllBytes(Path, binary);
Thats simple...

How do I store an uploaded file to a location other than the application folder in MVC application

I can successfully upload a file using this code:
[HttpPost]
public ActionResult Save(IEnumerable<HttpPostedFileBase> attachments)
{
// The Name of the Upload component is "attachments"
foreach (var file in attachments)
{
// Some browsers send file names with full path. This needs to be stripped.
var fileName = Path.GetFileName(file.FileName);
var physicalPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
file.SaveAs(physicalPath);
}
// Return an empty string to signify success
return Content("");
}
But this puts the file in the running application App_Data folder. I want to put the file in a share on my LAN. I have tried the code below but it always appends myPath to the path of the application:
[HttpPost]
public ActionResult Save(IEnumerable<HttpPostedFileBase> attachments)
{
// The Name of the Upload component is "attachments"
foreach (var file in attachments)
{
// Some browsers send file names with full path. This needs to be stripped.
var fileName = Path.GetFileName(file.FileName);
//add possible new folder name to path
var myPath = "//my-server-myshare/myfolder/";
//combine with file name
var physicalPath = Path.Combine(Server.MapPath(myPath), fileName);
file.SaveAs(physicalPath);
}
// Return an empty string to signify success
return Content("");
}
How can I force this to save in the URL I have as myPath?
Network shares need to be full UNC paths, so flip your slashes around :
var myPath = #"\\my-server-myshare\myfolder\";
You could also just create the file directly :
file.Create(#"\\my-server-myshare\myfolder\");

Azure: Read files from App_Data [duplicate]

What is the correct way to find the absolute path to the App_Data folder from a Controller in an ASP.NET MVC project? I'd like to be able to temporarily work with an .xml file and I don't want to hardcode the path.
This does not work:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
string path = VirtualPathUtility.ToAbsolute("~/App_Data/somedata.xml");
//.... do whatever
return View();
}
}
I think outside of the web context VirtualPathUtility.ToAbsolute() doesn't work.
string path comes back as "C:\App_Data\somedata.xml"
Where should I determine the path of the .xml file in an MVC app?
global.asax and stick it an application-level variable?
ASP.NET MVC1 -> MVC3
string path = HttpContext.Current.Server.MapPath("~/App_Data/somedata.xml");
ASP.NET MVC4
string path = Server.MapPath("~/App_Data/somedata.xml");
MSDN Reference:
HttpServerUtility.MapPath Method
string path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
This is probably a more "correct" way of getting it.
I try to get in the habit of using HostingEnvironment instead of Server as it works within the context of WCF services too.
HostingEnvironment.MapPath(#"~/App_Data/PriceModels.xml");
The most correct way is to use HttpContext.Current.Server.MapPath("~/App_Data");. This means you can only retrieve the path from a method where the HttpContext is available. It makes sense: the App_Data directory is a web project folder structure [1].
If you need the path to ~/App_Data from a class where you don't have access to the HttpContext you can always inject a provider interface using your IoC container:
public interface IAppDataPathProvider
{
string GetAppDataPath();
}
Implement it using your HttpApplication:
public class AppDataPathProvider : IAppDataPathProvider
{
public string GetAppDataPath()
{
return MyHttpApplication.GetAppDataPath();
}
}
Where MyHttpApplication.GetAppDataPath looks like:
public class MyHttpApplication : HttpApplication
{
// of course you can fetch&store the value at Application_Start
public static string GetAppDataPath()
{
return HttpContext.Current.Server.MapPath("~/App_Data");
}
}
[1] http://msdn.microsoft.com/en-us/library/ex526337%28v=vs.100%29.aspx
Phil Haak has an example that I think is a bit more stable when dealing with paths with crazy "\" style directory separators. It also safely handles path concatenation. It comes for free in System.IO
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
However, you could also try "AppDomain.CurrentDomain.BaseDirector" instead of "Server.MapPath".
string filePath = HttpContext.Current.Server.MapPath("~/folderName/filename.extension");
OR
string filePath = HttpContext.Server.MapPath("~/folderName/filename.extension");
This way i got the hosting path.
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
namespace IHostingEnvironmentExample.Controllers
{
public class HomeController : Controller
{
private IHostingEnvironment _env;
public HomeController(IHostingEnvironment env)
{
_env = env;
}
public IActionResult Index()
{
var webRoot = _env.WebRootPath;
var file = System.IO.Path.Combine(webRoot, "test.txt");
System.IO.File.WriteAllText(file, "Hello World!");
return View();
}
}
}
https://forums.asp.net/t/1696005.aspx?How+to+get+Local+Server+path+in+mvc
string Index = i;
string FileName = "Mutton" + Index + ".xml";
XmlDocument xmlDoc = new XmlDocument();
var path = Path.Combine(Server.MapPath("~/Content/FilesXML"), FileName);
xmlDoc.Load(path); // Can use xmlDoc.LoadXml(YourString);
this is the best Solution to get the path what is exactly need for now

A localized scriptbundle solution

Hi I am currently using the asp.net MVC 4 rc with System.Web.Optimization. Since my site needs to be localized according to the user preference I am working with the jquery.globalize plugin.
I would very much want to subclass the ScriptBundle class and determine what files to bundle according to the System.Threading.Thread.CurrentThread.CurrentUICulture. That would look like this:
bundles.Add(new LocalizedScriptBundle("~/bundles/jqueryglobal")
.Include("~/Scripts/jquery.globalize/globalize.js")
.Include("~/Scripts/jquery.globalize/cultures/globalize.culture.{0}.js",
() => new object[] { Thread.CurrentThread.CurrentUICulture })
));
For example if the ui culture is "en-GB" I would like the following files to be picked up (minified of course and if possible cached aswell until a script file or the currentui culture changes).
"~/Scripts/jquery.globalize/globalize.js"
"~/Scripts/jquery.globalize/globalize-en-GB.js" <-- if this file does not exist on the sever file system so fallback to globalize-en.js.
I tried overloading the Include method with something like the following but this wont work because it is not evaluated on request but on startup of the application.
public class LocalizedScriptBundle : ScriptBundle
{
public LocalizedScriptBundle(string virtualPath)
: base(virtualPath) {
}
public Bundle Include(string virtualPathMask, Func<object[]> getargs) {
string virtualPath = string.Format(virtualPathMask, getargs());
this.Include(virtualPath);
return this;
}
}
Thanks
Constantinos
That is correct, bundles should only be configured pre app start. Otherwise in a multi server scenario, if the request for the bundle is routed to a different server other than the one that served the page, the request for the bundle resource would not be found.
Does that make sense? Basically all of your bundles need to be configured and defined in advance, and not dynamically registered on a per request basis.
take a look: https://stackoverflow.com/questions/18509506/search-and-replace-in-javascript-before-bundling
I coded this way for my needs:
public class MultiLanguageBundler : IBundleTransform
{
public void Process(BundleContext context, BundleResponse bundle)
{
var content = new StringBuilder();
var uicult = Thread.CurrentThread.CurrentUICulture.ToString();
var localizedstrings = GetFileFullPath(uicult);
if (!File.Exists(localizedstrings))
{
localizedstrings = GetFileFullPath(string.Empty);
}
using (var fs = new FileStream(localizedstrings, FileMode.Open, FileAccess.Read))
{
var m_streamReader = new StreamReader(fs);
var str = m_streamReader.ReadToEnd();
content.Append(str);
content.AppendLine();
}
foreach (var file in bundle.Files)
{
var f = file.VirtualFile.Name ?? "";
if (!f.Contains("localizedstrings"))
{
using (var reader = new StreamReader(VirtualPathProvider.OpenFile(file.VirtualFile.VirtualPath)))
{
content.Append(reader.ReadToEnd());
content.AppendLine();
}
}
}
bundle.ContentType = "text/javascript";
bundle.Content = content.ToString();
}
private string GetFileFullPath(string uicult)
{
if (uicult.StartsWith("en"))
uicult = string.Empty;
else if (!string.IsNullOrEmpty(uicult))
uicult = ("." + uicult);
return Kit.ToAbsolutePath(string.Format("~/Scripts/locale/localizedstrings{0}.js", uicult));
}
}

Resources