In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "various methods of reading and writing config files in .net and the differences between config files and XML files". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Next, let the editor take you to learn the various methods of reading and writing config files in .net and the differences between config files and XML files.
Config File-Custom configuration Node
Why do you want a custom configuration node?
Indeed, many people use appSetting directly when using config files, stuffing all the configuration parameters there, which is good, but if there are too many parameters, the shortcomings of this approach will be obviously exposed: the configuration parameter items in appSetting can only be accessed by key name, cannot support complex hierarchical nodes and do not support strong typing, and because they all use only this one collection. You will find that completely irrelevant parameters should also be put together!
Do you want to get rid of this problem? Custom configuration nodes will be a feasible way to solve this problem.
First, let's take a look at how to add a custom configuration node to app.config or web.config. In this blog, I will introduce four ways to customize the configuration of nodes, and the final configuration file is as follows:
At the same time, I also provide all the sample code (available for download at the end of the article). The interface of the demo program is as follows:
Config File-Property
Let's start with the simplest custom node, where each configuration value exists as an attribute:
The implementation code is as follows:
Public class MySection1: ConfigurationSection {[ConfigurationProperty ("username", IsRequired = true)] public string UserName {get {return this ["username"]. ToString ();} set {this ["username"] = value;}} [ConfigurationProperty ("url", IsRequired = true)] public string Url {get {return this ["url"]. ToString ();} set {this ["url"] = value;}
Summary:
1. Customize a class with ConfigurationSection as the base class, and add [ConfigurationProperty] to each attribute. The name string passed in the constructor of ConfigurationProperty will be used in the config file to represent the attribute name of each parameter.
two。 The value of the property should be read and written by calling this [] and saved by the base class. Please do not design the Field to save it.
3. In order to use the configuration node to be parsed, you need to register: in, and note that the name= "MySection111" corresponds to it.
Description: the following will introduce the other three configuration nodes, although a little more complex, but some of the basic things are the same as this node, so I will not repeat it later.
Config File-Element
To take a more complicated look, each configuration item exists as a XML element:
The implementation code is as follows:
Public class MySection2: ConfigurationSection {[ConfigurationProperty ("users", IsRequired = true)] public MySectionElement Users {get {return (MySectionElement) this ["users"];} public class MySectionElement: ConfigurationElement {[ConfigurationProperty ("username", IsRequired = true)] public string UserName {get {return this ["username"]. ToString ();} set {this ["username"] = value }} [ConfigurationProperty ("password", IsRequired = true)] public string Password {get {return this ["password"] .ToString ();} set {this ["password"] = value;}
Summary:
1. Customize a class with ConfigurationSection as the base class, with each attribute in addition to [ConfigurationProperty]
two。 The type is also custom, and the specific configuration properties are written in the inheritance class of ConfigurationElement.
Config File-CDATA
Sometimes the configuration parameter contains long text, such as a SQL script, or a piece of HTML code, so you need a CDATA node. Suppose you want to implement a configuration that contains two SQL scripts:
The implementation code is as follows:
Public class MySection3: ConfigurationSection {[ConfigurationProperty ("Command1", IsRequired = true)] public MyTextElement Command1 {get {return (MyTextElement) this ["Command1"];}} [ConfigurationProperty ("Command2", IsRequired = true)] public MyTextElement Command2 {get {return (MyTextElement) this ["Command2"];}} public class MyTextElement: ConfigurationElement {protected override void DeserializeElement (System.Xml.XmlReader reader, bool serializeCollectionKey) {CommandText = reader.ReadElementContentAs (typeof (string), null) as string } protected override bool SerializeElement (System.Xml.XmlWriter writer, bool serializeCollectionKey) {if (writer! = null) writer.WriteCData (CommandText); return true;} [ConfigurationProperty ("data", IsRequired = false)] public string CommandText {get {return this ["data"]. ToString ();} set {this ["data"] = value;}
Summary:
1. In the implementation, you can refer to MySection2.
two。 For each ConfigurationElement, we control how to read and write the XML, that is, to overload the method SerializeElement,DeserializeElement
Config File-Collection
Such similar configurations are all too common in ASP.NET 's HttpHandler, HttpModule. Do you want to know how to implement them? The code is as follows:
Summary:
1. To create a derived class that inherits from ConfigurationElement for the parameter items in each collection, see MySection1
two。 Create a collection class for the collection that inherits from ConfigurationElementCollection, which is mainly implemented by calling the methods of the base class.
3. When creating an inheritance class for ConfigurationSection, it is OK to create a property that represents the collection. Note the parameters of [ConfigurationProperty].
Config files-read and write
Earlier, I introduced the implementation classes of four custom configuration nodes one by one, so let's take a look at how to read and write them.
Read configuration parameters:
MySection1 mySectioin1 = (MySection1) ConfigurationManager.GetSection ("MySection111"); txtUsername1.Text = mySectioin1.UserName;txtUrl1.Text = mySectioin1.Url;MySection2 mySectioin2 = (MySection2) ConfigurationManager.GetSection ("MySection222"); txtUsername2.Text = mySectioin2.Users.UserName;txtUrl2.Text = mySectioin2.Users.Password;MySection3 mySection3 = (MySection3) ConfigurationManager.GetSection ("MySection333"); txtCommand1.Text = mySection3.Command1.CommandText.Trim (); txtCommand2.Text = mySection3.Command2.CommandText.Trim (); MySection4 mySection4 = (MySection4) ConfigurationManager.GetSection ("MySection444") TxtKeyValues.Text = string.Join ("\ r\ n", (from kv in mySection4.KeyValues.Cast () let s = string.Format ("{0} = {1}", kv.Key, kv.Value) select s) .ToArray ()
Summary: when reading a custom node, we need to call ConfigurationManager.GetSection () to get the configuration node, convert it to our defined configuration node class, and then access it in a strongly typed way.
Write configuration file:
Configuration config = ConfigurationManager.OpenExeConfiguration (ConfigurationUserLevel.None); MySection1 mySectioin1 = config.GetSection ("MySection111") as MySection1;mySectioin1.UserName = txtUsername1.Text.Trim (); mySectioin1.Url = txtUrl1.Text.Trim (); MySection2 mySection2 = config.GetSection ("MySection222") as MySection2;mySection2.Users.UserName = txtUsername2.Text.Trim (); mySection2.Users.Password = txtUrl2.Text.Trim (); MySection3 mySection3 = config.GetSection ("MySection333") as MySection3;mySection3.Command1.CommandText = txtCommand1.Text.Trim () MySection3.Command2.CommandText = txtCommand2.Text.Trim (); MySection4 mySection4 = config.GetSection ("MySection444") as MySection4;mySection4.KeyValues.Clear (); (from s in txtKeyValues.Lines let p = s.IndexOf ('=') where p > 0 select new MyKeyValueSetting {Key = s.Substring (0, p), Value = s.Substring (p + 1)}). ToList (). ForEach (kv = > mySection4.KeyValues.Add (kv)); config.Save ()
Summary: before modifying the configuration node, we need to call ConfigurationManager.OpenExeConfiguration (), and then call config.GetSection () to change to the node type we defined after getting the node, then we can modify the parameter items we define in a strongly typed way, and finally call config.Save (); it's OK.
Note:
1. Net caches the data in order to optimize the read operation of the configuration node. If you want the modified result to take effect, you also need to call ConfigurationManager.RefreshSection (".")
two。 If you are modifying web.config, you need to use WebConfigurationManager
Read and write nodes already defined in .net framework
I've been demonstrating custom nodes all the time, so how do I read nodes that are already defined in. Net framework?
If I want to read the sender in the configuration node below.
Read configuration parameters:
SmtpSection section = ConfigurationManager.GetSection ("system.net/mailSettings/smtp") as SmtpSection;labMailFrom.Text = "MailFrom:" + section.From
Write configuration file:
Configuration config = ConfigurationManager.OpenExeConfiguration (ConfigurationUserLevel.None); SmtpSection section = config.GetSection ("system.net/mailSettings/smtp") as SmtpSection;section.From = "Fish.Q.Li@newegg.com2"; config.Save ()
Xml profile
Earlier, I demonstrated how to create a custom configuration node in a config file, and those methods are only suitable for app.config or web.config. If you have more configuration parameters, or if you plan to save some data separately in the form of a configuration file, it will be more convenient to read and write the entire XML directly. For example: I have an entity class, I want to save it in the XML file, it may be multiple records, or it may be one.
Let me put it the other way around this time, if we first defined the structure of XML, which looks like this, what would I do?
Insret into.
For the above XML structure, we can first define the following class in C #, and then read and write it through serialization and deserialization.
The C# class is defined as follows:
Public class MyCommand {[XmlAttribute ("Name")] public string CommandName; [XmlAttribute] public string Database; [XmlArrayItem ("Parameter")] public List Parameters = new List (); [XmlElement] public string CommandText;} public class MyCommandParameter {[XmlAttribute ("Name")] public string ParamName; [XmlAttribute ("Type")] public string ParamType;}
With these two C # classes, it is very easy to read and write this XML. The following is the corresponding read and write code:
Private void btnReadXml_Click (object sender, EventArgs e) {btnWriteXml_Click (null, null); List list = XmlHelper.XmlDeserializeFromFile (XmlFileName, Encoding.UTF8); if (list.Count > 0) MessageBox.Show (list [0] .CommandName + ":" + list [0] .CommandText, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); private void btnWriteXml_Click (object sender, EventArgs e) {MyCommand command = new MyCommand (); command.CommandName = "InsretCustomer"; command.Database = "MyTestDb" Command.CommandText = "insret into."; command.Parameters.Add (new MyCommandParameter {ParamName = "Name", ParamType = "DbType.String"}); command.Parameters.Add (new MyCommandParameter {ParamName = "Address", ParamType = "DbType.String"}); List list = new List (1); list.Add (command); XmlHelper.XmlSerializeToFile (list, XmlFileName, Encoding.UTF8);}
Summary:
1. The most convenient way to read and write an entire XML is to use serialization deserialization.
two。 If you want a parameter to appear as Xml Property, you need to decorate it with [XmlAttribute].
3. If you want a parameter to appear as XmlElement, you need to decorate it with [XmlElement].
4. If you want to specify ElementName for a List project, you need [XmlArrayItem]
5. Each of the above three Attribute can specify a mapping alias in XML.
6. Writing XML is done through XmlSerializer.Serialize ().
7. Reading XML files is done through XmlSerializer.Deserialize.
8. For List or Array items, do not use [XmlElement], otherwise they will be promoted inline to the current class unless you define another container class.
The implementation of XmlHelper is as follows:
Public static class XmlHelper {private static void XmlSerializeInternal (Stream stream, object o, Encoding encoding) {if (o = = null) throw new ArgumentNullException ("o"); if (encoding = = null) throw new ArgumentNullException ("encoding"); XmlSerializer serializer = new XmlSerializer (o.GetType ()); XmlWriterSettings settings = new XmlWriterSettings (); settings.Indent = true; settings.NewLineChars = "\ r\ n"; settings.Encoding = encoding; settings.IndentChars = "" Using (XmlWriter writer = XmlWriter.Create (stream, settings)) {serializer.Serialize (writer, o); writer.Close () }} / / serialize an object into a XML string / Encoding / the XML string generated by serialization public static string XmlSerialize (object o, Encoding encoding) {using (MemoryStream stream = new MemoryStream ()) {XmlSerializeInternal (stream, o, encoding); stream.Position = 0 Using (StreamReader reader = new StreamReader (stream, encoding)) {return reader.ReadToEnd () }} / write an object to a file as serialized by XML / Save file path / Encoding public static void XmlSerializeToFile (object o, string path, Encoding encoding) {if (string.IsNullOrEmpty (path)) throw new ArgumentNullException ("path") Using (FileStream file = new FileStream (path, FileMode.Create, FileAccess.Write)) {XmlSerializeInternal (file, o, encoding) }} / deserialize the object from the XML string / the resulting object type / contains the object's XML string / / Encoding / deserialized object public static T XmlDeserialize (string s, Encoding encoding) {if (string.IsNullOrEmpty (s)) throw new ArgumentNullException ("s") If (encoding = = null) throw new ArgumentNullException ("encoding"); XmlSerializer mySerializer = new XmlSerializer (typeof (T)); using (MemoryStream ms = new MemoryStream (encoding.GetBytes (s) {using (StreamReader sr = new StreamReader (ms, encoding)) {return (T) mySerializer.Deserialize (sr);} / read into a file and deserialize the object as XML does. / File path / Encoding method / / deserialized object public static T XmlDeserializeFromFile (string path, Encoding encoding) {if (string.IsNullOrEmpty (path)) throw new ArgumentNullException ("path"); if (encoding = = null) throw new ArgumentNullException ("encoding"); string xml = File.ReadAllText (path, encoding); return XmlDeserialize (xml, encoding);}}
Xml profile-CDATA
One of the imperfections in the previous demonstration is that I output the SQL script to XML as a normal string:
Insret into.
Obviously, real SQL scripts are relatively long and may contain some special characters, which is not advisable. A good way to deal with this is to save it in the form of CDATA. In order to achieve this goal, we cannot directly deal with it in the way of ordinary strings. Here I define a class MyCDATA:
Public class MyCDATA: IXmlSerializable {private string _ value; public MyCDATA () {} public MyCDATA (string value) {this._value = value;} public string Value {get {return _ value;}} XmlSchema IXmlSerializable.GetSchema () {return null;} void IXmlSerializable.ReadXml (XmlReader reader) {this._value = reader.ReadElementContentAsString ();} void IXmlSerializable.WriteXml (XmlWriter writer) {writer.WriteCData (this._value) } public override string ToString () {return this._value;} public static implicit operator MyCDATA (string text) {return new MyCDATA (text);}}
I will use this class to control the serialization and deserialization behavior of CommandText in XML so that it is written in CDATA form, so I also need to modify the definition of CommandText to look like this:
Public MyCDATA CommandText
In the end, the result is:
Points for attention in reading and writing xml files
Typically, we use the beginning of the XML string obtained with XmlSerializer.Serialize (), with a XML declaration element:
It may not be needed sometimes for a variety of reasons. In order to make this line of characters disappear, I have seen some people use regular expressions to delete it, and some have directly analyzed the string to delete it. These methods either waste program performance or write more strange code. Anyway, it just looks awkward. In fact, we can think about it the other way around: can we not output it when serializing? If we don't export it, won't we achieve our desired goal?
When XML serialization, there is a XmlWriterSettings to control some of the behavior of writing XML, it has an OmitXmlDeclaration attribute, which is specifically used to control whether or not to output that line of XML declaration. Also, this XmlWriterSettings has some other common properties. Take a look at the following demo code:
Using (MemoryStream stream = new MemoryStream ()) {XmlWriterSettings settings = new XmlWriterSettings (); settings.Indent = true; settings.NewLineChars = "\ r\ n"; settings.OmitXmlDeclaration = true; settings.IndentChars = "\ t"; XmlWriter writer = XmlWriter.Create (stream, settings)
Using the above code, I can:
1. The XML declaration is not output.
two。 Specifies the newline character.
3. Specifies the indent character.
If you don't use this class, you really can't control the behavior of XmlSerializer.Serialize ().
The method of reading and writing XML was introduced earlier, but how to get started? Since there is no XML file and the program cannot read it, how do you get a properly formatted XML? The answer is: first write code, create an object to read, enter some junk data casually, and then write it to XML (deserialization), then we can refer to the specific format of the generated XML file, or add other nodes (list), or modify the junk data mentioned earlier, and finally get a usable XML file with the correct format.
Recommended saving method for configuration parameters
Often see a lot of components or frameworks, like to put the configuration parameters in the config file, those designers may think that the parameters of their works are more complex, but also like to make custom configuration nodes. The result: a bunch of configuration parameters in the config file. The most troublesome thing is: the next time other projects need to use this thing, you have to continue to configure it!
.net has always advocated XCOPY, but I find that there are not many components or frameworks that follow this convention. So, I would like to suggest that when designing components or frameworks:
1. Please do not put your parameters in the config file, that kind of configuration is really inconvenient [reuse].
two。 Whether the configuration file and API interface can be provided at the same time to expose the parameters, it is up to the user to decide how to save the configuration parameters.
The difference between config file and XML file
In essence, config files are also XML files, but they are a little different, not least because. Net framework predefines many configuration sections for config files. For ASP.NET applications, if we put the parameters in web.config, the site will restart as long as we modify the web.config, with one benefit: our code always runs with the latest parameters. On the other hand, there is a downside: perhaps for various reasons, we do not want the site to be restarted, after all, restarting the site will take some time, which will affect the response of the site. For this feature, I can only say that there is no way, web.config is like this.
However, when we use XML, we obviously can't get the features mentioned above directly. Because XML files are maintained by ourselves.
At this point, I believe you have a deeper understanding of the various methods of reading and writing config files and the differences between config files and XML files in .net, so you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.