How to store file into inetpub\wwwroot instead of local machine folder on UWP application - iis

I am currently developing a UWP application for my school project and one of the pages allows the user to take a picture of themselves. I created the feature by following this tutorial: CameraStarterKit
For now I am storing the pictures taken on my desktop's picture folder. But the requirement of my project is to store the pictures taken in a folder called "Photos" under inetpub\wwwroot.
I dont really understand what wwwroot or IIS is... hence, I have no idea how I should modify my codes and store them into the folder.
Here are my codes for storing on my local desktop:
private async Task TakePhotoAsync()
{
idleTimer.Stop();
idleTimer.Start();
var stream = new InMemoryRandomAccessStream();
//MediaPlayer mediaPlayer = new MediaPlayer();
//mediaPlayer.Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/camera-shutter-click-03.mp3"));
//mediaPlayer.Play();
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
try
{
var file = await _captureFolder.CreateFileAsync("NYPVisitPhoto.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(_rotationHelper.GetCameraCaptureOrientation());
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
Debug.WriteLine("Photo saved!");
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
}
For the storing of the files:
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, StorageFile file, PhotoOrientation photoOrientation)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties);
await encoder.FlushAsync();
}
}
}

I would add an answer since there are tricky things about this requirement.
The first is the app can only access a few folders, inetpub is not one of them.
Using brokered Windows runtime component (I would suggest using FullTrustProcessLauncher, which is much simpler to develop and deploy) can enable UWP apps access folders in the same way as the traditional desktop applications do.
While this works for an ordinary folder, the inetpub folder, however, is different that it requires Administrators Privileges to write to, unless you turn UAC off.
The desktop component launched by the app does not have the adequate privileges to write to that folder, either.
So it think an alternative way would be setting up a virtual directory in IIS manager that maps to a folder in the public Pictures library, and the app saves picture to that folder.
From the website’s perspective, a virtual directory is the same as a real folder under inetpub, what differs is the access permissions.

Kennyzx is right here that you cannot access inetpub folder through your UWP application due to permissions.
But if your application fulfills following criteria then you can use Brokered Windows Component(a component within your app) to copy your file to any location in the system.
Your application is a LOB application
You are only targetting desktop devices(I assume this will be true because of your requirement)
You are using side-loading for your app installation and distribution.
If all three are Yes then use Brokered Windows Component for UWP, it's not a small thing that can be showed here on SO using an example. So give worth a try reading and implementing it.

Related

.net core web API,static file images not loading properly?

I have .net core web API PROJECT. I want to put some static images in this project.I have below code in start up file
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
provider.Mappings[".png"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
ContentTypeProvider = provider
});
when I run or deployed this web project, i have checked under it has StaticFiles folder has test.png
when I browse for test.tt/StaticFiles/test.png, or test.tt/wwwroot/StaticFiles/test.png or test.tt/wwwroot/StaticFiles/images/test.png
browser is not loading that image, it is displaying white page, where I check on network console of by F12,it is delivering response of type document and json.
My problem is image is not displaying, i have tried more images but not helpful.I am sure there is image,folder in my path.
can you tell how if I browse test.png,direct hitting path to get static file .net core WEB API images?
By default, static files go into the wwwroot in your project root. Calling app.UseStaticFiles(), causes this directory to be served at the base path of the site, i.e. /. As such, a file like wwwroot/images/test.png would be available at /images/test.png (note: without the wwwroot part).
I'm not sure what in the world you're doing with the rest of this code here, but you're essentially adding an additional served directory at [project root]/MyStaticFiles, which will then be served at /StaticFiles. As such, first, test.png would have to actually be in MyStaticFiles, not wwwroot, and then you'd access by requesting /StaticFiles/test.png.
However, there's no need for this other directory. If you simply want to add some additional media types, you can do that via:
services.Configure<StaticFileOptions>(o =>
{
var provider = new FileExtensionContentTypeProvider();
provider.Mappings.Add(".myapp", "application/x-msdownload");
// etc.
o.ContentTypeProvider = provider;
});
And then just use:
app.UseStaticFiles();
Nothing else is required.

Where is the ios LocalStorage when using PCLStorage for Xamarin forms?

I am using PCLStorage to store image in localStorage and access them via path returned.
Its working fine but the problem is, whenever I again start debugging the application, images are not accessible.
Where actually it stores images in Local Storage? Is it not permanent location?
I want to store images in fileSystem and related data and image path in sqlite. Its an offline application so need to store this data permanently.
Any suggestions for this would be helpful.
Thanks
Try below steps.
The interface is fairly simple because we're really only interested in passing the byte array and a filename when we save the image to disk.
public interface IPicture
{
void SavePictureToDisk (string filename, byte[] imageData);
}
DependencyService will delegate image saving to the appropriate class. The usage for the DependencyService is:
DependencyService.Get<IPicture>().SavePictureToDisk("ImageName", GetByteArray());
Create Classes in Platform-Specific Projects
iOS Project
[assembly: Xamarin.Forms.Dependency(typeof(Picture_iOS))]
namespace ImageSave.iOS
{
public class Picture_iOS: IPicture
{
public void SavePictureToDisk(string filename, byte[] imageData)
{
var MyImage = new UIImage(NSData.FromArray(imageData));
MyImage.SaveToPhotosAlbum((image, error) =>
{
//you can retrieve the saved UI Image as well if needed using
//var i = image as UIImage;
if(error != null)
{
Console.WriteLine(error.ToString());
}
});
}
}
}
I got the answer for this question on Xamarin Forum so just updating the link here so it can help others.
https://forums.xamarin.com/discussion/comment/217282/#Comment_217282
As explained here that everytime we redeploy app the core path changes thats why on redeploying I was not able to find images on the path where I saved it. So now I am only saving the partial path like the folderName\the image name and rest of the core path I am finding on runtime.
This solved my problem.

Why am I getting an UnauthorizedAccessException when trying to write a file to LocalStorage in Azure

I have created a local storage in my web role called "MyTestCache" as so in my
ServiceDefinition.csdef file. But when ever I call the System.IO.File.WriteAllBytes method I get a UnauthorizedAccess exception. Does anyone know what would be causing this? I dont get this when creating the directory in the code below, only when writing. I am using SDK 1.3.
private void SaveFileToLocalStorage(byte[] remoteFile, string filePath)
{
try
{
LocalResource myIO = RoleEnvironment.GetLocalResource("MyTestCache");
// Creates directory if it doesn't exist (ie the first time)
if (!Directory.Exists(myIO.RootPath + "/thumbnails"))
{
Directory.CreateDirectory(myIO.RootPath + "/thumbnails");
}
string PathToFile = Path.Combine(myIO.RootPath + "/thumbnails", filePath);
var path = filePath.Split(Char.Parse("/"));
// Creates the directory for the content item (GUID)
if (!Directory.Exists(Path.Combine(myIO.RootPath + "/thumbnails", path[0])))
{
Directory.CreateDirectory(Path.Combine(myIO.RootPath + "/thumbnails", path[0]));
}
// Writes the file to local storage.
File.WriteAllBytes(PathToFile, remoteFile);
}
catch (Exception ex)
{
// do some exception handling
return;
}
}
Check ACLs. In SDK 1.3 by default web roles are started in full IIS worker process, using Network Service as identity of application pool. Make sure Network Service account has permissions to execute operations you expect. In your case you are trying to create a sub-directory, so most probably you need at least Write permission. If your role also modifies ACLs on this directory, you need to grant Full access to this directory.

azure reading mounted VHD

I am developing "azure web application".
I have created drive and drivePath static members in WebRole as follows:
public static CloudDrive drive = null;
public static string drivePath = "";
I have created development storage drive in WebRole.OnStart as follows:
LocalResource azureDriveCache = RoleEnvironment.GetLocalResource("cache");
CloudDrive.InitializeCache(azureDriveCache.RootPath, azureDriveCache.MaximumSizeInMegabytes);
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
// for a console app, reading from App.config
//configSetter(ConfigurationManager.AppSettings[configName]);
// OR, if running in the Windows Azure environment
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
});
CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount;
CloudBlobClient blobClient = account.CreateCloudBlobClient();
blobClient.GetContainerReference("drives").CreateIfNotExist();
drive = account.CreateCloudDrive(
blobClient
.GetContainerReference("drives")
.GetPageBlobReference("mysupercooldrive.vhd")
.Uri.ToString()
);
try
{
drive.Create(64);
}
catch (CloudDriveException ex)
{
// handle exception here
// exception is also thrown if all is well but the drive already exists
}
string path = drive.Mount(azureDriveCache.MaximumSizeInMegabytes, DriveMountOptions.None);
IDictionary<String, Uri> listDrives = Microsoft.WindowsAzure.StorageClient.CloudDrive.GetMountedDrives();
drivePath = path;
The drive keeps visible and accessible till execution scope remain in WebRole.OnStart, as soon as execution scope leave WebRole.OnStart, drive become unavailable from application and static members get reset (such as drivePath get set to "")
Am I missing some configuration or some other error ?
Where's the other code where you're expecting to use drivePath? Is it in a web application?
If so, are you using SDK 1.3? In SDK 1.3, the default mode for a web application is to run under full IIS, which means running in a separate app domain from your RoleEntryPoint code (like OnStart), so you can't share static variables across the two. If this is the problem, you might consider moving this initialization code to Application_Begin in Global.asax.cs instead (which is in the web application's app domain).
I found the solution:
In development machine, request originate for localhost, which was making the system to crash.
Commenting "Sites" tag in ServiceDefinition.csdef, resolves the issue.

Upload a file to SharePoint through the built-in web services

What is the best way to upload a file to a Document Library on a SharePoint server through the built-in web services that version WSS 3.0 exposes?
Following the two initial answers...
We definitely need to use the Web Service layer as we will be making these calls from remote client applications.
The WebDAV method would work for us, but we would prefer to be consistent with the web service integration method.
There is additionally a web service to upload files, painful but works all the time.
Are you referring to the “Copy” service?
We have been successful with this service’s CopyIntoItems method. Would this be the recommended way to upload a file to Document Libraries using only the WSS web service API?
I have posted our code as a suggested answer.
Example of using the WSS "Copy" Web service to upload a document to a library...
public static void UploadFile2007(string destinationUrl, byte[] fileData)
{
// List of desination Urls, Just one in this example.
string[] destinationUrls = { Uri.EscapeUriString(destinationUrl) };
// Empty Field Information. This can be populated but not for this example.
SharePoint2007CopyService.FieldInformation information = new
SharePoint2007CopyService.FieldInformation();
SharePoint2007CopyService.FieldInformation[] info = { information };
// To receive the result Xml.
SharePoint2007CopyService.CopyResult[] result;
// Create the Copy web service instance configured from the web.config file.
SharePoint2007CopyService.CopySoapClient
CopyService2007 = new CopySoapClient("CopySoap");
CopyService2007.ClientCredentials.Windows.ClientCredential =
CredentialCache.DefaultNetworkCredentials;
CopyService2007.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Delegation;
CopyService2007.CopyIntoItems(destinationUrl, destinationUrls, info, fileData, out result);
if (result[0].ErrorCode != SharePoint2007CopyService.CopyErrorCode.Success)
{
// ...
}
}
Another option is to use plain ol' HTTP PUT:
WebClient webclient = new WebClient();
webclient.Credentials = new NetworkCredential(_userName, _password, _domain);
webclient.UploadFile(remoteFileURL, "PUT", FilePath);
webclient.Dispose();
Where remoteFileURL points to your SharePoint document library...
There are a couple of things to consider:
Copy.CopyIntoItems needs the document to be already present at some server. The document is passed as a parameter of the webservice call, which will limit how large the document can be. (See http://social.msdn.microsoft.com/Forums/en-AU/sharepointdevelopment/thread/e4e00092-b312-4d4c-a0d2-1cfc2beb9a6c)
the 'http put' method (ie webdav...) will only put the document in the library, but not set field values
to update field values you can call Lists.UpdateListItem after the 'http put'
document libraries can have directories, you can make them with 'http mkcol'
you may want to check in files with Lists.CheckInFile
you can also create a custom webservice that uses the SPxxx .Net API, but that new webservice will have to be installed on the server. It could save trips to the server.
public static void UploadFile(byte[] fileData) {
var copy = new Copy {
Url = "http://servername/sitename/_vti_bin/copy.asmx",
UseDefaultCredentials = true
};
string destinationUrl = "http://servername/sitename/doclibrary/filename";
string[] destinationUrls = {destinationUrl};
var info1 = new FieldInformation
{
DisplayName = "Title",
InternalName = "Title",
Type = FieldType.Text,
Value = "New Title"
};
FieldInformation[] info = {info1};
var copyResult = new CopyResult();
CopyResult[] copyResults = {copyResult};
copy.CopyIntoItems(
destinationUrl, destinationUrls, info, fileData, out copyResults);
}
NOTE: Changing the 1st parameter of CopyIntoItems to the file name, Path.GetFileName(destinationUrl), makes the unlink message disappear.
I've had good luck using the DocLibHelper wrapper class described here: http://geek.hubkey.com/2007/10/upload-file-to-sharepoint-document.html
From a colleage at work:
Lazy way: your Windows WebDAV filesystem interface. It is bad as a programmatic solution because it relies on the WindowsClient service running on your OS, and also only works on websites running on port 80. Map a drive to the document library and get with the file copying.
There is additionally a web service to upload files, painful but works all the time.
I believe you are able to upload files via the FrontPage API but I don’t know of anyone who actually uses it.
Not sure on exactly which web service to use, but if you are in a position where you can use the SharePoint .NET API Dlls, then using the SPList and SPLibrary.Items.Add is really easy.

Resources