.Net 6 WinForms - Unable to get configuration section value - winforms

I have a .Net 6 WinForms application and am trying to access some sections in the App.config (myapp.dll.config after build).
I have a class defined with the properties MyProp { public String runDate {get;set;} and app looking for a section called in the file.
I have used ConfigurationBuild().SetBasePath(AppContext.BasePath().AddXMLFile("myapp.dll.config").Build() returning an IConfiguration object called config.
The issue is that when I call either config.GetSection("MyProp").Bind(props) or config.GetSection("MyProp").Get(); It returns the entity but with the value null.
Note: if I change the settings section to bob then both values work. However, my config section is in the old web.config format and uses key/value pairs.
I recognize that when using an XML Provider, the key and value become attributes of the XElement, so its [the xelement] will have a value set to nothing. I was wondering if AddXmlFile was the correct provider to use for this?

Related

Why I am able to re-create java.lang package and classes?

I am just playing with package structure. And to my surprise I can bypass the default classes by creating my package and class name with that name.
For ex:
I created a package called java.lang and Class is Boolean. When I import java.lang.Boolean it's not the JDK's version of Boolean. It's mine. It's just showing the methods of Objects which every object java have.
Why so ? Why I am allowed to create the package java.lang? And the program runs fine.
Another baffle is if I create a Class with name Object and try to runs the program then an exception
java.lang.SecurityException: Prohibited package name: java.lang
at java.lang.ClassLoader.preDefineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
Why is this behaviour ? is this a bug or normal behaviour ?
The restriction on java.lang classes is a runtime restriction, not a compile time one.
The JVM actually specifically provides a mechanism for overriding classes in java.lang. You can do it using the -Xbootclasspath command line flag:
-Xbootclasspath:bootclasspath
Specifies a semicolon-separated list of directories, JAR files, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java platform JDK.
Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed because doing so would contravene the Java Runtime Environment binary code license.
-Xbootclasspath/a:path
Specifies a semicolon-separated path of directories, JAR files, and ZIP archives to append to the default bootstrap class path.
-Xbootclasspath/p:path
Specifies a semicolon-separated path of directories, JAR files, and ZIP archives to add in front of the default bootstrap class path.
Do not deploy applications that use this option to override a class in rt.jar because this violates the Java Runtime Environment binary code license.
However, as I've already emphasized with bold marks, doing so is a violation of the Oracle Binary Code License Agreement for Java SE and JavaFX Technologies:
D. JAVA TECHNOLOGY RESTRICTIONS. You may not create, modify, or change the behavior of, or authorize your licensees to create, modify, or change the behavior of, classes, interfaces, or subpackages that are in any way identified as "java", "javax", "javafx", "sun", “oracle” or similar convention as specified by Oracle in any naming convention designation. You shall not redistribute the Software listed on Schedule 1.
Apart from the above, you may add whatever class you want to whatever packages you want; it's specifically discussed in the the JLS §13.3:
13.3. Evolution of Packages
A new top level class or interface type may be added to a package without breaking compatibility with pre-existing binaries, provided the new type does not reuse a name previously given to an unrelated type.
If a new type reuses a name previously given to an unrelated type, then a conflict may result, since binaries for both types could not be loaded by the same class loader.
Changes in top level class and interface types that are not public and that are not a superclass or superinterface, respectively, of a public type, affect only types within the package in which they are declared. Such types may be deleted or otherwise changed, even if incompatibilities are otherwise described here, provided that the affected binaries of that package are updated together.
Answer to SecurityException related question:
SecurityManger throws this RuntimeException while your classloader calling defineClass method and encountered specified class(your "custom class") name has "java.*" in it.
This is because you defined your class in "java.*" package and as per ClassLoader's documentation this is not allowed.
defineClass( )
..
The specified name cannot begin with "java.", since all classes in the "java.* packages can only be defined by the bootstrap class loader. If name is not null, it must be equal to the binary name of the class specified by the byte array "b", otherwise a NoClassDefFoundError will be thrown.
Throws:
..
SecurityException - If an attempt is made to add this class to a package that contains classes that were signed by a different set of certificates than this class, or if name begins with "java.".
For your testing, try creating java.test package and define one Custom class (names doesn't matter; like Object..). In this case as well you will get same SecurityException.
package java.test;
public class Test {
public static void main(String[] args) {
System.out.println("This is Test");
}
}
This is not Bug.
Behaviour beacause of:
When the Java Virtual Machine (JVM) tries to load our class, it recognizes its package name as invalid and thus, a SecurityException is thrown.
The SecurityException indicates that a security violation has occurred an thus, the application cannot be executed.
public class SecurityException
extends RuntimeException
Thrown by the security manager to indicate a security violation.
please use different package name it not for only language package of java.it covers all package not gives permissions to override in build classes and packages of java.
By Changing this we can create or override same package and class:
a/j2ee.core.utilities/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiers.java
b/j2ee.core.utilities/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiers.java
**if (packageName.startsWith(".") || packageName.endsWith(".")) {// NOI18N
return false;
}
if(packageName.equals("java") || packageName.startsWith("java.")) {//NOI18N
return false;
}**
String[] tokens = packageName.split("\\."); //NOI18N
if (tokens.length == 0) {
return Utilities.isJavaIdentifier(packageName);
a/j2ee.core.utilities/test/unit/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiersTest.java b/j2ee.core.utilities/test/unit/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiersTest.java
assertFalse(JavaIdentifiers.isValidPackageName(" "));
assertFalse(JavaIdentifiers.isValidPackageName("public"));
assertFalse(JavaIdentifiers.isValidPackageName("int"));
assertFalse(JavaIdentifiers.isValidPackageName("java"));
assertFalse(JavaIdentifiers.isValidPackageName("java.something"));
}
Your problem with java.lang.Boolean as your Boolean Class, and not the Object one is simple to explain.
The Object class is the root of every other classes you can find, use, or even create. Which means that if you could have the ability to override it, not a single class, method, or whatever you want to use would work, since every of them depends on that root class.
For the Boolean Class, it is not a boolean type, but a class for a boolean type. And since nothing depends on it, it is then possible to override it.
A better way to understand this problem, is to look at this link: [http://docs.oracle.com/javase/7/docs/api/overview-tree.html] You will notice that every kind of package, containing every kind of java classes, depends on the Object Class.
So the security exception you encountered is like a "life savior" for your program.
If I'm wrong about your question, other persons may find a more appropriate answer to it. :)

When using Ado.Net interfaces such as IDbDataParameter is it correct to still prefix the ParameterName with "#"

In a seperate post, Is it necessary to add a # in front of an SqlParameter name?, a discussion is had about prefixing the ParameterName with the "#" sign.
If you are abstracting all of your ADO access behind interfaces such as IDbCommand and using IDbCommand.CreateParameter() to return instances of IDbDataParameter, is it still correct to prefix the ParameterName with "#".
My gut feeling is no, since the # is required by SqlServer and the point of using interfaces to remove the implementation details.
I'd also suggest this is perhaps why the undocumented feature of automatically checking for the prefix character exists, if you are only using ADO.NET via interfaces and are removed from knowing exactly what kind of database you are using ?
Simply as a demonstration that you need to take this little detail into account even when abstracting, if you look at Microsoft's Data Access Block which for years has provided ADO abstraction using the System.Data.Common base, you'll see that they address this very issue by including virtual method in the abstract base class Database that is then overridden by the provider specific derived classes.
So the base class Database.cs has this method:
/// <summary>Builds a value parameter name for the current database.</summary>
/// <param name="name">The name of the parameter.</param>
/// <returns>A correctly formated parameter name.</returns>
public virtual string BuildParameterName(string name){ return name; }
(if the provider uses positional parameters or has no need of a prefix, there is nothing more to override)
and then the SqlClient specific provider implementation SqlDatabase.cs overrides it as such:
/// <summary>Gets the parameter token used to delimit parameters for the SQL Server database.</summary>
protected char ParameterToken{ get { return '#'; } }
public override string BuildParameterName(string name)
{
if (name == null) throw new ArgumentNullException("name");
if (name[0] != ParameterToken)
return name.Insert(0, new string(ParameterToken, 1));
return name;
}
Notice that this implementation allows the calling code to use sql parameter names with the '#' prefix or not, thus freeing the devs from having to know/remember what the api actually does to the name under the covers.
I don't use the DAAB directly, but their overall approach to abstracting behind the System.Data and System.Data.Common interfaces and classes is a great guideline for small data access api's.

Error Application cast in WPF

i have 2 projects in my solution (main is A.WPF and secondary is B.WPF)
when i'm trying to access variables inside my App.xaml.cs in B.WPF:
filename = ((App)Application.Current).ErrorLogFileName;
i get the following error:
Unable to cast object of type 'A.App' to type 'B.App'.
i also tried the following:
filename = ((B.App)Application.Current).ErrorLogFileName;
but still the same error...
the definition in B.App is:
private string _errorLogFileName = "error log.xml";
public string ErrorLogFileName
{
get { return _errorLogFileName; }
}
please assist...
Looks like you need to do:
filename = ((A.App)Application.Current).ErrorLogFileName;
The error is saying the type is A.App, yet in both cases you are trying to cast to B.App.
There can only be one current application also.
Application.Current refers to the current application. The only way to be allowed to cast the current App to another App-type is when the other App-type is a base class of the current App-type.
Are A.App and B.App siblings or is B.App a base class of A.App?
If you don't want B to have a reference to A (or can't as you want A to reference B and that would cause a circular reference), then you need a common type defined in a third assembly that both A and B reference. In our implementation we tend to have a ConfigurationData type that is in a separate project referenced by both Wpf projects, e.g.
public static class ConfigurationData
{
private static string _errorLogFileName = "error log.xml";
public string ErrorLogFileName
{
get { return _errorLogFileName; }
}
}
Another approach would be to define an Interface for your ErrorLogFileName property in a 3rd assembly that both A and B reference, and then implement that interface on your Wpf Application class - A and B would then both be able to cast to that type. If you wanted your A project to set the values on that at runtime, you could make the ErrorLogFileName a read-write property instead and initialize it in your application startup.
I personally prefer using a separate ConfigurationData type from the Wpf app object for this kind of stuff (ErrorLogFileName etc.) as it can then also be used for code that might execute in a unit test and therefore might not be running under a Wpf application - it also avoids having to do casts all over the place (ConfigurationData.ErrorLogFileName instead of ((IAppConfigurationData)Application.Current).ErrorLogFileName.
BTW, if you have an Application object in both assemblies it sounds like you might have both assemblies configured to build as Output type: Windows Application in your project properties. You should only really have one assembly that is configured as the Windows Application and the rest should be Class Library to avoid confusing numbers of Application classes being generated - only the one in the main EXE (and it's related resources) will get created at runtime.

How to read values from 'WPF' project App.config file from within class library

I have a WpfApplication project (Visual Studio 2008) with an app.config generated from entering 'Name' and 'Value' pairs in the Settings.settings file (and therefore generating 'applicationSettings' elements rather than 'appSettings' elements).
I have added a class1 class library project in the same Visual Studio solution.
** I have added the WpfApplication app.config file to the class1 project using "add existing item and then add as link".** since found out this is unneccassary (i.e. string a = ConfigurationManager.AppSettings.Get("key1"); below works without this)
I want to read the values within app.config from class1 and have explored the following:
string s1 = Settings.Default.appsetting1;
But I do not want to reference the WpfApplication10 project from Class 1 project and so cannot get a reference to the Settings class. So this syntax only works within the WPF project.
string a = ConfigurationManager.AppSettings.Get("key1").ToString();
This does work, but only if I add the following to app.config:
<appSettings>
<add key="key1" value="1"/>
</appSettings>
Are there other ways to achieve what I want which may be better (e.g. offering type safety or being able to read the Settings class properties?
You can do the following thing:
if you need to get value from key="key1" just write this(supposing your app.config is in the correct directory).
string str=System.Configuration.ConfigurationSettings.AppSettings["key1"];

What is dbReferenceProperty?

In the python app engine docs, I see something called dbReferenceProperty. I can't understand what it is, or how it's used. I'm using the java interface to app engine, so I'm not sure if there's an equivalent.
I'm interested in it because it sounds like some sort of pseudo-join, where we can point a property of a class to some other object's value - something like if we had:
class User {
private String mPhotoUrl;
private String mPhone;
private String mState;
private String mCountry;
.. etc ..
}
class UserLite {
#ReferenceProperty User.mPhotoUrl;
private String mPhotoUrl;
}
then if we had to update a User object's mPhotoUrl value, the change would somehow propagate out to all UserLite instances referencing it, rather than having to update every UserLite object instance manually,
Thanks
A db.ReferenceProperty simply holds the key of another datastore entity, which is automatically fetched from the datastore when the property is used.
There's some additional magic where the entity that is referenced has access to a query for entities of type Foo that reference it in the special attribute foo_set.
The Java datastore API instead has owned relationships, which serve the same purpose.

Resources