How to get the Configuration App Settings file in MAUI iOS - configuration

I am converting my Xamarin Forms Application to .NET MAUI.
In existing application I am using below code which is using Xamarin.iOS to fetch the config file(App.config) which is in xml format and has app settings
public string Path
{
get
{
try
{
return System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
}
catch
{
throw new FileNotFoundException(#"File not found.");
}
}
}
But the same code doesn't work in MAUI
I tried below approach but File.OpenRead(Path) is throwing error "Data at the root level is invalid. Line 1, position 1"
App.config file is added in path Projectname/Platforms/iOS/App.config
public string Path
{
get
{
try
{
string configPath = string.Empty;
configPath = Assembly.GetEntryAssembly().Location + ".config";
AppDomain domain = System.AppDomain.CurrentDomain;
configPath = System.IO.Path.Combine(domain.SetupInformation.ApplicationBase, domain.FriendlyName + ".config");
return configPath;
}
catch
{
throw new FileNotFoundException(#"File not found.");
}
}
}
Any help is appreciated!

Since the value of Path could be obtained, you could manually checked the content to see if it is the one you want.
From the thrown error "Data at the root level is invalid. Line 1, position 1", it seems something wrong with xml data load. Some issues similar to this question indicated that it may due to BOM character, take a look at this issue.
Actually we could use appsettings.json as an alternative, see this App Configuration Settings in .NET MAUI and github project. It's really easy to read app config in this way.

Related

Swagger run locally but not on IIS, not resolving base path

I am setting up Swagger for documenting my API.
I have set up the SwaggerEndpoint with a relative path the the specification json, like you see below:
When I debug locally, everything resolves fine. But my site just runs as http://localhost:44348/index.html.
When I deploy to IIS, which is on a virtual path, it blows apart:
Note that the URL in the browser has /imaging4castapi_UAT/ as part of the path
Note that the actual request for the swagger.json is missing that base part of the path.
Here's what I've tried:
I tried removing the RoutePrefix override. But that doesn't resolve.
I tried using an application path like "~/swagger/..." but that's translated by the server on view elements like Razor pages and css and doesn't work here in Startup.
I'm struggling to understand if this is a client setup issue or something related to how my site is hosted on IIS.
Thoughts?
Try using a relative path:
setupAction.SwaggerEndpoint("../swagger/Imaging4CastApiSpecification/swagger.json", "4Cast API");
Please note answer and explanation from the following issue: SwashBuckle
Here is my Swagger config for once of PRD application. Hope it helps
public static IServiceCollection AddSwaggerConfig(this IServiceCollection services, IHostingEnvironment env,
string title, string version)
=> services.AddSwaggerGen(c =>
{
//Ensure XML Document File of project is checked for both Debug and Release mode
c.IncludeXmlComments("Your App.xml");
//Display Enum name
c.DescribeAllEnumsAsStrings();
//c.OperationFilter<AddRequiredHeaderParameter>();
//Authentication for Bearer
c.AddSecurityDefinition("Bearer",
new ApiKeyScheme
{
In = "header",
Description = "Please enter JWT with Bearer into field",
Name = "Authorization",
Type = "apiKey"
});
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{"Bearer", Enumerable.Empty<string>()}
});
c.SwaggerDoc(version, new Info
{
Title = title,
Version = version,
Description = "",
Contact = new Contact
{
Email = "Support#ABC.com",
Name = ""
}
});
});
Startup file
app.
//Swagger
.UseSwagger()
.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"./{_version}/swagger.json", Title);
});
The version is app variable from Config file which will be filtered by CI/CD
Swagger does not support Virtual Directory by default. Try and add this to your Startup.cs
app.UseSwagger(c =>
{
c.RouteTemplate = "virtual_path/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
//Include virtual directory
c.RoutePrefix = "virtual_path";// add your virtual path here.
c.SwaggerEndpoint("v1/swagger.json", "Api v1");
});
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"./v1/swagger.json", "Api v1");
});
My fix was following Killnines last comment to remove the preceding forward slash so that it looks like the following;
app.UseSwagger();
app.UseSwaggerUI(options => {
options.SwaggerEndpoint("swagger/v1/swagger.json", "Your API v1");
});

How to set response code while using json views with Grails 3

I am now in process of switching to use json view in one of my apps built with Grails 3.3
It all looks pretty simple and here is one of my controllers:
def create(ProjectCommand command) {
if (command.validate()) {
// do something with user
Project project = projectService.create(command, springSecurityService.principal.id as Long)
if (project) {
[status: HttpStatus.CREATED, project: project]
} else {
badRequest("failed to create the project")
}
}
else {
badRequest(command.errors)
}
}
Here, I assumed that the status will be used as a response status code, but it does not.
Is there an easy way to set status code of the response without explicitly going through render?
Hmmm... that was easy.
Apparently, inside the view file itself, there is a way to almost anything.
For this particular case, it is enough to do:
response.status HttpStatus.CREATED
I hope it will be useful to someone

Best way to get users folder using as-user in new Box Java SDK

Per Box example easy way to get user's root folder using below code
http://opensource.box.com/box-java-sdk/
BoxAPIConnection api = new BoxAPIConnection("your-developer-token");
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
for (BoxItem.Info itemInfo : rootFolder) {
System.out.format("[%d] %s\n", itemInfo.getID(), itemInfo.getName());
}
But if i need to access someone else info using As-user, I'm unable to use BOX SDK classes (BoxFolder, BoxFile, BoxUser...) and need to get the data only from JSON directly like below.
If i do so, i'm loosing the latest features added in the new SDK. Is it the best way? How about the performance? Is there any alternative way available?
url= new URL("https://api.box.com/2.0/folders/0");
BoxAPIRequest request = new BoxAPIRequest(api,url,"GET");
request.addHeader("As-User", "12345678");
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
Later get the folder properties using JsonObject / JsonArray. If i need the folder items, i need to loop the JsonArray like below
JsonArray entries = responseJSON.get("entries").asArray();
for (JsonValue entry : entries)
{ ....}
Unfortunately, the new Java SDK beta doesn't have built-in support for "As-User" functionality yet, which makes this kind of tricky. One workaround is to use a RequestInterceptor with your BoxAPIConnection to manually add the "As-User" header to every request.
api.setRequestInterceptor(new RequestInterceptor() {
#Override
public BoxAPIResponse onRequest(BoxAPIRequest request) {
request.addHeader("As-User", "user-id");
// Returning null means the request will be sent along with our new header.
return null;
}
}
This should let you use the rest of the SDK normally and not have to worry about doing the API requests manually. I also created an issue for adding "As-User" support.

DART lang reading JSON file saved in the client, i.e. without using a server

I'm trying to read data from JSON file, using the blow code:
void makeRequest(Event e){
var path='json/config.json';
var httpRequest= new HttpRequest();
httpRequest
..open('GET', path)
..onLoadEnd.listen((e)=>requestComplete(httpRequest))
..send('');
}
this worked very well when the app run as http:// .../ index.html, but gave the below error when trying to open it as file:///.../index.html
Exception: NetworkError: Failed to load 'file:///D:/DartApp/web/json/config.json'. main.dart:53makeRequest main.dart:53<anonymous closure>
Is there another way, other than httpRequest that can read JSON file from client side!
I understand I've 3 options, 2 of them only can use HttPRequest, which are:
saving the file of the server, and reading it from the server => can use HttpRequesit
saving the file on the server, and reading it from the client => can use HttpRequesit
saving the file on the client, and reading it from the client itself => CAN NOT use HTTPRequest
I'm searching for the way to do the 3rd option, which is like making off-line Android App using webview, or making off-line Chrome packaged app, i.e I do not want to use a server at all. thanks
thanks
If all you need is the data in the json file, you can just include that data in your .dart files (as a Map variable/constant, for example).
Map config = {
"displayName": "My Display Name",
"anotherProperty": 42,
"complexProperty": {
"value_1": "actual value",
"value_2": "another value"
}
};
If you need the actual json, you can put in a String. Something like:
const configJson = '''
{ "displayName": "My Display Name",
"anotherProperty": 42,
"complexProperty": {
"value_1": "actual value",
"value_2": "another value"
}
}
''';
The json data can be in a separate .dart file, which can be included as part of the same library (through part of ...), or imported (import 'package:mypackage/json.dart';).
If you're looking for something that you can change and the changes are persisted, you're going to need to use some sort of offline storage, which can be web storage if you're running in a browser. You can use the approach above to define inital config data, store it in web storage, and from then on read and edit it from there.
[Previous answer below, before original question was edited.]
Sorry, read "client side", thought "server side". My mistake.
If by "client side" you mean "running in a browser", and you're trying to access a json file which is on the server, then no, there isn't any other way, other than an http request. In fact, that's the only way to read any file on the server, not just json ones. (Well, I guess you could open a WebSocket and stream the content, but that doesn't seem to be a solution you're looking for.)
[Old solution below, before my mistake (server vs client) was pointed out.]
Try:
// THIS DOESN'T WORK IN A BROWSER ENVIRONMENT (aka client side)
import 'dart:io';
import 'dart:convert';
// ...
new File('json/config.json')
.readAsString()
.then((fileContents) => json.decode(fileContents))
.then((jsonData) {
// do whatever you want with the data
});
This poor example works fine in the chrome dev editor dart web app example.
Using HttpRequest.getString works fine with filename and path.
Chris has a good write for json web service stuff at
https://www.dartlang.org/articles/json-web-service/
import 'dart:html';
import 'dart:convert';
void main() {
HttpRequest.getString('json/config.json').then((myjson) {
Map data = JSON.decode(myjson);
var version = data["version"];
var element = new DivElement();
element.text = "version = $version";
document.body.children.add(element);
});
}

Play 2.0 routes file for different configurations

I have a Play 2.0 application with 3 different configurations (application.conf, test.conf and prod.conf)
Now I have a robots.txt file that should be delivered for only test.conf and for the rest environments it should give a 404 if someone tries to access it.
How can I configure my routes file to check if my application is using test.conf? Can I set some variable in test.conf that I can check in the routes file?
Something like this? (pseudo code)
#{if environment = "test"}
GET /robots.txt controllers.Assets.at(path="/public", file="robots.txt")
#{/if}
#{else}
GET /robots.txt controllers.Application.notFoundResult()
#{/else}
You can't add logic in the routes file.
I'd write a controller to serve the robots.txt file. Something like this:
In the routes file:
GET /robots.txt controllers.Application.robots
Then, in the controller, I'll test if I'm in a testing environment :
def robots = Action {
if (environment == "test") { // customize with your method
Redirect(routes.Assets.at("robots.txt"))
} else {
NotFound("")
}
}
I'm using Scala, but it can be easily translated to Java.
Edit - java sample
You can check if application is in one of three states: prod, dev or test, ie, simple method returning current state:
private static String getCurrentMode() {
if (play.Play.isTest()) return "test";
if (play.Play.isDev()) return "dev";
if (play.Play.isProd()) return "prod";
return "unknown";
}
you can use as:
play.Logger.debug("Current mode: "+ getCurrentMode());
of course in your case that's enough to use these condition directly:
public static Result robots() {
return (play.Play.isProd())
? notFound()
: ok("User-agent: *\nDisallow: /");
}