Using Newtonsoft Jschema, how can I validate derived class properties based on an abstract class? - asp.net

An example would be I have an array of the abstract class Production which has derived classes of Movie and Series. I have an array in the schema that is a Production[] which can hold either a Movie or Series. I'm validating schema that is being provided to us by a third party. I am only validating, not deserializing so I am validating it with the validation stream.
When I validate that array, it only validates against the properties within Production. It skips any properties that are within the derived classes. How can I get it to validate against the correct derived class properties? I have a ProductionType property on Production which is a one to one match to the derived class.
I have tried adding the derived class schemas to the "AdditionalItems" in the ProductionGenerationProvider and manually validate against it in the ProductionValidationProvider. Did this by value.Validate(matchedSchemaItem). This causes a whole new validation to be spawned off instead of validate it within the context of the current validation.
I also tried using the OneOf property on the schema by passing in the references to all the derived types but it just tells me that it didn't validate against any of the items in OneOf.
Is there a way another way to do this? I assume this is a solved issue and I just haven't come across the solution.

Related

Symfony Workflow - Is it possible to use doctrine relation as state holder?

I am trying to adopt the Symfony workflow component to my app.
As documentation says marking_store points to string. I was googling for it - it can be a string or json_array-field of a Doctrine entity.
But what if I have an Entity BlogPost with a relation BlogPostStatus that have two fields: some primary id and statusName. Can I configure the workflow component to change statuses of my BlogPost (i.e set new BlogPostStatus to BlogPost entity) and persist it to database?
Now I have only one solution: Add to my BlogPost entity non-mapped field and when it's changed change status of Entity.
Do you have a better solution?
For all built-in marking_store implementations the following is true:
If the functions setMarking or getMarking exist on the object holding the state, they will be used to set or get the marking respectively.
There are 3 built-in marking stores, the SingleStateMarkingStore (using the property accessor, hence setMarking/getMarking), the MultiStateMarkingStore (same), the MethodMarkingStore (explicitly calling those functions, you can change the function via the property setting of your marking_store config).
The difference lies within the argument provided in the setMarking call, for single state (this is the state_machine type, and by default NOT the the workflow type), the argument is the place (or state) where the mark is placed. For multi state (workflow type by default), the argument is an array where the keys are places and the values are marks, usually the marks are 1, and empty places are omitted.
So, I'll assume that your BlogPost (currently) only has a single state at any given time, and what you have to do now is to transform the marking given into the status entity - I will assume your workflow has type state_machine:
/** in class BlogPost */
public function setMarking(string $marking/*, array $context*/) {
$this->status->statusName = $marking;
}
public function getMarking() {
return $this->status->statusName;
}
special cases
If the BlogPostStatus should be a different one (for example, a constant object), then you'd have to use the new interface that dbrumann linked, and hook into the event to add that to the context.
If the BlogPostStatus may not exist at the time of the setMarking/getMarking, you have to create it on the fly in the setter and check for it in the getter. But I'm sure you're capable of doing that ;o)
Also if you're not using the single state workflows but multi state instead, you have to find a way to transform the array of (places->marks) into your status object and vice versa.

JSON.net ContractResolver vs. JsonConverter

I've been working with JSON.net for a while. I have written both custom converters and custom contract resolvers (generally from modifying examples on S.O. and the Newtonsoft website), and they work fine.
The challenge is, other than examples, I see little explanation as to when I should use one or the other (or both) for processing. Through my own experience, I've basically determined that contract resolvers are simpler, so if I can do what I need with them, I go that way; otherwise, I use custom JsonConverters. But, I further know both are sometimes used together, so the concepts get further opaque.
Questions:
Is there a source that distinguishes when to user one vs. the other? I find the Newtonsoft documentation unclear as to how the two are differentiated or when to use one or the other.
What is the pipeline of ordering between the two?
Great question. I haven't seen a clear piece of documentation that says when you should prefer to write a custom ContractResolver or a custom JsonConverter to solve a particular type of problem. They really do different things, but there is some overlap between what kinds of problems can be solved by each. I've written a fair number of each while answering questions on StackOverflow, so the picture has become a little more clear to me over time. Below is my take on it.
ContractResolver
A contract resolver is always used by Json.Net, and governs serialization / deserialization behavior at a broad level. If there is not a custom resolver provided in the settings, then the DefaultContractResolver is used. The resolver is responsible for determining:
what contract each type has (i.e. is it a primitive, array/list, dictionary, dynamic, JObject, plain old object, etc.);
what properties are on the type (if any) and what are their names, types and accessibility;
what attributes have been applied (e.g. [JsonProperty], [JsonIgnore], [JsonConverter], etc.), and
how those attributes should affect the (de)serialization of each property (or class).
Generally speaking, if you want to customize some aspect of serialization or deserialization across a wide range of classes, you will probably need to use a ContractResolver to do it. Here are some examples of things you can customize using a ContractResolver:
Change the contract used for a type
Serialize all Dictionaries as an Array of Key/Value Pairs
Serialize ListItems as a regular object instead of string
Change the casing of property names when serializing
Use camel case for all property names
Camel case all property names except dictionaries
Programmatically apply attributes to properties without having to modify the classes (particularly useful if you don't control the source of said classes)
Globally use a JsonConverter on a class without the attribute
Remap properties to different names defined at runtime
Allow deserializing to public properties with non-public setters
Programmatically unapply (ignore) attributes that are applied to certain classes
Optionally turn off the JsonIgnore attribute at runtime
Make properties which are marked as required (for SOAP) not required for JSON
Conditionally serialize properties
Ignore read-only properties across all classes
Skip serializing properties that throw exceptions
Introduce custom attributes and apply some custom behavior based on those attributes
Encrypt specially marked string properties in any class
Selectively escape HTML in strings during deserialization
JsonConverter
In contrast to a ContractResolver, the focus of a JsonConverter is more narrow: it is really intended to handle serialization or deserialization for a single type or a small subset of related types. Also, it works at a lower level than a resolver does. When a converter is given responsibility for a type, it has complete control over how the JSON is read or written for that type: it directly uses JsonReader and JsonWriter classes to do its job. In other words, it can change the shape of the JSON for that type. At the same time, a converter is decoupled from the "big picture" and does not have access to contextual information such as the parent of the object being (de)serialized or the property attributes that were used with it. Here are some examples of problems you can solve with a JsonConverter:
Handle object instantiation issues on deserialization
Deserialize to an interface, using information in the JSON to decide which concrete class to instantiate
Deserialize JSON that is sometimes a single object and sometimes an array of objects
Deserialize JSON that can either be an array or a nested array
Skip unwanted items when deserializing from an array of mixed types
Deserialize to an object that lacks a default constructor
Change how values are formatted or interpretted
Serialize decimal values as localized strings
Convert decimal.MinValue to an empty string and back (for use with a legacy system)
Serialize dates with multiple different formats
Ignore UTC offsets when deserializing dates
Make Json.Net call ToString() when serializing a type
Translate between differing JSON and object structures
Deserialize a nested array of mixed values into a list of items
Deserialize an array of objects with varying names
Serialize/deserialize a custom dictionary with complex keys
Serialize a custom IEnumerable collection as a dictionary
Flatten a nested JSON structure into a simpler object structure
Expand a simple object structure into a more complicated JSON structure
Serialize a list of objects as a list of IDs only
Deserialize a JSON list of objects containing GUIDs to a list of GUIDs
Work around issues (de)serializing specific .NET types
Serializing System.Net.IPAddress throws an exception
Problems deserializing Microsoft.Xna.Framework.Rectangle

Adding a callback when reading from an object in Twig

Let's say I have a basic entity called Entity which is mapped to a database table. This entity has got two properties: propertyA and propertyB.
One particularity of this entity is, although we may store whatever we want in these properties, when using the value of propertyB on a Twig template with entity.propertyB we want to systematically truncate the value to 100 characters.
Now, this is perfectly doable in several ways:
Truncate the value directly in the getPropertyB() method;
Register a Twig extension and create a dedicated filter;
Add a lifecycle callback on the entity to truncate the value before the object is actually created.
As this is strictly a display rule, and not a business rule on our entity, the second solution seems to be the best IMHO. However, it demands we apply the filter every time we need to use the value of propertyB in a template. Should an unaware developer come by, the value may not be truncated.
So my question is: is there a way to register some kind of callback, strictly restricted to the view model wrapping our entity, which would allow us to apply some filters on the fly on some of its properties ?
Since you never need to access anything beyond 100 characters, you can truncate the property in its setter. This doesn't really pollute Entity code, because this is some logic inherent to it.

Logging method name , input parameters , date and time with using Attribute

i just want to make a class that inherited from Attribute class to put attribute tags in every method in my project to write the method name , Class name that have this method , date and time of calling , parameters and method's return ( if it's return something ).
i create a table in SQL Server that will receive all log information and sign it ..
i have done all the methods & query that interact with my database ( except Date & Time method) , the only problem is i don't know how to use it with Attribute way to get the information i have mention.
If you want logging with attributes, you may use PostSharp that modifies IL during compilation of your code and puts your logging codes before/after the method that you put your custom attribute derived from PostSharp's attributes (aspects)(AOP).
I think you can not do this only by use of custom attributes, because as I know custom attributes are instantiated only when Type.GetCustomAttributes() is called. So you may have to do some reflection business for sending your logs through your attributes that I don't recommend.
Instead of attributes, you can simply use AOP through a third party tool. You can use Castle Dynamic Proxy 's interceptor.
You can also log with attributes by using Interception in Castle Windsor.
To do this, you create a class that inherits from IInterceptor, register it with your container, then you can add an attribute to any class or method you want to add the logging behaviour to.
I've written an explanation here:
http://www.paulsodimu.co.uk/Post/Aspect-Oriented-Programming-Using-Castle-Windsor
And I've created a sample on GitHub to show how its done:
https://github.com/PaulSodimu/LoggingAopCastle

WCF Return Type Issue

I am using automapper to map a master class to various child classes.
Example: I have a class called VitalStatistics (master class). This class holds all fields for a record.
The company business rules indicate that only certain fields are needed based on the State location.
So, California may not all 20 fields found in the master class and may need only 10 fields instead of the 20. So I use automapper to map the VitalStatis class data to the CAVitalStats class which has only 10 fields. The TXVitalStats class may only have 3 fields. etc..
My web services need to return a type that these classes have in common. E.g. IVitalStatistics interface.
It seems as though the WCF service does not like an interface declared as the return type.
So, how can I get the service to return CAVitalStats or TXVitalStats? Normally if these both were of the same interface type then this would work because they all would be of type IVitalStatistics but the serialization messaging rules appear to have a problem with returning interface types.
I hope this made sense. Thanks
If you have CAVitalStats and TXVitalStats both inheriting from the same base class, for instance 'VitalStatsBase', then your service method could return VitalStatsBase.
To make this work with your 2 subclasses you'll need to use the KnownTypeAttribute in your service.
Below is a link describing the KnownTypeAttribute.
http://msdn.microsoft.com/en-us/library/ms730167.aspx

Resources