File paths can't be found from shared library - c#

I have an app wheere the user can view images attached to a sample, and then they need to be able to email the details of that sample (including image attachements) to stakeholders.
In my web.config of the web app, I have:
<add key="ImagesPath" value="~/Images" />
And this path seems to work perfectly for retrieving and displaying the images, which are stored in an images folder in the project.
However, when I try adding the image as attachments to an email (from a shared library) The app suddenly can't find the path with this error when calling
message.Attachments.Add(new Attachment(item));
when debugging
Could not find file 'C:\Program Files (x86)\IIS Express\~\Images\3000\1\1\3.png'.
after publishing
Could not find a part of the path 'C:\Windows\SysWOW64\inetsrv\~\Images\9251\1\1\1.JPG'.
What I tried
1.
I tried calling this before creating the attachment
var appDomain = System.AppDomain.CurrentDomain;
var basePath = appDomain.RelativeSearchPath ?? appDomain.BaseDirectory;
var p = Path.Combine(basePath, item);
message.Attachments.Add(new Attachment(p));
But the app still can't find the files.
I tried calling
System.Web.HttpContext.Current.Server.MapPath(item);
message.Attachments.Add(new Attachment(item));
before creating each attachment, but again theh images can't be found.
Can anyone please help me resolve this.

From the code you posted, you seems to call the System.Web.HttpContext.Current.Server.MapPath(item); method, but not using the result of that to create the Attachment.
The Server.MapPath returns the physical location of the file. Use the result of the call to that method to add the attachment.
This should work.
var item = "3000/1/1/3.png";
var fileLocation = Path.Combine("images/",item);
var fullPath = System.Web.HttpContext.Current.Server.MapPath(fileLocation);
message.Attachments.Add(new Attachment(fullPath));
Sometimes, I tend to do a file exist check before actually trying to access it.
if (File.Exists(fullPath ))
{
message.Attachments.Add(new Attachment(fullPath));
}
If you are using it from an MVC controller, you may use Url.Content along with Server.MapPath
var p = Server.MapPath(Url.Content("~/images/3000/1/1/3.png"));

Related

PnP.Core uploading to Sharepoint folder c# error 'To update this folder, go to the channel in Microsoft Teams'

I have a solution I created a little over a year ago that uses PnP.Core to upload file to a specific folder on SharePoint. It was all well until a couple days ago where that solution started generating error that says
To update this folder, go to the channel in Microsoft Teams
I am at a bit of a loss as to why and what is causing this.
Below is a minimal code sample of what I have. I should mention that the folder is getting created but fails with said error when uploading the file to the folder.
Any pointers would be greatly appreciated.
authenticate using officeDev.PnP.Core.AuthenticationManager
...
Folder Root_Folder = web.GetFolderByServerRelativeUrl(Root_Folder_Relative_Url_Path);
//Create new subFolder to load files into
string Folder_Name = _Folder_Name;
Root_Folder.Folders.Add(Folder_Name);
Root_Folder.Update();
//Add file to new Folder
Folder Subject_Folder = web.GetFolderByServerRelativeUrl(Root_Folder_Relative_Url_Path + "/" + Folder_Name);
FileCreationInformation Subject_Result_File = new FileCreationInformation {
ContentStream = new MemoryStream(_File_To_Upload),
Url = _File_Name,
Overwrite = true
};
Microsoft.SharePoint.Client.File uploadFile = Subject_Folder.Files.Add(Subject_Result_File);
Subject_Folder.Update();
Client_Ctx.ExecuteQuery();
Looks like the Update method was the issue. Removing it and just letting the ExecuteQuery handle all the operation fixed it.

Downloading images from publicly shared folder on Dropbox

I received a link to shared folder from e-commerce company. The link is public and not shared with my dropbox account directly.
How do I get an url to the image that I can pass to either DownloadAsync method of the same sdk or simply HttpClient and well ... download it?
Ideally it would be the same link I get when I click on the image when viewing that shared folder in a browser.
https://www.dropbox.com/sh/{folder_hash}/{file_hash_maybe}/{filename}?dl=0
This is what I have tried:
using Dropbox.Api;
using Dropbox.Api.Files;
...
var accessToken = "abracadabra";
var sharedFolderUrl = "https://www.dropbox.com/sh/{folder_hash}?dl=0";
using (var dbx = new DropboxClient(accessToken))
{
var sharedLink = new SharedLink(sharedFolderUrl);
var sharedFiles = await dbx.Files.ListFolderAsync(path: "", sharedLink: sharedLink);
// sharedFiles - has over 13,000 entries, I use cursor to get them all.
foreach (var file in sharedFiles.Entries)
{
if (file.IsFile)
{
// tried this, but:
// 1. it's crazy to loop through all
// 2. link.Response.Url gives me the same url to a shared folder for all items
var link = await dbx.Sharing.GetSharedLinkFileAsync(url: sharedFolderUrl, path: "/" + file.Name);
}
}
}
Using the GetSharedLinkFileAsync method is the right way to programmatically download a file from a shared link. It actually gives both the metadata (in the link.Response in your code like you mentioned), as well as the file data directly (not via a URL).
To access the file data, you can use any of the GetContentAs... methods documented under IDownloadResponse as returned by GetSharedLinkFileAsync. In your code, that would look something like: link.GetContentAsStreamAsync() (or whichever one you want).
Alternatively, if you want to download the entire folder from the shared link, you can use the URL parameters documented in this help center article. (That may fail for very large folders though.)

Not allowed to load local resource from App_Data folder

I need to server a larger amount of Pdf's which require authorisation in order to be able to download.
I have read that it is advisable to place them in the App_Data folder.
I have created three folders in the App_Data folder:
> SetOne
> SetTwo
> SetThree
I need to pass these files to my view.
Controller
var files = Directory.EnumerateFiles(Server.MapPath("~/App_Data/SetOne"));
return View(files);
View
<ul>
#foreach (var fullPath in Model)
{
var fileName = Path.GetFileName(fullPath);
var downloadPath = #Path.GetDirectoryName(fullPath) + "\\" + #fileName;
<li>#fileName</li>
}
</ul>
Using the above code, I am able to list the contents of the SetOne folder in an unordered list, however when I attempt to view one of the Pdf's I see:
Not allowed to load local resource:
file:///B:/Development/MyProject/MyProject.Web/App_Data/SetOne/sampleOne.pdf
How can I allow the application to give access to these files?
edit
I've also tried creating a new folder called Pdfs and moving the documents to this, however I get the same error message when I view in chrome dev tools.
Do I need to implement a Http Handler for this task?
Your approach is OK for WinForms application but shouldn't work for Web. downloadPath should contain the Url but not the physical path on the file (like some.com/pdfs/1.pdf)
You could use Server.MapPath for this case

WriteTextAsync not writing to file

I have this piece of code:
string jsonPath = #"Model\Datamodel\UserData.json";
User userItem = JsonConvert.DeserializeObject<User>(user);
User.Add(userItem);
string content = user;
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
var file = await folder.GetFileAsync(jsonPath);
await FileIO.WriteTextAsync(file,content);
Debug.WriteLine(String.Format("DONE"));
The "Done" debug line is written in console but it does not write anything to the file.
I also don't get any errors. When I debug and look at Folder and file I see that they are correctly.
Can anybody help?
You can't write to files in Windows.ApplicationModel.Package.Current.InstalledLocation, you need to use one of the other writeable locations available to you instead. (e.g. ApplicationData.Current.LocalFolder)
If you need to access the content of the file that was shipped with the package, I would suggest copying it to the local folder, and using the copy for read/write access.

Visual Studio 2010 working directory

I'm developing a C# asp.net web application. I'm basically done with it, but I have this little problem. I want to save xml files to the "Users" folder within my project, but if I don't psychically hard code the path "C:......\Users" in my project it wants to save the file in this "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\Users" folder, this is an annoying problem because I can't use the hard coded directory on our web hosts server. Also, I have a checkbox list that populates from the the "DownloadLibrary" folder in my project, and its suppose to download the files from that fold but its also looking to the "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" folder for download even though its populating from the correct folder. I'm very confused by this, its the first time something like this has ever happened to me. Can anyone please help me with this, its the only thing standing in my way to complete this project.
You don't want to use the working directory at all; you want to use a directory relative to where the web application is located (which can be retrieved from HttpRequest.ApplicationPath.
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string pathToApp = request.MapPath(request.ApplicationPath);
string usersPath = System.IO.Path.Combine(pathToApp, "Users");
Update
As VincayC points out; asp.net development is not my strongest skill ;) The above code is essentially equivalent of this (much simpler) code:
string usersPath = HttpRequest.Current.Request.MapPath("~/Users");
If this code appears in the code-behind of a page, you can probably cut HttpContext.Current as well, since the page has a Request property.
That did fix the one problem I'm having, but the downloads are still not downloading from the right place, the program still wants to get the files from "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" directory here is the code I'm using
--Code to populate the checkbox--
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string appPath = request.MapPath(request.ApplicationPath);
string directory = System.IO.Path.Combine(appPath, "DownloadLibrary/");
// Get the list of files into the CheckBoxList
var dirInfo = new DirectoryInfo(directory);
cblFiles.DataSource = dirInfo.GetFiles();
cblFiles.DataBind();
--Download Button Code--
// Tell the browser we're sending a ZIP file!
var downloadFileName = string.Format("Items-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HH_mm_ss"));
Response.ContentType = "application/zip";
Response.AddHeader("Content-Disposition", "filename=" + downloadFileName);
// Zip the contents of the selected files
using (var zip = new ZipFile())
{
// Add the password protection, if specified
/*if (!string.IsNullOrEmpty(txtZIPPassword.Text))
{
zip.Password = txtZIPPassword.Text;
// 'This encryption is weak! Please see http://cheeso.members.winisp.net/DotNetZipHelp/html/24077057-63cb-ac7e-6be5-697fe9ce37d6.htm for more details
zip.Encryption = EncryptionAlgorithm.WinZipAes128;
}*/
// Construct the contents of the README.txt file that will be included in this ZIP
var readMeMessage = string.Format("Your ZIP file {0} contains the following files:{1}{1}", downloadFileName, Environment.NewLine);
// Add the checked files to the ZIP
foreach (ListItem li in cblFiles.Items)
if (li.Selected)
{
// Record the file that was included in readMeMessage
readMeMessage += string.Concat("\t* ", li.Text, Environment.NewLine);
// Now add the file to the ZIP (use a value of "" as the second parameter to put the files in the "root" folder)
zip.AddFile(li.Value, "Your Files");
}
// Add the README.txt file to the ZIP
//zip.AddEntry("README.txt", readMeMessage, Encoding.ASCII);
// Send the contents of the ZIP back to the output stream
zip.Save(Response.OutputStream);</pre></code>
I'm not sure how to get the downloads to point to my application directory,I tried everything I can think off.

Categories

Resources