GetFileFromPathAsync giving "The parameter is incorrect" exception - exception

I've started to get into Windows Universal Platform programming (Windows 10, VS2015, c#) and hitting some basic issues..
I have a subfolder in MusicLibrary with a file test.txt in it. At the moment I am forcing GetFileFromPathAsync to be non asych (I'm in early stage of converting an old app to new target so asynch will come in later). Based on some examples the following code should work
string parentPath = returnStorage(_location).Path;
string filePath = Path.Combine(parentPath, _filename);
StorageFile _file = StorageFile.GetFileFromPathAsync(filePath).AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
But I'm getting the exception "The parameter is incorrect" but I cannot understand why
_filename = "ggmptest_04a\\test.txt"
parentPath = ""
_location is musicLibrary
Elsewhere in my code I am able to create subfolders and files to musicLibrary and list files there with GetItemsAsync.. But this GetFileFromPathAsync call fails me..
Please, what is the obvious that everybody else sees immediately -- but evades now my eyes.?

GetFileFromPathAsync throws ArgumentException if the provided path is not an absolute path.
In your case, seems like that the filePath contains a relative path since parentPath is an empty string and combining it with _filename will result a relative path.

Related

Using a relative path for File() in Flutter

I am working in Flutter and trying to open a json file in my assets folder. I found I can use the File() method, but it only seems to take an absolute path. Is there a way I can convert this to a relative path? I've tried using the relative path to the file already, but it returns an error saying no such file.
Here is the code so far. Basically I want to get the json file, and return it as a string (in the function readFileSync() below). Then I use that data to create a List object. If there's a better way to read a file into Flutter, I'm open to that too!
List<Answers> myFunction2() {
String arrayObjsText = readFileSync();
//print(arrayObjsText);
var tagObjsJson = jsonDecode(arrayObjsText)['tags'] as List;
var tagObjs =
tagObjsJson.map((tagJson) => Answers.fromJson(tagJson)).toList();
return tagObjs;
}
String readFileSync() {
String contents = new File(
'/Users/pstumbaugh/Documents/Computer Science/CS492 Mobile Dev/Dart-Flutter-CallMeMaybe/project3/assets/answers.json')
.readAsStringSync();
return contents;
}
I don't know much about how Futures work. I tried with those, but it seems like it always returns a Future and I'm not sure how to unpack that down to just a string without having to make everything async functions, which then led to problems when I try to get the List in my widgets on the main page...
You should to get assets not from relative path from your PC. When you install an app for a device or a emulator/simulator, it is can't access files on your computer. In few words, you can do it with loadString method from flutter/services.dart package (it is in Flutter SDK by default):
import 'package:flutter/services.dart' show rootBundle;
final data = rootBundle.loadString('assets/answers.json');
And make sure that you declared assets in pubspec.yaml config. Here is an official tutorial for how to work with assets.

Can you preview ASP.NET Core's appsettings.json environment overrides?

In ASP.NET Core, the JsonConfigurationProvider will load configuration from appsettings.json, and then will read in the environment version, appsettings.{Environment}.json, based on what IHostingEnvironment.EnvironmentName is. The environment version can override the values of the base appsettings.json.
Is there any reasonable way to preview what the resulting overridden configuration looks like?
Obviously, you could write unit tests that explicitly test that elements are overridden to your expectations, but that would be a very laborious workaround with upkeep for every time you change a setting. It's not a good solution if you just wanted to validate that you didn't misplace a bracket or misspell an element name.
Back in ASP.NET's web.config transforms, you could simply right-click on a transform in Visual Studio and choose "Preview Transform". There are also many other ways to preview an XSLT transform outside of Visual Studio. Even for web.config parameterization with Parameters.xml, you could at least execute Web Deploy and review the resulting web.config to make sure it came out right.
There does not seem to be any built-in way to preview appsettings.{Environment}.json's effects on the base file in Visual Studio. I haven't been able to find anything outside of VS to help with this either. JSON overriding doesn't appear to be all that commonplace, even though it is now an integral part of ASP.NET Core.
I've figured out you can achieve a preview with Json.NET's Merge function after loading the appsettings files into JObjects.
Here's a simple console app demonstrating this. Provide it the path to where your appsettings files are and it will emit previews of how they'll look in each environment.
static void Main(string[] args)
{
string targetPath = #"C:\path\to\my\app";
// Parse appsettings.json
var baseConfig = ParseAppSettings($#"{targetPath}\appsettings.json");
// Find all appsettings.{env}.json's
var regex = new Regex(#"appsettings\..+\.json");
var environmentConfigs = Directory.GetFiles(targetPath, "*.json")
.Where(path => regex.IsMatch(path));
foreach (var env in environmentConfigs)
{
// Parse appsettings.{env}.json
var transform = ParseAppSettings(env);
// Clone baseConfig since Merge is a void operation
var result = (JObject)baseConfig.DeepClone();
// Merge the two, making sure to overwrite arrays
result.Merge(transform, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Replace
});
// Write the preview to file
string dest = $#"{targetPath}\preview-{Path.GetFileName(env)}";
File.WriteAllText(dest, result.ToString());
}
}
private static JObject ParseAppSettings(string path)
=> JObject.Load(new JsonTextReader(new StreamReader(path)));
While this is no guarantee there won't be some other config source won't override these once deployed, this will at least let you validate that the interactions between these two files will be handled correctly.
There's not really a way to do that, but I think a bit about how this actually works would help you understand why.
With config transforms, there was literal file modification, so it's easy enough to "preview" that, showing the resulting file. The config system in ASP.NET Core is completely different.
It's basically just a dictionary. During startup, each registered configuration provider is run in the order it was registered. The provider reads its configuration source, whether that be a JSON file, system environment variables, command line arguments, etc. and builds key-value pairs, which are then added to the main configuration "dictionary". An "override", such as appsettings.{environment}.json, is really just another JSON provider registered after the appsettings.json provider, which obviously uses a different source (JSON file). Since it's registered after, when an existing key is encountered, its value is overwritten, as is typical for anything being added to a dictionary.
In other words, the "preview" would be completed configuration object (dictionary), which is composed of a number of different sources, not just these JSON files, and things like environment variables or command line arguments will override even the environment-specific JSON (since they're registered after that), so you still wouldn't technically know the the environment-specific JSON applied or not, because the value could be coming from another source that overrode that.
You can use the GetDebugView extension method on the IConfigurationRoot with something like
app.UseEndpoints(endpoints =>
{
if(env.IsDevelopment())
{
endpoints.MapGet("/config", ctx =>
{
var config = (Configuration as IConfigurationRoot).GetDebugView();
return ctx.Response.WriteAsync(config);
});
}
});
However, doing this can impose security risks, as it'll expose all your configuration like connection strings so you should enable this only in development.
You can refer to this article by Andrew Lock to understand how it works: https://andrewlock.net/debugging-configuration-values-in-aspnetcore/

Box API .NET SDK: "pad block corrupted" exception when instantiating BoxJWTAuth

I'm using the Box SDK for .NET and just trying to get started authenticating using the Java Web Token workflow. I'm using code that's pretty much the same as the code sample that's included in the SDK's code examples.
var jwtPrivateKey = File.ReadAllText("private_key.pem");
var boxConfig = new BoxConfig(ClientId, ClientSecret, EnterpriseId, jwtPrivateKey, JwtPrivateKeyPassword, JwtPublicKeyId);
var boxJwt = new BoxJWTAuth(boxConfig);
But at that last line I'm getting an exception that says "pad block corrupted". The stack trace seems to indicate that it involves reading the private key, but I don't see what I could be doing wrong considering this is basically the same as the code sample (https://github.com/box/box-windows-sdk-v2/blob/master/Box.V2.Samples.JWTAuth/Program.cs).
Any ideas?
After re-generating the private key with Cygwin, things are working for me.
I believe what happened was I opened the private key in Notepad or something, then saved it in some format it didn't like (maybe changed encoding to UTF-8, or saved it with Windows-style line breaks).

Design time instantiation issues when accessing xml file using XDocument.Load

In my windows store app using the Visual Studio 2012 designer I want to be able to load some model objects for the designer. I've done this plenty of times before where I supply a xaml file using the ms-appx:/// uri without error. However, for this project I need to be able to instantiate a class and have it convert raw xml of a different format into my model objects.
I'm using the following xaml to instantiate my class for the designer:
d:DataContext="{Binding Source={d:DesignInstance Type=model:Walkthroughs, IsDesignTimeCreatable=True}}"
In my Walkthroughs class had code that did this initially:
public Walkthroughs()
{
if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
AppDataLoader.LoadWalkthroughs(this, XDocument.Load("ms-appx:///SampleData/walkthroughs.xml"));
}
I first ran into an issue where the XDocument.Load did not understand the ms-appx:/// uri so I modified my code to something very simplistic:
AppDataLoader.LoadWalkthroughs(this, XDocument.Load(#"C:\walkthroughs.xml"));
Now I get access to path '' is denied.
I've tried several directories as well to no avail. I'm even running Visual Studio as an Administrator. If I remove the prefix altogether I get the following error:
Could not find file 'C:\Users\{me}\AppData\Local\Microsoft\VisualStudio\11.0\Designer\ShadowCache\omxyijbu.m4y\yofsmg1x.avh\walkthroughs.xml'.
Has anyone been able to load files from the file system when the designer instantiates objects?
Thanks,
-jeff
XDocument.Load(string uri) seems to have problems with loading Project resources from ms-appx:/
Regarding your second approach: Direct access to "C:" is not permitted. Ther is only a handful of special folders that you can access. Check out my workaround for this (my xml file is within the Assets folder of my project:
var storageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
storageFolder = await storageFolder.GetFolderAsync("Assets");
var xmlFile = await storageFolder.GetFileAsync("data.xml");
var stream = await xmlFile.OpenReadAsync();
var rdr = new StreamReader(stream.AsStream(), System.Text.Encoding.GetEncoding("ISO-8859-1")); //needed if you have "ä,ß..." in your xml file
var doc = XDocument.Load(rdr);

grails base.dir system property

I have a simple grails file upload app.
I am using transferTo to save the file to the file system.
To get the base path in my controller I am using
def basePath = System.properties['base.dir'] // HERE IS HOW I GET IT
println "Getting new file"
println "copying file to "+basePath+"/files"
def f = request.getFile('file')
def okcontents = ['application/zip','application/x-zip-compressed']
if (! okcontents.contains(f.getContentType())) {
flash.message = "File must be of a valid zip archive"
render(view:'create', model:[zone:create])
return;
}
if(!f.empty) {
f.transferTo( new File(basePath+"/files/"+zoneInstance.title+".zip") )
}
else
{
flash.message = 'file cannot be empty'
redirect(action:'upload')
}
println "Done getting new file"
For some reason this is always null when deployed to my WAS 6.1 server.
Why does it work when running dev but not in prod on the WAS server? Should I be accessing this information in a different way?
Thanks j,
I found the best dynamic solution possible. As a rule I never like to code absolute paths into any piece of software. Property file or no.
So here is how it is done:
def basePath = grailsAttributes.getApplicationContext().getResource("/files/").getFile().toString()
grailsAttributes is available in any controller.
getResource(some relative dir) will look for anything inside of the web-app folder.
So for example in my dev system it will toString out to "C:\WORKSPACEFOLDER\PROJECTFOLDER\web-app\ with the relative dir concated to the end
like so in my example above
C:\WORKSPACEFOLDER\PROJECTFOLDER\web-app\files
I tried it in WAS 6.1 and it worked in the container no problems.
You have to toString it or it will try to return the object.
mugafuga
There's a definitive way...
grailsApplication.parentContext.getResource("dir/or/file").file.toString()
Out of controllers (ex. bootstrap)? Just inject..
def grailsApplication
Best regards!
Grails, when it's run in dev mode, provides a whole host of environment properties to its Gant scripts and the app in turn, including basedir.
Take a look at the grails.bat or grails.sh script and you will find these lines:
Unix: -Dbase.dir="." \
Windows: set JAVA_OPTS=%JAVA_OPTS% -Dbase.dir="."
When these scripts start your environment in dev mode you get these thrown in for free.
When you take the WAR and deploy you no longer use these scripts and therefore you need to solve the problem another way; you can either
Specify the property yourself to the startup script for the app server, eg: -Dbase.dir=./some/dir .. however
... it usually makes more sense to use the Grails Config object which allows for per-environment properties
Another option:
def basePath = BuildSettingsHolder.settings.baseDir