YamlDotNet can not find property - c#

I am trying to create a simple model for parsing a yaml file to my domain object using YamlDotNet. The caveat is, that I want the domain model to be readonly, so I'm attempting to solve this through inheritance and internal setters.
For some reason though, the library throws an exception stating:
Property 'HtmlTemplate' not found on type
'ConsoleApplication1.Repositories.YamlTemplateRepository+DeserializeableTemplate'.
I am using an alias, but even scratching that, and using a test class with the right property names does not set it right.
What am I doing wrong? Have I misunderstood how the library should be used?
The code that calls YamlDotNet looks like this:
deserializer.Deserialize<DeserializeableTemplate>(yamlContents);
and the class I'm deserializing looks like this:
private class DeserializeableTemplate : Template
{
[YamlMember(Alias = "HtmlTemplate")]
public string HtmlTemplateWrapper
{
get { return HtmlTemplate; }
set { HtmlTemplate = value; }
}
// A few more properties...
}
and the class I am inheriting:
public class Template
{
public string HtmlTemplate { get; internal set; }
// A few more properties...
}
(Small console test application with the same error can be found here)

Old question, but I had a similar issue, which was solved by changing the access modifier of the inherited property setter to protected. I'm guessing the internal modifier used here is playing tricks on the deserialization. This might be an unwanted solution for this problem regarding making the model truly readonly, but I wanted to share my solution for future troubleshooters.

Related

How the meta tags of a method work? [duplicate]

What are attributes in .NET, what are they good for, and how do I create my own attributes?
Metadata. Data about your objects/methods/properties.
For example I might declare an Attribute called: DisplayOrder so I can easily control in what order properties should appear in the UI. I could then append it to a class and write some GUI components that extract the attributes and order the UI elements appropriately.
public class DisplayWrapper
{
private UnderlyingClass underlyingObject;
public DisplayWrapper(UnderlyingClass u)
{
underlyingObject = u;
}
[DisplayOrder(1)]
public int SomeInt
{
get
{
return underlyingObject .SomeInt;
}
}
[DisplayOrder(2)]
public DateTime SomeDate
{
get
{
return underlyingObject .SomeDate;
}
}
}
Thereby ensuring that SomeInt is always displayed before SomeDate when working with my custom GUI components.
However, you'll see them most commonly used outside of the direct coding environment. For example the Windows Designer uses them extensively so it knows how to deal with custom made objects. Using the BrowsableAttribute like so:
[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
get{/*do something*/}
}
Tells the designer not to list this in the available properties in the Properties window at design time for example.
You could also use them for code-generation, pre-compile operations (such as Post-Sharp) or run-time operations such as Reflection.Emit.
For example, you could write a bit of code for profiling that transparently wrapped every single call your code makes and times it. You could "opt-out" of the timing via an attribute that you place on particular methods.
public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
bool time = true;
foreach (Attribute a in target.GetCustomAttributes())
{
if (a.GetType() is NoTimingAttribute)
{
time = false;
break;
}
}
if (time)
{
StopWatch stopWatch = new StopWatch();
stopWatch.Start();
targetMethod.Invoke(target, args);
stopWatch.Stop();
HandleTimingOutput(targetMethod, stopWatch.Duration);
}
else
{
targetMethod.Invoke(target, args);
}
}
Declaring them is easy, just make a class that inherits from Attribute.
public class DisplayOrderAttribute : Attribute
{
private int order;
public DisplayOrderAttribute(int order)
{
this.order = order;
}
public int Order
{
get { return order; }
}
}
And remember that when you use the attribute you can omit the suffix "attribute" the compiler will add that for you.
NOTE: Attributes don't do anything by themselves - there needs to be some other code that uses them. Sometimes that code has been written for you but sometimes you have to write it yourself. For example, the C# compiler cares about some and certain frameworks frameworks use some (e.g. NUnit looks for [TestFixture] on a class and [Test] on a test method when loading an assembly).
So when creating your own custom attribute be aware that it will not impact the behaviour of your code at all. You'll need to write the other part that checks attributes (via reflection) and act on them.
Many people have answered but no one has mentioned this so far...
Attributes are used heavily with reflection. Reflection is already pretty slow.
It is very worthwhile marking your custom attributes as being sealed classes to improve their runtime performance.
It is also a good idea to consider where it would be appropriate to use place such an attribute, and to attribute your attribute (!) to indicate this via AttributeUsage. The list of available attribute usages might surprise you:
Assembly
Module
Class
Struct
Enum
Constructor
Method
Property
Field
Event
Interface
Parameter
Delegate
ReturnValue
GenericParameter
All
It's also cool that the AttributeUsage attribute is part of the AttributeUsage attribute's signature. Whoa for circular dependencies!
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute
Attributes are a kind of meta data for tagging classes. This is often used in WinForms for example to hide controls from the toolbar, but can be implemented in your own application to enable instances of different classes to behave in specific ways.
Start by creating an attribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
public int SortOrder { get; set; }
public SortOrderAttribute(int sortOrder)
{
this.SortOrder = sortOrder;
}
}
All attribute classes must have the suffix "Attribute" to be valid.
After this is done, create a class that uses the attribute.
[SortOrder(23)]
public class MyClass
{
public MyClass()
{
}
}
Now you can check a specific class' SortOrderAttribute (if it has one) by doing the following:
public class MyInvestigatorClass
{
public void InvestigateTheAttribute()
{
// Get the type object for the class that is using
// the attribute.
Type type = typeof(MyClass);
// Get all custom attributes for the type.
object[] attributes = type.GetCustomAttributes(
typeof(SortOrderAttribute), true);
// Now let's make sure that we got at least one attribute.
if (attributes != null && attributes.Length > 0)
{
// Get the first attribute in the list of custom attributes
// that is of the type "SortOrderAttribute". This should only
// be one since we said "AllowMultiple=false".
SortOrderAttribute attribute =
attributes[0] as SortOrderAttribute;
// Now we can get the sort order for the class "MyClass".
int sortOrder = attribute.SortOrder;
}
}
}
If you want to read more about this you can always check out MSDN which has a pretty good description.
I hope this helped you out!
An attribute is a class that contains some bit of functionality that you can apply to objects in your code. To create one, create a class that inherits from System.Attribute.
As for what they're good for... there are almost limitless uses for them.
http://www.codeproject.com/KB/cs/dotnetattributes.aspx
Attributes are like metadata applied to classes, methods or assemblies.
They are good for any number of things (debugger visualization, marking things as obsolete, marking things as serializable, the list is endless).
Creating your own custom ones is easy as pie. Start here:
http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx
In the project I'm currently working on, there is a set of UI objects of various flavours and an editor to assembly these objects to create pages for use in the main application, a bit like the form designer in DevStudio. These objects exist in their own assembly and each object is a class derived from UserControl and has a custom attribute. This attribute is defined like this:
[AttributeUsage (AttributeTargets::Class)]
public ref class ControlDescriptionAttribute : Attribute
{
public:
ControlDescriptionAttribute (String ^name, String ^description) :
_name (name),
_description (description)
{
}
property String ^Name
{
String ^get () { return _name; }
}
property String ^Description
{
String ^get () { return _description; }
}
private:
String
^ _name,
^ _description;
};
and I apply it to a class like this:
[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
// stuff
};
which is what the previous posters have said.
To use the attribute, the editor has a Generic::List <Type> containing the control types. There is a list box which the user can drag from and drop onto the page to create an instance of the control. To populate the list box, I get the ControlDescriptionAttribute for the control and fill out an entry in the list:
// done for each control type
array <Object ^>
// get all the custom attributes
^attributes = controltype->GetCustomAttributes (true);
Type
// this is the one we're interested in
^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid;
// iterate over the custom attributes
for each (Object ^attribute in attributes)
{
if (attributetype->IsInstanceOfType (attribute))
{
ECMMainPageDisplay::ControlDescriptionAttribute
^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute);
// get the name and description and create an entry in the list
ListViewItem
^item = gcnew ListViewItem (description->Name);
item->Tag = controltype->Name;
item->SubItems->Add (description->Description);
mcontrols->Items->Add (item);
break;
}
}
Note: the above is C++/CLI but it's not difficult to convert to C#
(yeah, I know, C++/CLI is an abomination but it's what I have to work with :-( )
You can put attributes on most things and there are whole range of predefined attributes. The editor mentioned above also looks for custom attributes on properties that describe the property and how to edit it.
Once you get the whole idea, you'll wonder how you ever lived without them.
As said, Attributes are relatively easy to create. The other part of the work is creating code that uses it. In most cases you will use reflection at runtime to alter behavior based on the presence of an attribute or its properties. There are also scenarios where you will inspect attributes on compiled code to do some sort of static analysis. For example, parameters might be marked as non-null and the analysis tool can use this as a hint.
Using the attributes and knowing the appropriate scenarios for their use is the bulk of the work.
Attributes are, essentially, bits of data you want to attach to your types (classes, methods, events, enums, etc.)
The idea is that at run time some other type/framework/tool will query your type for the information in the attribute and act upon it.
So, for example, Visual Studio can query the attributes on a 3rd party control to figure out which properties of the control should appear in the Properties pane at design time.
Attributes can also be used in Aspect Oriented Programming to inject/manipulate objects at run time based on the attributes that decorate them and add validation, logging, etc. to the objects without affecting the business logic of the object.
You can use custom attributes as a simple way to define tag values in sub classes without having to write the same code over and over again for each subclass. I came across a nice concise example by John Waters of how to define and use custom attributes in your own code.
There is a tutorial at http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx
To get started creating an attribute, open a C# source file, type attribute and hit [TAB]. It will expand to a template for a new attribute.
Attributes are also commonly used for Aspect Oriented Programming. For an example of this check out the PostSharp project.

c# Add custom method to Entity generated class with visual studio

Can anyone tell me the specific steps to add custom methods to classes generated in from an .edmx file?
I have a ReturnedItem class, which has some simple and navigation properties. From everything I have read, I should just be able to add a ReturnedItem.cs file to the project, and define the same class as partial, similar to the following code where I implement the fullDetails() method.
However, I get an error that "trackingNumber does not exist in the current context" for every property I use. When I check the properties in the method with "this" it looks like ReturnedItem is a new object type that doesn't have the properties from the object defined in the model/edmx.
I'm missing something simple I'm sure, but no amount of research is pointing me towards my mistake.
using MyEntities;
namespace MyEntityDataModel
{
public partial class ReturnedItem
{
public string fullDetails() {
return "Tracking Number:" + trackingNumber;
}
}
}
Of course I figured it out seconds after posting. I knew it had something to do with the namespace, which you pointed out. It should be:
//using MyEntities; (don't need this)
namespace MyEntities
{
public partial class ReturnedItem
{
public string fullDetails() {
return "Tracking Number:" + trackingNumber;
}
}
}
As for the other question of posting my actual entity class, I didn't even realize how to do that. Now I know I should be looking at the Designer.cs file (which I understand is auto-generated) but that would have easily shown me what the proper namespace was.
Thanks for the help! You are ridiculously fast!

How can I change properties' names (of auto generated classes) in serialization?

I have a class like below, auto generated by Entity Framework, based in our database:
public partial class TB_Cliente
{
public int IDCliente { get; set; }
public string Nome { get; set; }
// other properties
}
I'm using DataContractJsonSerializer and I need to change the properties' names in serialization. For instance, the property IDCliente must be serialized like ClientID.
I can't use [DataMember] in top of the property, because the class is auto generated, and any future changes will generate the class again and these changes will be lost.
I've had the same problem in the past, when I wanted to use data annotations. I've found the below solution, creating another file and using an interface, which works perfectly:
public interface ITB_Cliente
{
[Required]
string Nome { get; set; }
// other properties
}
[MetadataType(typeof(ITB_Cliente))]
public partial class TB_Cliente : ITB_Cliente
{
}
But this solution doesn't help me now, because (as far as I know) this attribute must be set directly in the class. I've tried to set it in the interface and it didn't work.
Is there a way to change the properties' names in the serialization, in my case? Any help will be greatly appreciated.
You probably want to use DTOs for serialization. I have not tried but AutoMapper can probably do the heavy lifting for you.
I have been trying to overcome a similar problem this week for JSON output from some legacy VB.Net classes that I would prefer not to change if I can avoid it. The serialisation is returning underlying private member names rather than the public property names, e.g. "mFirstName".
Also for autogenerated property names I am getting json like
{"k__BackingField":"Brian","k__BackingField":"Furlong"}
which is not good.
I considered a similar approach to Pawel's above (create DTOs and use Automapper which I have used extensively before).
I am also checking to see if I can make a customised json serialiser but haven't got very far yet.
The third way I have investigated is to create an "Aspect" using PostSharp which will decorate the business entity classes with the DataContract.
This would allow me to create the necessary [DataContract] and [DataMember] attributes on the public properties at compile time without having to modify the legacy code base. As I am using the legacy assemblies within a new WebAPI assembly it effectively extends the code for me.
For guidance / hints please refer to the following links:
For background information http://pietschsoft.com/post/2008/02/NET-35-JSON-Serialization-using-the-DataContractJsonSerializer
For the question that gave the pointer: How to inject an attribute using a PostSharp attribute?
For a walkthrough on how to do something similar which is enough to get going on this: http://www.postsharp.net/blog/post/PostSharp-Principals-Day-12-e28093-Aspect-Providers-e28093-Part-1

What does [input] mean in C#?

I saw this in saample source code project.
[Input]
public int Length { get; set; }
It was defined in a class:
namespace PowerLanguage.Strategy
{
public class MovAvg_Cross_SE : SignalObject
{
....
What does the [input] mean?
That's an Attribute -- a way to declare information about your source code. What your particular attribute means depends on the namespace of the attribute. You can hover over it to get information on it or (if the declaration is part of your project) ctrl-click on it to see its source.
Its an attribute. The full class name is InputAttribute. Code can reflect over properties and discover attributes, which may modify the behavior or trigger other functionality. Another example of adding functionality is Data Annotations, which when used with something that will discover and run them, can be thought of as adding behavior. You can read more about attributes here (while older, the concept is the same).

How attributes are added to class and functions

I am learning C#. I saw something like the code below. My questions are: how do you know what to put inside the [ ]? Do you have to add them manually one by one or there is a tool (such as visual studio) to do that? It is not just limited to xml, of course. I searched online, it is attribute annotion. Is there any good reference to read?
[XmlRoot("Logs")]
public class LogConfig {
[XmlArray("Servers")]
[XmlArrayItem("Server")]
public Server[] servers{
set; get;
}
public LogConfig(){
}
}
Attributes are normal classes, which means you can define your own! For an example of how to do that, see here. What you put in the [] is the name of the class. What you put in the () is defined by what properties the attribute class has.
For example (this is from the MSDN article linked above), for the attribute class below:
[System.AttributeUsage(System.AttributeTargets.Class)]
public class Author : System.Attribute
{
private string name;
public double version;
public Author(string name)
{
this.name = name;
version = 1.0;
}
}
You can add this attribute to a class like so:
[Author("P. Ackerman", version = 1.1)]
class SampleClass
{
// P. Ackerman's code goes here...
}
For a list of already defined attributes in the .NET framework, see the bottom of this page.
Do you have to add them manually one by one
Yes.
You learn about these attributes and how to apply them.
Some tools can generate classes from XSD or JSON which may contain attributes like the above, but if you are writing the class, you will need to add the attributes yourself.
No tool can guess at how a class will map to an XML structure.

Categories

Resources