I have a wpf application which is using a dll of a class library. I am unable to access the app.config value in the class library
How I'm trying to access app.config:
ConfigurationSettings.AppSettings["conStr"].ToString();
this is returning a null value
using System.Configuration is also added .
Why don't you just put that value in the Main Project ?
If you're calling the class library from the Main Project. Then the code in the class library uses the AppConfig defined inside the main project.
It is a common practice to have the connection string in the AppConfig for the Main Project and not inside the Class Library.
I recomend to use your own class for save Class Library settings. Something like this:
public class GlobalSettings
{
public double RedFiber { get; set; }
public double GreenFiber { get; set; }
public double BlueFiber { get; set; }
public bool DeleteMinorViews { get; set; }
public static GlobalSettings Load()
{
try
{
return JsonConvert.DeserializeObject<GlobalSettings>(File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YOUR_APP_NAME\\"));
}
catch ()
{
return DefaultSettings;
}
}
public void Save()
{
File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YOUR_APP_NAME\\", JsonConvert.SerializeObject(this, Formatting.Indented));
}
private static readonly GlobalSettings DefaultSettings = new GlobalSettings()
{
RedFiber = 0,
GreenFiber = 255,
BlueFiber = 0,
DeleteMinorViews = true,
};
}
I had the same issue. Try adding a settings file for your class library to store your values. The value will be stored in the app.config but accessed using the settings file.
This post explains better: Can a class library have an App.config file?
This post goes into more detail about settings files: Best practice to save application settings in a Windows Forms Application
If you prefer not to do the above you can also move your data to the main projects App.config file and it should work.
try
ConfigurationManager.AppSettings["conStr"].ToString();
If the does not work post your App.Config
ConfigurationSettings.AppSettings is obsolete
Related
I have:
a Dto.Library (.Net 5 Library)
a SharedResourceLibrary with Resource.resx (.Net 5 Library)
How can i use the Resource File Messages in conjunction with Data Annotation in my DTO.Library?
The ErrorMessage should be the text from the resx files:
public class MeterForCreationDto
{
[Required(ErrorMessage = "Name must not be empty!")]
public string Name { get; set; }
[Required(ErrorMessage = "Unit must not be empty!")]
public string Unit { get; set; }
}
SharedResourceLibrary: looks like this answer #Shiran Dror
You can create a custom attribute for the properties. Something like this:
public class LocalizedDisplayNameAttribute: DisplayNameAttribute
{
public LocalizedDisplayNameAttribute(string resourceKey)
: base(GetMessageFromResource(resourceId))
{ }
private static string GetMessageFromResource(string resourceKey)
{
// return the translation out of your .rsx files
}
}
and then you need to add
public class MeterForCreationDto
{
[LocalizedDisplayName("Name")]
public string Name { get; set; }
[LocalizedDisplayName("Unit")]
public string Unit { get; set; }
}
but you need to add exactly the same key in the attribute which is in your .rsx file. If your searching for "asp.net localizeddisplayname" there are a lot of different sites with examples.
Some help for creating custom attributes:
https://learn.microsoft.com/en-gb/dotnet/standard/attributes/writing-custom-attributes
Hopefully, it helps. :)
you can use:
[Required(ErrorMessageResourceName ="NameInRecourseFile",ErrorMessageResourceType =typeof(RecourseFileName))]
also u need to make the Recourse file public from this menu:
finally u need to have a default Resource file[for your default culture] Default resource file name shouldn't have any specific culture (.en،.fr،....)
SharedService.en.resx => SharedService.resx note .en is the default culture in your app
so it will like these:
SharedService.resx[for your default culture]
SharedService.ar.resx
SharedService.fr.resx
Hope this helped you.
Best wishes.
I'm working on a small WPF app to help me with file organisation. The class I store most of my data in is Project and it contains most of the data the app uses. Therefore, it has a lot of properties which I need to be saved and loaded from a file (around 20, using few as an example)
public DateTime Start { get; set; }
public DateTime End { get; set; }
public Int32 Count { get; set; }
public String Name { get; set; }
public HashSet<String> Files { get; set; }
As far as I know, loading an object can be done in 2 main ways:
I.
Project.cs
public Project Load( String file ) {
Project project = json( file ); //to shorten the question
return project;
}
MainWindow
Project project = new Project();
project = project.Load( file );
II.
Project.cs
public void Load( String file ) {
Project project = json( file );
Start = project.Start;
End = project.End;
Count = project.Count;
Name = project.Name;
Files = project.Files;
}
MainWindow
Project project = new Project();
project.Load( file );
Can I somehow still use void Load() function, but assign the whole object at once?
I tried using this = project;, but it is read-only.
Json .net has a method,
Quick and dirty way to do it using reflection
var project = Json(file); //to shorten the question
foreach (var prop in this.GetType().GetProperties())
{
prop.SetValue(this, prop.GetValue(project));
}
return project;
More performant way using compilation this one is more advanced.
But this looks like somewhat wrong in general when using wpf you should be using some MVVM pattern and the project should be the binding context of your view and you can set the created object from json with out making a copy of the object.
I have imported a third-party WSDL (via Service Reference) into my Console Application project in order to send and receive data through Web Services. In order to get this to function appropriately, I have had to add some code to the Reference.cs file associated to the Web Service. While this works, if an update is made to the WSDL, and I re-import/generate that Service Reference, that work-around code will go away.
In order to get around this, I have saved the necessary code-changes to an external text file saved within the project.
I'm curious if anyone knows of a way that I could write these changes into a their own separate class, outside of the Service Reference, and yet, still be referenced by the Service Reference, thus using the "correct" code needed to send/receive from the Web Service.
I have two classes (not included in the generated code) that I am able to reference in the generated code after separating them into their own .cs file and referencing the namespace used by the Service Reference.
What I would like to do, if possible, is the following:
Overall Goal:
Add custom code to code generated by importing a third-party WSDL as a Service Reference, that way when the WSDL is updated by the third-party, another developer would not have to necessarily remember to dive into the Reference.cs file of the Service Reference, and replace/add specific code.
To achieve this goal, I need to be able to:
Replace an existing property and associated field of the generated
partial class, with a customized version (see Snippet #1 below).
Replace an existing generated partial class with a customized version of the class, having a different attribute definition and slightly different property/field definitions.
Snippet #1
Replace the following:
private byte[] bulkExchangeFileField;
[System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common", DataType = "base64Binary", Order = 0)]
public byte[] BulkExchangeFile
{
get { return this.bulkExchangeFileField; }
set
{
this.bulkExchangeFileField = value;
this.RaisePropertyChanged("BulkExchangeFile");
}
}
with this version of the properties/fields that worked once I altered the generated code:
private BulkExchangeFileType bulkExchangeFileField;
[System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:us:gov:treasury:irs:common", Order = 0)]
public BulkExchangeFileType BulkExchangeFile
{
get { return this.bulkExchangeFileField; }
set
{
this.bulkExchangeFileField = value;
this.RaisePropertyChanged("BulkExchangeFile");
}
}
Use extension methods and/or overload the properties in an inhered class, so your code will not be replaced.
To overload the properties you just need to declare it with the word new before public like in : new public BulkExchangeFileType BulkExchangeFile, so when you use the object it will call your properties instead the ones defined by the web service
and here is how to create extention methods https://msdn.microsoft.com/library/bb383977.aspx
class Program
{
static void Main(string[] args)
{
InheredClass test = new InheredClass(); // Do this
BaseClass test2 = new InheredClass(); // don't do this
Console.WriteLine(test.MyProperty.GetType());
Console.WriteLine(test2.MyProperty.GetType());
Console.Read();
}
class BaseClass
{
public int MyProperty { get; set; }
}
class InheredClass : BaseClass
{
new public decimal MyProperty { get; set; }
}
}
I try to save some application data using ApplicationSettingsBase class's Save method. I have a net 2.0 exe (BugTest.exe) and a net 2.0 dll (MyLibrary.dll). Exe is using dll (references it). My main exe code is like that:
public class ApplicationSettings : ApplicationSettingsBase
{
[UserScopedSetting]
[DefaultSettingValue(null)]
public Settings Settings
{
get
{
return ((Settings)this["Settings"]);
}
set
{
this["Settings"] = value;
}
}
[UserScopedSetting]
[DefaultSettingValue(null)]
public LibrarySettings LibrarySettings
{
get
{
return ((LibrarySettings)this["LibrarySettings"]);
}
set
{
this["LibrarySettings"] = value;
}
}
}
public class Settings
{
public string FirstValue { get; set; }
public string LastValue { get; set; }
}
private void btnSave_Click(object sender, EventArgs e)
{
Settings settings = new Settings {FirstValue = "1", LastValue = "2"};
LibrarySettings librarySettings = new LibrarySettings { LibrarySettings1Value = "1", LibrarySettings2Value = "2" };
ApplicationSettings applicationSettings = new ApplicationSettings {Settings = settings, LibrarySettings = librarySettings};
applicationSettings.Save();
}
And MyLibrary.dll code is:
public class LibrarySettings
{
public string LibrarySettings1Value { get; set; }
public string LibrarySettings2Value { get; set; }
}
It's important for me to use pre-built xmlSerialization dlls for my project. So, then I add “$(FrameworkSDKDir)\Bin\sgen” /a:"$(TargetPath)" /force Post-built event command line (both for exe and dll). Then I got two xmlSerialization dll on my release directory: (BugTest.XmlSerializers.dll and MyLibrary.XmlSerializers.dll)
I start my application and start process monitor. Everything is ok and my application settings are saved succesfully. And I see that csc.exe (run time compiler) never run during serialization. It's also important for me to making Xmlserialization without csc.exe. So everything is well for me.
Also on my project I've to merge BugTest.exe and Mylibrary.dll. So I use ILMerge and merged BugTest.exe and MyLibrary.dll. Output is BugTest.exe. (BugTest.XmlSerializers.dll and MyLibrary.XmlSerializers.dll are not merged.) When I run and click save button of this merged BugTest.exe, saving application data to file is possible again but process monitor screen alert me that this xmlserialization maked by csc.exe. BugTest.XmlSerializers.dll and MyLibrary.XmlSerializers.dll are in the same directory with BugTest.exe but why my application using csc.exe for XmlSerialization this time instead of XmlSerializers.dlls ?
How can I force merged executable to use XmlSerializers.dlls ?
NOTE: Because of OOP design, I shouldn't carry LibrarySettings class codes from MyLibrary.dll to the BugTest.exe codes.
I've just solved this problem by changing order of some processes.
If I compile the project without generating XMLSerialization dlls and then merge BugTest.exe and MyLibrary.dll as a new BugTest.exe and then generate BugTest.XmlSerialization.dll from this new BugTest.exe (using sgen) then my application works perfectly.
This post http://blog.bits-in-motion.com/2009/11/xmlserializers-moduleversionid-ilmerge.html is very useful for my solution.
I have this code in my asp.net app:
String appPath = HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath);
String path = appPath + "\\Database\\SAMPLE.BIN";
I want to movie it to a class library, which then will be referenced by multiple projects.
The thing is that HttpContext.Current.Request.ApplicationPath is referencing the running app and not the class lib.
How do I put the SAMPLE.BIN inside the class lib, so that I don't have to duplicate it in all referencing projects?
EDIT:
At the end I need to be able to:
myobject.DatabasePath = appRoot + "\\Database\\SAMPLE.BIN";
You have 2 choices:
Either you pass the value as a parameter to your new library:
public class MyNewLibrary {
private string _path { get; set; }
public MyNewLibrary(string path)
{
this.path = path;
}
}
or you import the System.Web reference and use the HttpContext at will.