Use JsonIgnore on certain inherited properties - c#

I have a base class like this-ish:
public class Baseclass
{
public string Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
}
...and many classes that inherit these properties, like this-ish:
public class Thing: Baseclass
{
public string Size{ get; set; }
public string Color{ get; set; }
public string Smell{ get; set; }
}
Now, I don't want to serialize all of these properties (mvc/jsonresult), so I use [JsonIgnore] on the properties of a class I want to exclude, and that works fine. The problem is that I don't want to serialize all the inherited properties for a class either. I've asked around and gotten the following answer:
Ex: I don't want to serialize the inherited Id from Baseclass in Thing.
I should make Id in Baseclass virutal:
public virtual string Id { get; set; }
and add the following to the Thing class:
[JsonIgnore]
public override string Id { get; set; }
...but this doesn't work, I'm afraid. I can get around it rebuilding the class hierarchy. but I would prefer a simpler solution. Any suggestions as to why this solution didn't work or alternatives to exclude certain inherited properties?

Related

EF Core name mapping

I've been trying to figure out how to do the following (although my research did not help): I have the these three classes:
public abstract class Classifier
{
public int ClassifierId { get; set; }
public string ClassifierName { get; set; }
public DateTime DateAdded { get; set; }
}
public class ManualClassifier : Classifier
{
public int ManualClassifierId { get; set; }
public string user_name { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
public string password { get; set; }
}
public class ToolClassifier : Classifier
{
public int ToolId { get; set; }
public string ToolName { get; set; }
}
Both the ManualClassifier and ToolClassifer inherit from Classifier. I'm using EF Core to map this to a database but the question is the following: I've already searched a bit and I must make use of a descriminator which basically is an implicitly created column that will say the type of, in this case, classifier. So far so good. The issue arises when I have a property called ManualClassifierId as well as a ToolId. I want this two properties to map to the ClassifierId property. So in the table representing the entity Classifier, the ClassifierId property will either be the ManualClassifierId or the ToolId.
How can I achieve this mapping? Also, this solution would mean that both child classes would both have empty fileds in the tables (due to inheriting the three properties from the Classifier class). Is there a better solution? Perhaps just erase the Id's from both child classes a let them inherit the parent one?
Thank you in advance!
To use the same column name in both classes, you can add a Column attribute to both properties. Then they will both use that column name in the database. See ColumnAttribute(String).
Use it like this:
public class ManualClassifier : Classifier
{
[Column(Name="ClassifierId")]
public int ManualClassifierId { get; set; }
...........
}
Do the same with ToolId.

Is there any way to disable the validation of inherited properties?

I have the following entities for example:
public class BaseClass
{
[Required]
public virtual string DisplayName { get; set; }
}
public class FirstChildClass: BaseClass
{
public int Id { get; set; }
}
public class SecondChildClas: BaseClass
{
public int Id { get; set; }
}
Then i have the following viewmodel:
public class MyViewModel
{
public FirstChildClass FirstProperty { get; set; }
public SecondChildClass SecondProperty { get; set; }
}
In my View i have a form which submits the following properties FirstChildClass.Id and SecondChildClass.Id.
My problem is that the inherited DisplayName is added to my ModelState due to the [Required] attribute. I'd like to ignore the validation of inherited properties without removing them explicitly from the ModelState with Remove().
Is there any way to accomplish it?
I would suggest not using inheritance here. What is BaseClass:
I have DisplayName and it should be Required but not always, it depends, looks in all derived classes to understand how I work.
If you really want to go that way check if you can make this property virtual, and add attribute only to one derived class.

Multiple metadata classes for entity

Suppose I have 2 entities one is UserMaster another is ProjectMaster, now there are few common properties in both the entities and I need to apply same data annotations and attributes on both set of common properties which I do using metadata classes, now my question is there any way that I have a common metadata class for all this common properties across entities,so that I don't need apply data annotation and attributes for common properties again and again and if yes then how to achieve this.
You can create a base metadata class and the other metadata class derive from the base and add some other properties.
Example:
In the below example I supposed you can't derive Class2 from Class1 so I have inheritance only between metadata classes, otherwise you can simply have inheritance between your model classes.
[MetadataType(typeof(Class1Metadata))]
public class Class1
{
public string Id { get; set; }
public string Name { get; set; }
}
[MetadataType(typeof(Class2Metadata))]
public class Class2
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Class1Metadata
{
[Display(Name="Id1")]
public string Id { get; set; }
[Display(Name = "Name1")]
public string Name { get; set; }
}
public class Class2Metadata:Class1Metadata
{
[Display(Name = "Description2")]
public string Description { get; set; }
}

Creating Objects where multiple objects have the same properties

My program is starting to get pretty big. and i have found that its starting to do the same thing in multiple area's.
Im trying to figure out how i can make it more efficient.
So i have an object that looks like this
public class TreeViewNode
{
public TreeViewNode()
{
Children = new ObservableCollection<TreeViewNode>();
}
public String Name { get; set; }
public string Description { get; set; }
public ObservableCollection<TreeViewNode> Children { get; set; }
}
i also have another object that looks like this;
public class ComputerObject
{
public String Name { get; set; }
public Int32 UUID { get; set; }
public DateTime Created { get; set; }
public ObservableCollection<Object> Children { get; set; }
}
Both these items need to have some of the same properties..
at the moment they both have the Children Property and the Name Property. but they both need to have some other common properties added to them.
so i have tried something like this.
public class BaseObject
{
public String Name { get; set; }
public ObservableCollection<Object> Children { get; set; }
public string Description { get; set; }
public BaseObject()
{
Children = new ObservableCollection<object>();
}
}
public class ComputerObject: BaseObject
{
public Int32 UUID { get; set; }
public DateTime Created { get; set; }
}
public class TreeViewNode: BaseObject
{
public String IconPath { get; set; }
}
Now this is just a cut down version of what i am implementing, i have alot of objects that share the same properties. and some that dont and mix and match. and i cannot figure out the best implimentation for this.
My Objects are becoming very cluttered, and when i rename a property i find that i have to rename it in several area's and this isnt the way its ment to be.
can someone please advise how i would implement multiple objects that share the same property names?
In my opinion you should not let classes inherit from one baseclass when these childclasses are not related to each other (like #Sriram Sakthivel asked Animal < Dog,Cat) just to share the same properties.
You should determine which classes are related (cat, dog are animals; car, motorcycle are vehicles) and then create baseclasses based on these "groupings".
I would look into decorator pattern. In short, you dont share common properties via inheritance. You make classes that contain common properties, and use these classes as properties in your end classes.
EDIT: Example is actually just a standard composition, it should work nevertheless
E.G.
public class Decorator1
{
public String Name { get; set; }
public ObservableCollection<Object> Children { get; set; }
public string Description { get; set; }
}
public class Decorator2
{
public long Id { get; set; }
}
public class ClassA
{
public Decorator1 TreeNodeImpl;
}
public class ClassB
{
public Decorator1 TreeNodeImpl;
public Decorator2 LongIdImpl;
}

Define simple data classes as abstract , interface or just classes?

Rather new to OOP..
I am gonna build a number of small applications that will support our main business.
These apps:
-Will need some common data classes
-The above classes may change in the future as far as properties are concerned (will add properties when ERP versions advance).
For example i have a class:
public class Lot
{
public string SSCC { get; set; }
public InventoryItem Item { get; set; }
public string DescriptionLocalLot { get; set; }
public string DescriptionEnglishLot { get; set; }
public DateTime ProductionDate { get; set; }
public string Shift { get; set; }
public string WorkOrder { get; set; }
public string ProductionLine { get; set; }
public string BarcodeEAN14 { get; set; }
public decimal Boxes { get; set; }
public decimal Units { get; set; }
public decimal Pieces { get; set; }
public DateTime LastUpdated { get; set; }
public string LastUser { get; set; }
public Warehouse LastWarehouse { get; set; }
public string ProductionLot { get; set; }
public string PalletSequence { get; set; }
}
The above class will be used by almost all applications (Windows forms or ASP pages). Ihave put this definition in a separate file called CommonClasses.
Should i define these classes as Abstract or Interfaces better? In most cases these classes will not include methods.
A class should describe all of an object's properties as well as methods that can act upon it. Not all are going to be used at once; but they are provided so that all the behavior is understood and state of an object can be tracked.
The class described in your code seems like a candidate for a concrete class. It provides a set of properties that are stored in memory and act in relation to one object. If you require additional functionality at a later point, you can extend the class to provide this.
If however, each instance of the class requires different implementation; then you should consider abstract class, or perhaps interface.
You should use concrete classes in your case if the change is common for all applications which are using these classes.

Categories

Resources