XmlReader best practices - c#

I've had a good read through MSDN and the XmlReader related questions on StackOverflow and I haven't yet come across a decent "best practices" example.
I've tried various combinations and each seems to have downsides, but the best I can come up with is as follows:
The XML:
<properties>
<actions:name>start</actions:name>
<actions:value type="System.DateTime">06/08/2011 01:26:49</actions:value>
</properties>
The code:
// Reads past the initial/root element
reader.ReadStartElement();
// Check we haven't hit the end
while (!reader.EOF && reader.NodeType != XmlNodeType.EndElement) {
if (reader.IsStartElement("name", NamespaceUri)) {
// Read the name element
this.name = reader.ReadElementContentAsString();
} else if (reader.IsStartElement("value", NamespaceUri)) {
// Read the value element
string valueTypeName = reader["type"] ?? typeof(string).Name;
Type valueType = Type.GetType(valueTypeName);
string valueString = reader.ReadElementContentAsString();
// Other stuff here that doesn;t matter to the XML parsing
} else {
// We can't do anything with this node so skip over it
reader.Read();
}
}
This is being passed into my class from a .ReadSubTree() call and each class reads its own information. I would prefer it NOT to rely on it being in a specific order.
Before this, I did try several variations.
1) while(reader.Read())
This was taken from various example, but found that it "missed" some elements when .ReadContent*() of element 1 left it on the start of the element 2, .Read read over it to element 3.
2) Removing the .Read() caused it to just get stuck after the first element I read.
3) Several others I long consigned to "failed".
As far as I can see, the code I've settled on seems to be the most accepting and stable but is there anything obvious I'm missing?
(Note the c# 2.0 tag so LINQ/XNode/XElement aren't options)

One approach is to use a custom XmlReader. XmlReader is abstract and XmlReaders can be chained, giving a powerful mechanism to do some domain specific processing in a reader.
Example: XamlXmlReader
Help on XmlWrappingReader
Here's a sample of how it could be implemented (See inline comments):
/// <summary>
/// Depending on the complexity of the Xml structure, a complex statemachine could be required here.
/// Such a reader nicely separates the structure of the Xml from the business logic dependent on the data in the Xml.
/// </summary>
public class CustomXmlReader: XmlWrappingReader
{
public CustomXmlReader(XmlReader xmlReader)
:base(XmlReader.Create(xmlReader, xmlReader.Settings))
{
}
public override bool Read()
{
var b = base.Read();
if (!b)
return false;
_myEnum = MyEnum.None;
if("name".Equals(this.Name))
{
_myEnum = MyEnum.Name;
//custom logic to read the entire element and set the enum, name and any other properties relevant to your domain
//Use base.Read() until you've read the complete "logical" chunk of Xml. The "logical" chunk could be more than a element.
}
if("value".Equals(this.Value))
{
_myEnum = Xml.MyEnum.Value;
//custom logic to read the entire element and set the enum, value and and any other properties relevant to your domain
//Use base.Read() until you've read the complete "logical" chunk of Xml. The "logical" chunk could be more than a element.
}
return true;
}
//These properties could return some domain specific values
#region domain specific reader properties.
private MyEnum _myEnum;
public MyEnum MyEnum
{
get { return _myEnum; }
}
#endregion
}
public enum MyEnum
{
Name,
Value,
None
}
public class MyBusinessAppClass
{
public void DoSomething(XmlReader passedInReader)
{
var myReader = new CustomXmlReader(passedInReader);
while(myReader.Read())
{
switch(myReader.MyEnum)
{
case MyEnum.Name:
//Do something here;
break;
case MyEnum.Value:
//Do something here;
break;
}
}
}
}
A word of caution : This might be over engineering for some simple Xml processing that you've shown here. Unless, you have more that two elements that need custom processing, this approach is not advised.

Related

How can I specify which value a enum can have based on the current value?

I am looking for a way to specify a lets call it Decision Tree or a Flow.
I have a Start value 1 or REQUESTED and this enum can have multiple following values like 2 or IN_PROGRESS or 3 or DECLINED.
And now only from the value 2 it should be possible to go to a higher value like 4 or FINISHED.
What is the most practically way to define the possible paths a process or flow can have?
What's practical is often what's easiest to read an understand. To that end I recommend being explicit about what which states can lead to which other states. The enum is just a list of possible values. Using the int values of the enum might seem more concise, but it's harder to read and can lead to other problems.
First, here's an enum and a simple class that changes from one state to another if that change is allowed. (I didn't cover every state.)
enum RequestState
{
Requested,
InProgress,
Declined,
Finished
}
public class Request
{
private RequestState _state = RequestState.Requested;
public void BeginWork()
{
if (_state == RequestState.Declined || _state == RequestState.Finished)
throw new InvalidOperationException("You can only begin work on a new request.");
_state = RequestState.InProgress;
}
public void Decline()
{
if (_state == RequestState.Finished)
throw new InvalidOperationException("Too late - it's finished!");
_state = RequestState.Declined;
}
// etc.
}
If we base it on the numeric value of _state and determine that the number can only go up, a few things can go wrong:
Someone can rearrange the enums or add a new one, not knowing that the numeric value or position has logical significance. That's an easy mistake because that value usually isn't significant.
You might need to implement logic that isn't quite so simple. You might need a state that can be preceded by some of the values before it but not all of them.
You might realize that there's a valid reason for going backwards. What if a request is declined, and in the future you determine that you want to reopen requests, effectively sending them back to Requested?
If the way this is implemented starts out a little bit weird, those changes could make it even harder to change and follow. But if you just describe clearly what changes are possible given any state then it will be easy to read and modify.
You could do something to leverage that enums are basically just integers:
private static Status NextState(Status status)
{
var intOfStatus = ((int)status) + 1;
return (Status)intOfStatus;
}
And some sample logic based on this approach:
public enum Status
{
NotStarted = 0,
Started = 1,
InProgress = 2,
Declined = 3
}
public static void Main()
{
var curStatus = Status.NotStarted;
Console.WriteLine(curStatus.ToString()); //writes 'NotStarted'
if ((int)curStatus++ == (int)Status.Started)
{
curStatus = Status.Started;
}
Console.WriteLine(NextState(curStatus)); //writes 'InProgress'
}

What is proper way to save data from file to object C#

what is proper way to save all lines from text file to objects. I have .txt file something like this
0001Marcus Aurelius 20021122160 21311
0002William Shakespeare 19940822332 11092
0003Albert Camus 20010715180 01232
From this file I know position of each data that is written in file, and all data are formatted.
Line number is from 0 to 3
Book author is from 4 to 30
Publish date is from 31 to 37
Page num. is from 38 to 43
Book code is from 44 to 49
I made class Data which holds information about start, end position, value, error.
Then I made class Line that holds list of type Data, and list that holds all error founded from some line. After load data from line to object Data I loop through lineError and add errors from all line to list, because I need to save errors from each line to database.
My question is this proper way to save data from file to object and after processing same data saving to database, advice for some better approach?
public class Data
{
public int startPosition = 0;
public int endPosition = 0;
public object value = null;
public string fieldName = "";
public Error error = null;
public Data(int start, int end, string name)
{
this.startPosition = start;
this.endPosition = end;
this.fieldName = name;
}
public void SetValueFromLine(string line)
{
string valueFromLine = line.Substring(this.startPosition, this.endPosition - this.startPosition);
// if else statment that checks validity of data (lenght, empty value)
this.value = valueFromLine;
}
}
public class Line
{
public List<Data> lineData = new List<Data>();
public List<Error> lineError = new List<Error>();
public Line()
{
AddObjectDataToList();
}
public void AddObjectDataToList()
{
lineData.Add(new Data(0, 3, "lineNumber"));
lineData.Add(new Data(4, 30, "bookAuthor"));
lineData.Add(new Data(31, 37, "publishData"));
lineData.Add(new Data(38, 43, "pageNumber"));
lineData.Add(new Data(44, 49, "bookCode"));
}
public void LoadLineDataToObjects(string line)
{
foreach(Data s in lineData)
{
s.SetValueFromLine(line);
}
}
public void GetAllErrorFromData()
{
foreach (Data s in lineData)
{
if(s.error != null)
{
lineError.Add(s.error);
}
}
}
}
public class File
{
public string fileName;
public List<Line> lines = new List<Line>();
}
I assume that the focus is on using OOP. I also assume that parsing is a secondary task and I will not consider options for its implementation.
First of all, it is necessary to determine the main acting object. Strange as it may seem, this is not a Book, but the string itself (e.g. DataLine). Initially, I wanted to create a Book from a string (through a separate constructor), but that would be a mistake.
What actions should be able to perform DataLine? - In fact, only one - process. I see two acceptable options for this method:
process returns Book or throws exceptions. (Book process())
process returns nothing, but interacts with another object. (void process(IResults result))
The first option has the following drawbacks:
It is difficult to test (although this applies to the second option). All validation is hidden inside DataLine.
It is impossible/difficult to return a few errors.
The program is aimed at working with incorrect data, so expected exceptions are often generated. This violates the ideology of exceptions. Also, there are small fears of slowing performance.
The second option is devoid of the last two drawbacks. IResults can contain methodserror(...), to return several errors, and success(Book book).
The testability of the process method can be significantly improved by adding IValidator. This object can be passed as a parameter to the DataLine constructor, but this is not entirely correct. First, this unnecessary expense of memory because it will not give us tangible benefits. Secondly, this does not correspond to the essence of the DataLine class. DataLine represents only a line that can be processed in one particular way. Thus, a good solution is the void process (IValidator validator, IResults result).
Summarize the above (may contain syntax errors):
interface IResults {
void error (string message);
void success (Book book);
}
interface IValidator {
// just example
bool checkBookCode (string bookCode);
}
class DataLine {
private readonly string _rawData;
// constructor
/////////////////
public void process (IValidator validator, IResults result) {
// parse _rawData
bool isValid = true; // just example! maybe better to add IResults.hasErrors ()
if (! validator.checkBookCode (bookCode)) {
result.error("Bad book code");
isValid = false;
}
if (isValid) {
result.success(new Book (...));
// or even result.success (...); to avoid cohesion (coupling?) with the Book
}
}
}
The next step is to create a model of the file with the lines. Here again there are many options and nuances, but I would like to pay attention to IEnumerable<DataLine>. Ideally, we need to create a DataLines class that will support IEnumerable<DataLine> and load from a file or from IEnumerable<string>. However, this approach is relatively complex and redundant, it makes sense only in large projects. A much simpler version:
interface DataLinesProvider {
IEnumerable <DataLine> Lines ();
}
class DataLinesFile implements DataLinesProvider {
private readonly string _fileName;
// constructor
////////////////////
IEnumerable <DataLine> Lines () {
// not sure that it's right
return File
. ReadAllLines (_fileName)
.Select (x => new DataLine (x));
}
}
You can infinitely improve the code, introduce new and new abstractions, but here you must start from common sense and a specific problem.
P. S. sorry for "strange" English. Google not always correctly translate such complex topics.

Constructing an IEnumerable based on a collection of collections

Good afternoon,
I'm having a highly entertaining time trying to convince the 'yield' keyword to function in a way that I can understand, but unfortunately I'm not having much luck. Here's the scenario:
Based on the property of a user, I want to look up a set of RSS feed addresses and display the seven most recent articles from all of those feeds, not each of those feeds. To do so, I'm trying to build a collection of the five most recent articles from each feed, then take the 7 most recent from those. The (very dull) pseudo-code-type-process goes something like:
Look up the the member
Get the relevant property ( a group name) for the member
Look up the addresses of the RSS feeds for that group
For each address in the collection, get the five most recent articles and place them in another collection
Take the seven most recent articles from that
subsequent collection and display them.
I've done some research and been able to produce the following:
public static class RSSHelper
{
public static IEnumerable<SyndicationItem> GetLatestArticlesFromFeeds(List<string> feedList, short articlesToTake)
{
foreach (string Feed in feedList)
{
yield return GetLatestArticlesFromFeed(Feed).OrderByDescending(o => o.PublishDate).Take(articlesToTake).First();
}
yield return null;
}
private static IEnumerable<SyndicationItem> GetLatestArticlesFromFeed(string feedURL)
{
// We're only accepting XML based feeds, so create an XML reader:
SyndicationItem Result = new SyndicationItem();
int SkipCount = 0;
for (int Curr = 1; Curr <= 5; Curr++)
{
try
{
XmlReader Reader = XmlReader.Create(feedURL);
SyndicationFeed Feed = SyndicationFeed.Load(Reader);
Reader.Close();
Result = Feed.Items.OrderByDescending(o => o.PublishDate).Skip(SkipCount).Take(1).Single();
SkipCount++;
}
catch (Exception ex)
{
// Do nothing, else the Yield will fail.
}
yield return Result;
}
}
}
What seems to be happening is that I get five results (articlesToTake is 7, not 5), and occasionally either the whole SyndicationItem is null, or properties of it are null. I'm also convinced that this is a really, really poorly performing approach to tackling this problem, but I can't find much direction on using the yield keyword in this context.
I did find this question but it's not quite helping me understand anything.
Is what I'm trying to do achievable in this way, or do I just need to bite the bullet and use a couple of foreach loops?
Load your RSS feed in memory using async and await, then order them by date, and just Take the first 7
Considering all you want to do in GetLatestArticlesFromFeed is to get the 5 latest items, wouldn't it be easier to only order the list once and then take the first 5 items? It would look like this (together with a SelectMany based approach to the first method)
public static class RSSHelper
{
public static IEnumerable<SyndicationItem> GetLatestArticlesFromFeeds(List<string> feedList, short articlesToTake)
{
return feedList.SelectMany(f => GetLatestArticlesFromFeed(f)).OrderByDescending(a => a.PublishDate).Take(articlesToTake);
}
private static IEnumerable<SyndicationItem> GetLatestArticlesFromFeed(string feedURL)
{
// We're only accepting XML based feeds, so create an XML reader:
SyndicationFeed feed = null;
try
{
using (XmlReader reader = XmlReader.Create(feedURL))
{
feed = SyndicationFeed.Load(reader);
}
return feed.Items.OrderByDescending(o => o.PublishDate).Take(5);
}
catch
{
return Enumerable.Empty<SyndicationItem>();
}
}
}
Let me know if this doesn't work!
Morning,
Now that I don't feel like death warmed up, I've got it working! Thanks to #Rodrigo and #McKabue for their help in finding the eventual answer, and #NPSF3000 for pointing out my original stupidity!
I've settled on this as a result:
public static class RSSHelper
{
public static IEnumerable<SyndicationItem> GetLatestArticlesFromFeeds(List<string> feedList, short articlesToTake)
{
return GetLatestArticlesFromFeedsAsync(feedList, articlesToTake).Result;
}
private async static Task<IEnumerable<SyndicationItem>> GetLatestArticlesFromFeedsAsync(List<string> feedList, short articlesToTake)
{
List<Task<IEnumerable<SyndicationItem>>> TaskList = new List<Task<IEnumerable<SyndicationItem>>>();
foreach (string Feed in feedList)
{
// Call and start a task to evaluate the RSS feeds
Task<IEnumerable<SyndicationItem>> T = Task.FromResult(GetLatestArticlesFromFeed(Feed).Result);
TaskList.Add(T);
}
var Results = await Task.WhenAll(TaskList);
// Filter the not null results - on the balance of probabilities, we'll still get more than 7 results.
var ReturnList = Results.SelectMany(s => TaskList.Where(w => w.Result != null).SelectMany(z => z.Result).OrderByDescending(o => o.PublishDate)).Take(articlesToTake);
return ReturnList;
}
private async static Task<IEnumerable<SyndicationItem>> GetLatestArticlesFromFeed(string feedURL)
{
// We're only accepting XML based feeds, so create an XML reader:
try
{
XmlReader Reader = XmlReader.Create(feedURL);
SyndicationFeed Feed = SyndicationFeed.Load(Reader);
Reader.Close();
return Feed.Items.OrderByDescending(o => o.PublishDate).Take(5);
}
catch (Exception ex)
{
return null;
}
}
}
It took me a while to wrap my head around, as I was forgetting to define the result type of the task I was kicking off, but thankfully I stumbled across this question this morning, which helped everything fall nicely into place.
I feel a bit cheeky answering my own question, but on balance I think this is a nice, tidy balance between the proposed answers and it certainly seems functional. I'll add some hardening and comments, and of course if anyone has feedback I'll receive it gratefully.
Thanks!
Ash

Implementing IFormatter recursively

I'm trying to implement a custom formatter using the .NET IFormatter interface.
After a couple of hours of search, I just found a very basic sample which unfortunately doesn't include recursion. I also tried with Reflector to look at BinaryFormatter and SoapFormatter, but they are rather complex.
My question is:
Should I implement recursion myself, or there's something I've missed in FormatterServices?
Following my code:
public void Serialize(Stream serializationStream, object graph)
{
// Get fields that are to be serialized.
MemberInfo[] members = FormatterServices.GetSerializableMembers(graph.GetType(), Context);
// Get fields data.
object[] data = FormatterServices.GetObjectData(graph, members);
// Write class name and all fields & values to file
StreamWriter sw = new StreamWriter(serializationStream);
string accumulator = string.Empty;
for (int i = 0; i < data.Length; ++i)
{
// Skip this field if it is marked NonSerialized.
if (Attribute.IsDefined(members[i], typeof(NonSerializedAttribute)))
continue;
FieldInfo field = (FieldInfo)members[i];
if (field.FieldType.IsPrimitive)
{
}
else //TODO: What should I do here?
}
sw.Close();
}
If by recursion you mean traversing through the object tree then yes, it up to you when you implement your own IFormatter.
Simply check if the value of the property is not null and if it is implementing IFormatter interface. If it is then just call it and use the value it returns.
If not then it is up to you again: you may throw an exception saying that IFormatter must be implemented, or just fall-back to some sort of default formatter (XML or Binary one).
The recursion per se is tricky. When, let's say, the object references itself, you need to be smart enough to handle this situation and not to end up with the infinite loop:
public class A {
public object SomeProperty { get; set; }
}
var a = new A();
a.SomeProperty = a;
There are a number of tricky aspects in implementing formatters, like what if two properties are actually reference the same object? Will you serialize/format it twice or just once and keep the information about these references somehow?
You don't probably need this if you want just one-way serialization, but if you want to be able to restore the object it might be important...

Most Useful Attributes [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I know that attributes are extremely useful. There are some predefined ones such as [Browsable(false)] which allows you to hide properties in the properties tab. Here is a good question explaining attributes: What are attributes in .NET?
What are the predefined attributes (and their namespace) you actually use in your projects?
[DebuggerDisplay] can be really helpful to quickly see customized output of a Type when you mouse over the instance of the Type during debugging. example:
[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
public string FirstName;
public string LastName;
}
This is how it should look in the debugger:
Also, it is worth mentioning that [WebMethod] attribute with CacheDuration property set can avoid unnecessary execution of the web service method.
System.Obsolete is one of the most useful attributes in the framework, in my opinion. The ability to raise a warning about code that should no longer be used is very useful. I love having a way to tell developers that something should no longer be used, as well as having a way to explain why and point to the better/new way of doing something.
The Conditional attribute is pretty handy too for debug usage. It allows you to add methods in your code for debug purposes that won't get compiled when you build your solution for release.
Then there are a lot of attributes specific to Web Controls that I find useful, but those are more specific and don't have any uses outside of the development of server controls from what I've found.
[Flags] is pretty handy. Syntactic sugar to be sure, but still rather nice.
[Flags]
enum SandwichStuff
{
Cheese = 1,
Pickles = 2,
Chips = 4,
Ham = 8,
Eggs = 16,
PeanutButter = 32,
Jam = 64
};
public Sandwich MakeSandwich(SandwichStuff stuff)
{
Console.WriteLine(stuff.ToString());
// ...
}
// ...
MakeSandwich(SandwichStuff.Cheese
| SandwichStuff.Ham
| SandwichStuff.PeanutButter);
// produces console output: "Cheese, Ham, PeanutButter"
Leppie points out something I hadn't realized, and which rather dampens my enthusiasm for this attribute: it does not instruct the compiler to allow bit combinations as valid values for enumeration variables, the compiler allows this for enumerations regardless. My C++ background showing through... sigh
I like [DebuggerStepThrough] from System.Diagnostics.
It's very handy for avoiding stepping into those one-line do-nothing methods or properties (if you're forced to work in an early .Net without automatic properties). Put the attribute on a short method or the getter or setter of a property, and you'll fly right by even when hitting "step into" in the debugger.
For what it's worth, here's a list of all .NET attributes. There are several hundred.
I don't know about anyone else but I have some serious RTFM to do!
My vote would be for Conditional
[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
// your code here
}
You can use this to add a function with advanced debugging features; like Debug.Write, it is only called in debug builds, and so allows you to encapsulate complex debug logic outside the main flow of your program.
I always use the DisplayName, Description and DefaultValue attributes over public properties of my user controls, custom controls or any class I'll edit through a property grid. These tags are used by the .NET PropertyGrid to format the name, the description panel, and bolds values that are not set to the default values.
[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
...
}
I just wish Visual Studio's IntelliSense would take the Description attribute into account if no XML comment are found. It would avoid having to repeat the same sentence twice.
[Serializable] is used all the time for serializing and deserializing objects to and from external data sources such as xml or from a remote server. More about it here.
In Hofstadtian spirit, the [Attribute] attribute is very useful, since it's how you create your own attributes. I've used attributes instead of interfaces to implement plugin systems, add descriptions to Enums, simulate multiple dispatch and other tricks.
Here is the post about interesting attribute InternalsVisibleTo. Basically what it does it mimics C++ friends access functionality. It comes very handy for unit testing.
I've found [DefaultValue] to be quite useful.
I'd suggest [TestFixture] and [Test] - from the nUnit library.
Unit tests in your code provide safety in refactoring and codified documentation.
[XmlIgnore]
as this allows you to ignore (in any xml serialisation) 'parent' objects that would otherwise cause exceptions when saving.
It's not well-named, not well-supported in the framework, and shouldn't require a parameter, but this attribute is a useful marker for immutable classes:
[ImmutableObject(true)]
I like using the [ThreadStatic] attribute in combination with thread and stack based programming. For example, if I want a value that I want to share with the rest of a call sequence, but I want to do it out of band (i.e. outside of the call parameters), I might employ something like this.
class MyContextInformation : IDisposable {
[ThreadStatic] private static MyContextInformation current;
public static MyContextInformation Current {
get { return current; }
}
private MyContextInformation previous;
public MyContextInformation(Object myData) {
this.myData = myData;
previous = current;
current = this;
}
public void Dispose() {
current = previous;
}
}
Later in my code, I can use this to provide contextual information out of band to people downstream from my code. Example:
using(new MyContextInformation(someInfoInContext)) {
...
}
The ThreadStatic attribute allows me to scope the call only to the thread in question avoiding the messy problem of data access across threads.
The DebuggerHiddenAttribute which allows to avoiding step into code which should not be debugged.
public static class CustomDebug
{
[DebuggerHidden]
public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}
...
// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception());
Also it prevents from showing methods in stack trace, useful when having a method which just wraps another method:
[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
return GetElementAt(position.X, position.Y);
}
public Element GetElementAt(Single x, Single y) { ... }
If you now call GetElementAt(new Vector2(10, 10)) and a error occurs at the wrapped method, the call stack is not showing the method which is calling the method which throws the error.
DesignerSerializationVisibilityAttribute is very useful. When you put a runtime property on a control or component, and you don't want the designer to serialize it, you use it like this:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
get { return baz; }
set { baz = value; }
}
Only a few attributes get compiler support, but one very interesting use of attributes is in AOP: PostSharp uses your bespoke attributes to inject IL into methods, allowing all manner of abilities... log/trace being trivial examples - but some other good examples are things like automatic INotifyPropertyChanged implementation (here).
Some that occur and impact the compiler or runtime directly:
[Conditional("FOO")] - calls to this method (including argument evaluation) only occur if the "FOO" symbol is defined during build
[MethodImpl(...)] - used to indicate a few thing like synchronization, inlining
[PrincipalPermission(...)] - used to inject security checks into the code automatically
[TypeForwardedTo(...)] - used to move types between assemblies without rebuilding the callers
For things that are checked manually via reflection - I'm a big fan of the System.ComponentModel attributes; things like [TypeDescriptionProvider(...)], [TypeConverter(...)], and [Editor(...)] which can completely change the behavior of types in data-binding scenarios (i.e. dynamic properties etc).
If I were to do a code coverage crawl, I think these two would be top:
[Serializable]
[WebMethod]
I have been using the [DataObjectMethod] lately. It describes the method so you can use your class with the ObjectDataSource ( or other controls).
[DataObjectMethod(DataObjectMethodType.Select)]
[DataObjectMethod(DataObjectMethodType.Delete)]
[DataObjectMethod(DataObjectMethodType.Update)]
[DataObjectMethod(DataObjectMethodType.Insert)]
More info
In our current project, we use
[ComVisible(false)]
It controls accessibility of an individual managed type or member, or of all types within an assembly, to COM.
More Info
[TypeConverter(typeof(ExpandableObjectConverter))]
Tells the designer to expand the properties which are classes (of your control)
[Obfuscation]
Instructs obfuscation tools to take the specified actions for an assembly, type, or member. (Although typically you use an Assembly level [assembly:ObfuscateAssemblyAttribute(true)]
The attributes I use the most are the ones related to XML Serialization.
XmlRoot
XmlElement
XmlAttribute
etc...
Extremely useful when doing any quick and dirty XML parsing or serializing.
Being a middle tier developer I like
System.ComponentModel.EditorBrowsableAttribute Allows me to hide properties so that the UI developer is not overwhelmed with properties that they don't need to see.
System.ComponentModel.BindableAttribute Some things don't need to be databound. Again, lessens the work the UI developers need to do.
I also like the DefaultValue that Lawrence Johnston mentioned.
System.ComponentModel.BrowsableAttribute and the Flags are used regularly.
I use
System.STAThreadAttribute
System.ThreadStaticAttribute
when needed.
By the way. I these are just as valuable for all the .Net framework developers.
[EditorBrowsable(EditorBrowsableState.Never)] allows you to hide properties and methods from IntelliSense if the project is not in your solution. Very helpful for hiding invalid flows for fluent interfaces. How often do you want to GetHashCode() or Equals()?
For MVC [ActionName("Name")] allows you to have a Get action and Post action with the same method signature, or to use dashes in the action name, which otherwise would not be possible without creating a route for it.
I consider that is important to mention here that the following attributes are also very important:
STAThreadAttribute
Indicates that the COM threading model for an application is single-threaded apartment (STA).
For example this attribute is used in Windows Forms Applications:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
And also ...
SuppressMessageAttribute
Suppresses reporting of a specific static analysis tool rule violation, allowing multiple suppressions on a single code artifact.
For example:
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
string fileIdentifier = name;
string fileName = name;
string version = String.Empty;
}
Off the top of my head, here is a quick list, roughly sorted by frequency of use, of predefined attributes I actually use in a big project (~500k LoCs):
Flags, Serializable, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.
I generates data entity class via CodeSmith and I use attributes for some validation routine. Here is an example:
/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
get { return _firmGUID; }
set { _firmGUID = value; }
}
And I got an utility class to do the validation based on the attributes attached to the data entity class. Here is the code:
namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
/// <summary>
/// Data entity validation
/// </summary>
/// <param name="data">Data entity object</param>
/// <returns>return true if the object is valid, otherwise return false</returns>
public static bool Validate(object data)
{
bool result = true;
PropertyInfo[] properties = data.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
//Length validatioin
Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
if (attribute != null)
{
ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
if (validLengthAttribute != null)
{
int maxLength = validLengthAttribute.MaxLength;
int minLength = validLengthAttribute.MinLength;
string stringValue = p.GetValue(data, null).ToString();
if (stringValue.Length < minLength || stringValue.Length > maxLength)
{
return false;
}
}
}
//Range validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
if (attribute != null)
{
ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
if (validRangeAttribute != null)
{
decimal maxValue = decimal.MaxValue;
decimal minValue = decimal.MinValue;
decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
decimal decimalValue = 0;
decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
if (decimalValue < minValue || decimalValue > maxValue)
{
return false;
}
}
}
//Regex validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
if (attribute != null)
{
ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
if (validRegExAttribute != null)
{
string objectStringValue = p.GetValue(data, null).ToString();
string regExString = validRegExAttribute.RegExString;
Regex regEx = new Regex(regExString);
if (regEx.Match(objectStringValue) == null)
{
return false;
}
}
}
//Required field validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
if (attribute != null)
{
ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
if (validRequiredAttribute != null)
{
object requiredPropertyValue = p.GetValue(data, null);
if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
{
return false;
}
}
}
}
return result;
}
}
}
[DeploymentItem("myFile1.txt")]
MSDN Doc on DeploymentItem
This is really useful if you are testing against a file or using the file as input to your test.
[System.Security.Permissions.PermissionSetAttribute] allows security actions for a PermissionSet to be applied to code using declarative security.
// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
// The immediate caller is required to have been granted the FullTrust permission.
[PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
public FullConditionUITypeEditor() { }
}

Categories