Just what are the conventions of the ODataConventionModelBuilder? - asp.net-web-api

There are lots of examples of using ODataConventionModelBuilder with simple, contrived models, often just a single class.
But there's nothing that actually explains what the conventions are; how to code a model that complies with convention. There's no official documentation for it.
So what's the convention?

From what I've seen so far, the conventions are those used by Entity Framework, as opposed to any new ones for OData. Please correct me if I am wrong.
More on Code-first conventions, below, but there are many more in the Julie Lerman book I have yet I cannot find an exhaustive list of them on the web.
http://blogs.msdn.com/b/efdesign/archive/2010/06/01/conventions-for-code-first.aspx
Update
The EF modelling conventions system is pluggable and each convention is represented by a class encapsulating the behaviour, and those classes are listed here:
http://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions(v=vs.113).aspx
However that doesn't help with which ones are applicable or used by the ODataConventionModelBuilder if any.
AssociationInverseDiscoveryConvention - Provides convention to detect navigation properties to be inverses of each other when only one pair of navigation properties exists between the related types.
AttributeToColumnAnnotationConvention - A general purpose class for Code First conventions that read attributes from .NET properties and generate column annotations based on those attributes.
AttributeToTableAnnotationConvention - A general purpose class for Code First conventions that read attributes from .NET types and generate table annotations based on those attributes.
ColumnAttributeConvention - Represents a convention to process instances of ColumnAttribute found on properties in the model.
ColumnOrderingConvention - Represents a convention to apply column ordering specified via ColumnAttribute or theDbModelBuilder API.
ColumnOrderingConventionStrict - Convention to apply column ordering specified via ColumnAttribute or theDbModelBuilder API. This convention throws if a duplicate configured column order is detected.
ComplexTypeAttributeConvention - Represents the convention to process instances of ComplexTypeAttribute found on types in the model.
ComplexTypeDiscoveryConvention - Represents a convention to configure a type as a complex type if it has no primary key, no mapped base type and no navigation properties.
ConcurrencyCheckAttributeConvention - Represents the convention to process instances of ConcurrencyCheckAttributefound on properties in the model.
Convention - A convention that doesn't override configuration.
DatabaseGeneratedAttributeConvention - Represents a convention to process instances of DatabaseGeneratedAttribute found on properties in the model.
DecimalPropertyConvention - Convention to set precision to 18 and scale to 2 for decimal properties.
DeclaredPropertyOrderingConvention - Represents a convention to move primary key properties to appear first.
ForeignKeyAssociationMultiplicityConvention - Represents a convention to distinguish between optional and required relationships based on CLR nullability of the foreign key property.
ForeignKeyDiscoveryConvention - Represents a base class for conventions that discover foreign key properties.
ForeignKeyIndexConvention - Represents a convention to introduce indexes for foreign keys.
ForeignKeyNavigationPropertyAttributeConvention - Represents a convention to process instances of ForeignKeyAttribute found on navigation properties in the model.
ForeignKeyPrimitivePropertyAttributeConvention - Represents a convention to process instances of ForeignKeyAttribute found on foreign key properties in the model.
IdKeyDiscoveryConvention - Convention to detect primary key properties. Recognized naming patterns in order of precedence are: 1. 'Id' 2. [type name]Id Primary key detection is case insensitive.
IndexAttributeConvention - A convention for discovering IndexAttributeattributes on properties and generatingIndexAnnotation column annotations in the model.
InversePropertyAttributeConvention - Represents a convention to process instances of InversePropertyAttribute found on properties in the model.
KeyAttributeConvention - Convention to process instances ofKeyAttribute found on properties in the model.
KeyDiscoveryConvention - Represents a base class for conventions that discover primary key properties.
ManyToManyCascadeDeleteConvention - Convention to add a cascade delete to the join table from both tables involved in a many to many relationship.
MappingInheritedPropertiesSupportConvention - Convention to ensure an invalid/unsupported mapping is not created when mapping inherited properties
MaxLengthAttributeConvention - Represents a convention to process instances of MaxLengthAttribute found on properties in the model.
NavigationPropertyNameForeignKeyDiscoveryConvention - Convention to discover foreign key properties whose names are a combination of the dependent navigation property name and the principal type primary key property name(s).
NotMappedPropertyAttributeConvention - Represents a convention to process instances of NotMappedAttribute found on properties in the model.
NotMappedTypeAttributeConvention - Represents a convention to process instances of NotMappedAttribute found on types in the model.
OneToManyCascadeDeleteConvention - Provides a convention to enable cascade delete for any required relationships.
OneToOneConstraintIntroductionConvention - Provides a convention to configure the primary key(s) of the dependent entity type as foreign key(s) in a one:one relationship.
PluralizingEntitySetNameConvention - Represents a convention to set the entity set name to be a pluralized version of the entity type name.
PluralizingTableNameConvention - Represents a convention to set the table name to be a pluralized version of the entity type name.
PrimaryKeyNameForeignKeyDiscoveryConvention - Convention to discover foreign key properties whose names match the principal type primary key property name(s).
PrimitivePropertyAttributeConfigurationConvention - Base class for conventions that process CLR attributes found on primitive properties in the model.
PropertyAttributeConfigurationConvention - Base class for conventions that process CLR attributes found on properties of types in the model.
PropertyMaxLengthConvention - Represents a convention to set a maximum length for properties whose type supports length facets. The default value is 128.
RequiredNavigationPropertyAttributeConvention - Convention to process instances ofRequiredAttribute found on navigation properties in the model.
RequiredPrimitivePropertyAttributeConvention - Represents a convention to process instances of RequiredAttribute found on primitive properties in the model.
SqlCePropertyMaxLengthConvention - Represents a convention to set a default maximum length of 4000 for properties whose type supports length facets when SqlCe is the provider.
StoreGeneratedIdentityKeyConvention - Represents a convention to configure integer primary keys to be identity.
StringLengthAttributeConvention - Represents a convention to process instances of StringLengthAttribute found on properties in the model.
TableAttributeConvention - Represents a convention to process instances of TableAttribute found on types in the model.
TimestampAttributeConvention - Represents a convention to process instances of TimestampAttribute found on properties in the model.
TypeAttributeConfigurationConvention - Base class for conventions that process CLR attributes found in the model.
TypeNameForeignKeyDiscoveryConvention - Convention to discover foreign key properties whose names are a combination of the principal type name and the principal type primary key property name(s).

The best explanation I'm aware of, is here
Routing Conventions in ASP.NET Web API 2 Odata
NB this is Odata 3, not odata 4

The conventions used in ODataConventionModelBuilder are described here.
As for how to code a model that complies with the conventions, that is pretty straight forward, or rather you don't need to code a model to the conventions at all. The conventions exist to simplify and standardize how an EF model is expressed in an OData Edm Model. If you find yourself manually enabling features, then you might find there is a convention that can automate this process for you. Understanding what the conventions are might help.
Your answer #LukePuplett describes some of the EF Code First conventions, they don't really apply here, not all directly anyway. I don't want to say you were wrong... ;)
The following is derived from the source code for ConventionModelBuilder.
Type and Property Conventions
NOTE: ordering is important here.
AbstractTypeDiscoveryConvention
configures all structural types backed by an abstract CLR type as abstract.
DataContractAttributeEdmTypeConvention
Configures classes that have the DataContractAttribute to follow DataContract serialization/deserialization rules.
NotMappedAttributeConvention
Ignores properties with the NotMappedAttribute from IEdmStructuredType
NotMappedAttributeConvention MUST run before EntityKeyConvention, or it will allow Keys to be excluded from the model
DataMemberAttributeEdmPropertyConvention
Configures properties that have DataMemberAttribute as optional or required on their edm type.
NOTE: This does not explicitly remove properties that have IgnoreDataMemberAttribute, but it will not explicitly add them either
DerivedTypeConstraintAttributeConvention
Adds Derived Type Constraints to the Model if required
RequiredAttributeEdmPropertyConvention
Marks properties that have RequiredAttribute as non-optional on their edm type.
DefaultValueAttributeEdmPropertyConvention
Sets default value for properties that have DefaultValueAttribute
ConcurrencyCheckAttributeEdmPropertyConvention
Marks properties that have ConcurrencyCheckAttribute as non-optional on their EDM type.
TimestampAttributeEdmPropertyConvention
Annotates a single column in a Type as the Timestamp column, even if multiple columns are annotated with the TimestampAttribute.
This is due to a SQL limitation table (the underlying concept this attribute is bounded to) that only supports one row version column per table.
ColumnAttributeEdmPropertyConvention
Marks properties that have ColumnAttribute as the target EDM type.
KeyAttributeEdmPropertyConvention
Configures properties that have the KeyAttribute as keys in the IEdmEntityType
KeyAttributeEdmPropertyConvention MUST run before EntityKeyConvention
EntityKeyConvention
This convention configures properties that are named 'ID' (case-insensitive) or {EntityName}+ID (case-insensitive) as the key.
ComplexTypeAttributeConvention
Removes primitive properties that are exposed through ComplexType definitions from the IEdmEntityType
This MUST run after Key conventions, basically overrules them if there is a ComplexTypeAttribute
IgnoreDataMemberAttributeEdmPropertyConvention
Removes properties that have IgnoreDataMemberAttribute from their edm type.
If class is a DataContract and DataMemberAttribute is present on this property, then the property will not be removed, DataMemberAttribute takes precedence
NotFilterableAttributeEdmPropertyConvention
Configures a column with fluent IsNotFilterable() if it has a NotFilterableAttribute annotation. This will specify that the property cannot be used in the $filter OData query option.
This is the same implementation as NonFilterableAttribute and its related NonFilterableAttributeEdmPropertyConvention
NonFilterableAttributeEdmPropertyConvention
Configures a column with fluent IsNotFilterable() if it has a NonFilterableAttribute annotation. This will specify that the property cannot be used in the $filter OData query option.
This is the same implementation as NotFilterableAttribute and its related NotFilterableAttributeEdmPropertyConvention;
NotSortableAttributeEdmPropertyConvention
Configures a column with fluent IsNotSortable() if it has a NotSortableAttribute annotation. This will specify that the property cannot be used in the $orderby OData query option.
UnsortableAttributeEdmPropertyConvention
Configures a column with fluent IsNotSortable() if it has a UnsortableAttribute annotation. This will specify that the property cannot be used in the $orderby OData query option.
NotNavigableAttributeEdmPropertyConvention
Configures a column with fluent IsNotNavigable() if it has the NotNavigableAttribute annotation. This will specify that the property cannot be navigated in OData query.
This does not preclude $expand, it means that the propert cannot be used to traverse to the associated resource using an Entity Path, for instance if ProductType had this attribute, and was a navigation property that returned a ProductType reference, the following OData path would not be servived: ~/api/products(112)/ProductType this is a feature from the updates to support Containment.
NotExpandableAttributeEdmPropertyConvention
Configures a column with fluent IsNotExpandable() if it has a NotExpandableAttribute annotation. This will specify that the property cannot be used in the $expand OData query option.
NotCountableAttributeEdmPropertyConvention
Configures a column with fluent IsNotCountable() if it has a NotCountableAttribute annotation. This will specify that the $count cannot be applied on the property.
MediaTypeAttributeConvention
Configures a class with fluent MediaType() which marks this entity type as media type.
AutoExpandAttributeEdmPropertyConvention
Configured the AutoExpand feature of a column when it has the AutoExpandAttribute annotation.
AutoExpandAttributeEdmTypeConvention
When AutoExpandAttribute is placed on a class it can specify all navigation properties are auto expanded.
MaxLengthAttributeEdmPropertyConvention
Configures string or binary properties that have the MaxLengthAttribute annotation.
PageAttributeEdmPropertyConvention
Sets the page size and Max Top of the entity type based on the PageAttribute annotation if present on any of the properties in the class.
There is no added value of supporting this on a property level, but it is offered as a redundancy for poorly configured code.
PageAttributeEdmTypeConvention
Sets the page size and Max Top of the entity type based on the PageAttribute annotation on the class.
ExpandAttributeEdmPropertyConvention
Configures OData $expand query option for navigation columns with ExpandAttribute annotation.
ExpandAttributeEdmTypeConvention
Set the ExpandConfigurations of navigation properties of this structural type based on the ExpandAttribute annotation on the class.
CountAttributeEdmPropertyConvention
Configures the $count OData query options for specific columns with the CountAttribute annotation. The $count OData query option can be explicity enabled or disabled with the CountAttribute annotation.
CountAttributeEdmTypeConvention
Set whether the $count can be applied on the edm type. The $count OData query option can be explicity enabled or disabled with the CountAttribute annotation.
OrderByAttributeEdmTypeConvention
Configures the OData $orderby query option settings for a type based on the OrderByAttribute on the class or on the properties.
When used on a class, the default $orderby value can be specified.
When used on properties it can also prevent that property from being referenced in an $orderby OData query option.
FilterAttributeEdmTypeConvention
Configures the OData $filter query option settings for a type based on the FilterAttribute on the class or properties.
OrderByAttributeEdmPropertyConvention
Configures the OData $orderby query option settings for a type based on the OrderByAttribute on the class or on the properties.
When used on a class, the default $orderby value can be specified.
When used on properties it can also prevent that property from being referenced in an $orderby OData query option.
FilterAttributeEdmPropertyConvention
Configures the OData $filter query option settings for a type based on the FilterAttribute on the class or on the properties.
When used on a class, the default $filter value can be specified.
When used on properties it can also prevent that property from being referenced in an $filter OData query option.
SelectAttributeEdmTypeConvention
For classes that have SelectAttribute, the attribute will list the properties that can be referenced by the $select OData query option for this structural type.
SelectAttributeEdmPropertyConvention
Configures the OData $select query option settings for a type based on the SelectAttribute on the class or on the properties.
When used on a class, the default $select value can be specified.
When used on properties it can also prevent that property from being referenced in an $select OData query option.
INavigationSourceConvention's
SelfLinksGenerationConvention
Generates Item and Edit links in the OData annotations.
NavigationLinksGenerationConvention
Generate links without cast for declared and inherited navigation properties, or with a cast in derived types.
AssociationSetDiscoveryConvention
This convention adds an association set for each EDM navigation property defined in this type, its base types and all its derived types.
The target navigation source chosen is the default navigation source for the navigation property's target entity type.
The default navigation source for an entity type is the navigation source that contains entity of that entity type.
If more than one navigation source match, the default navigation source is none.
If no navigation sources match the default navigation source is the default navigation source of the base type.
IEdmFunctionImportConventions's
ActionLinkGenerationConvention
calls action.HasActionLink(..) if the action binds to a single entity and has not previously been configured.
FunctionLinkGenerationConvention
calls function.HasFunctionLink(..) if the function binds to a single entity and has not previously been configured.
Interesting notes:
I tried to do some research on the history of NotFilterableAttribute vs NonFilterableAttribute but struggled to find a point of divergence in the open source libraries. Both of these attributes exist in the VS 2013 help docs and the System.Web.OData.Query namespace. I assume at one point two different namespaces or libraries were merged together and the attributes were retained for backward compatibility.
What should have happened in the associated commit was that one of these attributes should have been deprecated (annotated with [Obsolete]) and in a future version that deprecated class should have been removed, certainly long before now.
This same situation exists with NotSortableAttribute and UnsortableAttribute...
Some of these conventions have the same implementation in two different convention classes, one mapped to the Entity Type, the other to the Property. At first glance this looks redundant, but it is necessary for attributes that support both class and property annotation. The reason it is necessary is that the presence of the associated attribute triggers the convention to be evaluated at all. The OData conventions do not operate like the EF code first conventions that evaluate all types and properties for a match. The model is iterated, not the conventions. A class level attribute application, like PageAttribute if we want to allow it to be specified on the property it still needs to apply the logic to the Edm Type. The reverse is try to for FilterAttribute that can be declared once on the Edm Type with an array of properties, or you can manage the properties individually, you might even have both, with property level attributes to explicitly prevent $filter access.
I can only speculate that someone decided that this was a necessary performance measure as these conventions are evaluated at runtime, we could measure it later if anyone is interested ;)
For these classes that have multiple similar implementations, I would have designed the logic such that there was a single class that defined the common logic and the concrete types would reference it. This satisfies the DRY principal but also makes the code and patterns like this more discoverable.

Related

Read null as empty set in springdata-cassandra

I use spring-data-cassandra, and have entity like this:
#Table("users")
public class User {
#Column("permissions")
#CassandraType(type = DataType.Name.SET, typeArguments = {DataType.Name.TEXT})
public Set<String> permissions = new HashSet<>();
}
In cassandra I have table users with field permissions of type Set. It works fine when I store some values in the set, but when I try to store empty set, it becomes null when I read such entity from the repository.
Is there a way to force spring-data-cassandra to change null to empty HashSet? Or can I somehow add custom reader for this specific property of the entity?
TL;DR;
That's Cassandra's default behavior to return null for empty Collection and Map-typed columns.
Further Read
Cassandra returns null values for lists, sets, and maps, which do not contain any items. This is especially unfortunate when using classes with pre-initialized fields as seen in your question. There's an open ticket (DATACASS-266 - Loading empty collection-typed properties overwrites pre-initialized fields) in the issue tracker - as of now, without comments or votes.
We're not exactly sure whether it's a good idea to skip setting properties or apply some sort of defaulting when dealing with empty (null) collections as this raises follow-up questions what to do when:
Creating an instance through constructor creation: A value is required in such case. For property access, we could omit to set the property, for constructor creation we must provide a value.
The pre-initialized collection contains items but the one received from Cassandra is null.
We assume, the change would be applied, what will happen with already existing code that assumes empty collections default to null.
A possibility to address this behavior could be configuration on MappingCassandraConverter or an extension point to override so users can apply their own empty collection behavior.
I've been trying to eliminate the null collections in my model objects as well, and while it may not be possible to do that at the Spring Data level currently (version 2.1.x), there are some options you can consider:
Use property access for the field in question (i.e. use the annotation #AccessType(PROPERTY)), and in the setter method, set the field to an empty collection when the argument is null.
Define a compatible (see below) constructor that sets the field to an empty collection when a null is provided (and if the model is mutable, you may still want to provide the setter as above).
There are some caveats to ensure Spring Data Cassandra uses the desired constructor (e.g. don't provide a no argument constructor), so it's critical to review the "Object Mapping Fundamentals" section of the reference guide (https://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#mapping.fundamentals).
Among the recommendations in that reference guide (as of version 2.1 at least) is to use an all argument constructor and make model objects immutable, which would work well with the constructor-based approach to handling nulls. Though it does mean writing and maintaining the constructor to handle the nulls rather than relying on Lombok's #AllArgsConstructor.
I have used the property access approach in one case, but not the constructor approach. However I do intend go the constructor route when adding new or model classes (I'm a fan of immutable objects, and will explore that route even without any collection fields)
I believe Spring Data Cassandra 2.0 also added persistence lifecycle callbacks which is another possible option I suppose, but I ruled that out, mainly because the logic would not reside in the model class itself (as well as going against the recommendations from the creators of the framework)

Elasticsearch NEST DefaultMappingFor usage

Currently, I have been adding mapping through REST Api and programatically indexing documents using NEST.
However, I recently came across NEST's DefaultMappingFor (in ConnectionSettings) and wondering how it's used. (Won't be able to spike soon hence asking.)
Question: In the source code, if I set mapping using the DefaultMappingFor, does that mean it is not necessary to create the mapping using the Rest Api because, maybe(I think), and NEST will use the declared default mapping whenever a document is indexed?
Thank you.
DefaultMappingFor() and DefaultMappingFor<T>() allows you to configure defaults for a given CLR type. Both allow you to configure:
The default index name to use, through the .IndexName() method
The default type name to use, through the .TypeName() method
The default relation name to use when mapping as Parent/Child relationship, through the .RelationName() method
In addition, DefaultMappingFor<T>() allows you to configure:
The property on the type to use for the id of the document through the .IdProperty() method
The property on the type to use for the routing parameter (useful to set for Parent/Child relationships, but also when you need routing), through the .Routing() method
Which properties to ignore when serializing the type through the .Ignore() method
Which properties should be serialized with different field names through the .PropertyName() method
Setting any of these for a type means that NEST will use these over any conventions it has. The typical ones to use are .IndexName() and .TypeName() (although types are removed in Elasticsearch 6.x), and means that you don't need to specify either of these on each request (unless you want to override this default mapping too).

Guidelines of updating business network without breaking compatibility using Composer?

As updating business network could break your APIs and You may not able to fetch old data. We are looking for generic guidelines about what we should take care before updating business network and deploying using composer.
We will include this into the docs for the release next week...
Model Compatability
Introduction
Composer models are expected to change and evolve over time. However some care and discipline must be applied when making model changes to ensure that existing instances are still valid with respect to the new model.
A model M' is compatible with model M if instances created with model M are valid with respect to model M'. If the instances are valid, then they may be deserialized using the Serializer.
Terminology
The following terms are used throughout this document:
Class : the declaration of the structure of an asset, participant, transaction, concept or event
Instance : an instance of a class, for example if org.example.Vehicle is an asset (class), then org.example.Vehicle#ABC123 is an instance of an org.acme.Vehicle
Property : a member (or field) defined by a class, including a relationship. For example the class org.example.Vehicle may have a property called model of type string.
A class (the asset SampleAsset):
```
namespace org.acme.sample
asset SampleAsset identified by assetId {
o String assetId
--> SampleParticipant owner
o String value
}
```
An instance of the class:
{
"$class": "org.acme.sample.SampleAsset",
"assetId": "assetId:6463",
"owner": "resource:org.acme.sample.SampleParticipant#participantId:8091",
"value": "secret plant frequently ruler"
}
Evolution of Namespaces
A new class may be added to a namespace without breaking compatibility with pre-existing instances.
Evolution of Classes
This section describes the effects of changes to the declaration of a class and its properties on pre-existing instances.
Renaming
Renaming a class will break compatability with any pre-existing instances of the class, or relationships to the class.
abstract Classes
If a class that was not declared abstract is changed to be declared abstract, then attempts to create new instances of that class will throw an error at runtime; such a change is therefore not recommended for widely distributed classes.
Changing a class that is declared abstract to no longer be declared abstract does not break compatibility with pre-existing instances.
Superclasses
An error is thrown at load time if a class would be a superclass of itself. Changes to the class hierarchy that could result in such a circularity when instances are loaded are not recommended for widely distributed classes.
Changing the direct superclass of a class type will not break compatibility with pre-existing instances, provided that the total set of superclasses of the class type loses no properties.
If a change to the direct superclass results in any class no longer being a superclass respectively, then errors may result if pre-existing instances have relationships to the modified class. Such changes are not recommended for widely distributed classes.
Class Properties
No incompatibility with pre-existing instances is caused by adding a property to a class if the property is either declared as optional or is assigned a default value. Adding new properties that are neither optional nor have a default will break compatability with any pre-existing instances of the class.
Changing the cardinality of a property (changing an array [] to a non-array or vice-a-versa) will break compatability with any pre-existing instances of the class.
Deleting a property from a class will break compatibility with any pre-existing instances that reference this field.
Changing the type of a property may cause an error if the property is used by a pre-existing instance.
Changing the validation expression of a property may cause an error if the property is used by a pre-existing instance.
Properties that are relationships follow the same rules as for other types.
Evolution of Enums
Adding or reordering constants in an enum type will not break compatibility with pre-existing instances.
If a pre-existing instance attempts to access an enum constant that no longer exists, an error will occur. Therefore such a change is not recommended for widely distributed enums.
In all other respects, the model evolutions rules for enums are identical to those for classes.

What features does mogenerator provide?

I've been using mogenerator for a while now, and while there is a reasonable Getting Started Guide and a Stack Exchange article on the command line options, I haven't found a good guide for all of the functionality it provides.
In short: what, above and beyond the classes that Core Data provides for you, what does mogenerator actually generate?
(Frankly, I kept finding little pleasant surprises in the headers/implementations that I didn't realize were in there and I decided to step through the mogenerator templates and code and document what I found in a Stack Exchange Q&A. I'd love to see additional answers and edits, however. )
In addition to its core feature of a two class system, mogenerator helps you by automatically implementing a number of best practices regarding Core Data in your machine header and implementation files.
Property Accessors
Methods to access the attributes of your Entities are the core of what mogenerator generates. But there are some nice features implemented in the accessors above and beyond what the out of the box Xcode class generator provides to you.
Scalar Accessors
Xcode's built in generator gives you the option of "use scalar properties for primitive data types". This option gives you choice of having Xcode create properties with NSTimeIntervals instead of NSDates for date types, BOOLs instead of NSNumbers for boolean types, and int16_t (or similar) rather than NSNumbers.
I find this infuriating because most of the time I prefer the primitive types, but not for NSDates which are much more useful than a NSTimeInterval. So Core Data is giving me the choice of objects, in which case I will be constantly unboxing stuff and making stupid mistakes like if(myBooleanAttribute) (which is always YES because myBooleanAttribute is a NSNumber, not a BOOL). Or I can have scalars, but in that case, I get NSTimeIntervals that I'll always have to convert to NSDates. Or I can hand edit all of the generated files by hand to give me my desired mix of NSDates and BOOLs.
On the other hand, mogenerator provides you with both options. For example, you will get both a myBooleanAttribute getter that gives you an NSNumber (for easy storage in an NSArray) and a myBooleanAttributeValue getter that gives you an actual BOOL. Same with integers and floats. (Mogenerator does not generate NSTimeInterval accessors: only NSDates.)
Typed Transformable Properties
If you have a transformable property, you can set a specific UserInfo key ( attributeValueClassName ) in the attribute that will specify the class that your property will return/accept. (And it will properly forward declare the class etc.) The only place I found this documented was on Verious.
In contrast, the Xcode code generator will only type these transformable attributes as id types.
Validation Declaration
While mogenerator does not automatically generate any validation methods, it does include the proper signature as a comment in the machine h file. The seems to largely be for historical reasons, but it does mean that it is easy to copy and paste the signature if you decide to implement it in your human file implementation. (I wouldn't actually uncomment the declaration as you aren't supposed to call validation directly.)
Primitive Accessors
Core Data already provides you these accessors to the primitive values, but for some reason doesn't include them in its Xcode generated headers. Having mogenerator include them in its header files makes it much easier to access a primitive value.
Fetched Properties
mogenerator will generate accessors for fetched properties. As far as I can tell there is no way to have the Xcode generator do this.
Helper methods
Automatic NSFetchedResultsController generation
If you have a to many relationship in your Entity and you pass --template-var frc=true into mogenerator, mogenerator will automatically generate a method to create a fetch request for the child objects associated with a parent object. It even automatically generates a unique cache name, and isolates everything inside an #if TARGET_OS_IPHONE preprocessor macro.
Even if this doesn't fit your particular needs, it is a great example of how the templates can be extended.
+fetchMyFetchRequest:moc_
If you like defining your fetch requests in the model, this is a lot better way to retrieve them than hardcoded strings.
-MyEntitySet
Mogenerator uses the magic of KVC to give you a NSMutableSet proxy into your relationships.
+entityName
Need to provide a entity name to a NSFetchRequest or other Core Data method? It's easy to avoid hard coded strings by using this simple method that returns the name of the entity as an NSString.
+insertInManagedObjectContext: and entityInManagedObjectContext:
Another way to avoid hardcoding entity names is to use these helper methods.
Typed object ids
Each of your headers and implementations also includes a MyEntityID class. They are empty interfaces and implementations that merely subclass the NSManagedObjectID class. Also, each model class has a helper method called objectID that overrides the standard objectID method in NSManagedObject. The helper method does nothing but cast the superclass's return value to the MyEntityID type.
The net result: the compiler can catch your mistakes if you ever accidentally interchange your object ids from different entities.
Miscellaneous
Subclassing a Custom Superclass
One of the command line options is --base-class: which allows you to specify a base class that all of your generated classes will inherit from. This is very useful, either so that you can have a base class where you define convenience methods (which, given Core Data, you probably should) or so you can use an off the shelf Core Data toolkit like SSDataKit (or both).
includem
A simple little thing, but if you specify a --includem argument, mogenerator will generate a header file that includes all of your model header files. Convenient if you want to include all of your headers in a PCH, or something some other standard header you include.
Const Definitions of All Attributes, Relationships, Fetched Properties
An extern declaration of a struct is included in the header that has an NSString defined for every attribute and relationship defined in your Entity. This allows you to define predicates and other parameters, without baking the names of your entities into your strings. For example,
req.predicate = [NSPredicate predicateWithFormat:
#"(%K == YES) AND (%K <= %#)",MyObject.favorite, MyObject.availableDate, [NSDate date]];
(This type of struct used for "namespaced" constants is described My Mike Ash on his blog
const Definitions of User Info Keys/Values
Similarly an extern declaration of a struct is defined in the header that includes the keys as members of the struct, and the values as a values. i.e.
NSLog(#"User info for key my key is %#",MyObjectInfo.mykey) //will log "myvalue"
Alternate Templates
One of the interesting things about mogenerator is that in building mogenerator its author (Wolf Rentzsch) has basically built a generic parser and templating engine for the xcdatamodel files produced by Xcode. So you don't need to use the mogenerator templates. You can provide your own with a simple command line argument. There are lots of user contributed templates on the GitHub site.
In fact, you don't even have to use Core Data. Many of the contributed templates allow you to generate a series of ordinary NSObject model classes based on the data model. (So called PONSOs: "plain old nsobjects"). Want to use the data modeler in Xcode, but some other persistence mechanism? mogenerator can help you there.
You don't even need to generate objects at all: another interesting submitted template just provides a diff of two different model versions.

Is there a reason why the default modelbinder doesn't bind to fields?

I'm using ASP.NET MVC3 and i'm wondering that the default modelbinder binds to public properties but not to public fields.
Normally i just define the model classes with properties but sometimes i use some predefined classes which contains some fields. And everytime i have to debug and remember that the modelbinder just don't like fields.
The question: Whats the reason behind it?
but sometimes i use some predefined classes which contains some fields
While I cannot answer your question about the exact reason why the default model binder works only with properties (my guess is that it respects better encapsulation this way and avoids modifying internal state of the object which is what fields represent) I can say that what you call predefined classes should normally be view models. You should always use view models to and from your controller actions. Those view models are classes that are specifically defined to meet the requirements of the given view.
So back to the main point: fields are supposed to be modified only from within the given class. They should not be accessed directly from the outside. They represent and hold internal state of the class. Properties on the other hand is what should be exposed to the outside world. Imagine that in the property getter/setter you had some custom logic. By modifying directly the field this custom logic would be broken and potentially bring the object into an inconsistent state.
Maybe the reason for ignoring fields is to increase performance of the binder. Instead of searching all the Fields and properties. The Model Binder search for Properties only.
Though I think the Model Binder use cache to improve performance.
DefaultModelBinder exposes a public method:
DefaultModelBinder.BindModel, and a number of protected method available for overriding. All of them listed here.
Besides the model, these method refer to properties only, not fields, like
GetModelProperties,
GetFilteredModelProperties,
GetPropertyValue,
OnXYZValidating,
OnXYZValidated,
OnXYZUpdating,
OnXYZUpdated,
GetXYZValue,
where XYZ stands for either Model, or Property/ies, or both, and so on.
As you can see there is no Fields mentioned with these names whatsoever. As Darin explained no direct changes to Model's state are tolerated by the Binder. Hence no Field in its methods.
And also, you may wish to take a look at another important class: ModelBindingContext. An instance of this class gets passed to the BindModel, and subsequently to BindSimpleModel, and BindComplexModel, depending on model type (string, int,... are considered simple, everything else is complex).
So, this context has the following properties:
ModelXYZ, and
PropertyXYZ.
In other words you have no means to reference the fields in your ViewModel unless you do not override these classes and undertake special actions to do so.
But again, beware of fighting the framework, its always easier to follow it instead.
EDIT: The ModelMetadata class holds all the data needed to bind the model. Its code however, shows no sign of fields, field names, etc. Only properties are referenced and accessed. So, even if you try to inherit and override DefaultModelBinder and ModelBinderContext, you still won't be able to access fiellds, nevermind what their access modifier is: public, private, etc.
Hope this explains most of it.

Resources