We are happy to announce that the OData Client Code Generator is released and available on Visual Studio Gallery. In this release, we focused on lighting up more OData features and the usability of the generated APIs while preserving the most consistency with the former version. Following is the release notes:
Improvements of this OData Client Code Generator update
Usability
- The exception message about the “MetadataDocumentUri” value not filled in before running the code generator is improved.
- The exception message about failed to generated proxy of a service whose metadata document access needs authentication is improved.
- The configuration of the code generation is now migrated into the .tt template file.
It increases the usability of the template in the following ways:
-
- Before this improvement, users may forget toregenerate the code by saving the .tt template file or “run custom tools” after they’ve modified the configuration in the .odata.config file. Now, as the configurations are in the .tt file, whenever it is changed and saved, the code will always be regenerated.
- The configuration can be included as C# codes inthe .tt file, which is more readable and referencable after having installed some extension for T4 templates:
- The type of the generated class for singletons is redesigned.
It was formerly designed as a DataServiceQuery<T> class. Which has the limitation that
-
- It supports query options that shouldn’t be supported by singletons logically. (e.g. $filter, $orderby, and etc.
- Executing the singleton (e.g. context.Boss.Execute()) returns an IEnumerable<T> (e.g. IEnumerable<Person>). It means that users can iterate through a singleton to get the actual single object contained, which is weird logically
- The fact that the singleton class has to Execute()to get the type and it is a DataServiceQuery<T> has the problem that it doesn’t support nested navigation calls (also called as “delayed query” since you can delay the execution of the query until you explicitly execute it) such as context.Boss.Wife.Company.Execute()as navigation properties are not implemented on DataServiceQuery<T> but the entity type classes.
Now it is redesigned as a DataServiceQuerySingle<T> class, which
-
- Has its native implementation of OData query options supported by singletons
- Doesn’t implements IEnumerable<T> or IQueryable<T> so that users may not iterate through it
- Has a GetValue() method whose return type is the type of the singleton
- Has all the navigation properties of the T type implemented on it so it can support delayed query.
With this redesign and a few new APIs introduced on DataServiceQuery<T>, the generated client side proxy can better support complex queries and support them in a more usable way:
Scenario | Query | Client code in old version | Client code in new version |
Get a boss singleton | GET http://host/service/Boss | Person boss = context.Boss.First(); | Person boss = context.Boss.GetValue(); |
Get the parent of the boss of the company whose ID is 1 | GET http://host/service/Companies(1)/Boss/Parent | Not possible | Person bossesParent = context.Company.ByKey(new Dictionary<string, object>() {{“ID”, 0}}).Boss.Parent.GetValue(); |
Functionality
- Now the client side proxy can be generated referencing a metadata document which is stored in a local file.
This lights up the scenario of generating client side proxy for services whose metadata document access needs authentication. Upon such services, customers can access the metadata document using a web browser then download and store the metadata in a local file. The value of the “MetadataDocumentUri” variable in the configuration file can be set to a local path such as “File:///C:/Odata.edmx” or @”C:Odata.edmx”.
- Now the code generator supports generating proxy according to metadata documents which reference external CSDL documents.
- Code generation of some actions & functions defined in the model is supported.
Following kinds of operations are supported now: function imports, action imports, actions & functions bound to collection of entities, actions & functions bound to an entity type.
Configurability
- A configuration is added to the configuration file “ODataClient.tt” enable the conversion from lower camel case property, entity and namespace names (e.g. “myName”) to upper camel case ones (e.g. “MyName”).
// This flag indicates whether to enable naming alias. The value must be set to true or false.
public const bool EnableNamingAlias = true;
If the “EnableNamingAlias” is set to true, all the names of the properties generated will have be in upper camel case. If it is set to false, the original case defined in the model will be preserved.
Bug fixes
- Fixed the bug of generated client code missing System.Nullable<> for nullable EnumType.
- Fixed the bug that some of the global namespace in the code generated are missing “global::” prefix which can cause a namespace collision.
- Fixed the bug that the T4 templates adds a trailing slash to the end of the metadata document URI. This is actually the default address for “Metadata as a Service”.
Features enabled by the OData core and client library updates
- The code generator can now recognize the inheritance relationship between complex types in the metadata document and generate the complex type classes reflecting thisrelationship.
- The client property tracking is supported by the generated proxy (see this blog post for details) to reduce the payload size for update requests.
- Using enum type objects in query options & operation parameter is now supported.
- The API of OData client for server-side paging support is improved.
Sample:
NorthwindEntities ctx = new NorthwindEntities(new Uri(@”http://services.odata.org/V4/Northwind/Northwind.svc/”));
var customers = ctx.Customers.GetAllPages(); // automatically get all pages of the Customers entity set
foreach (var customer in customers)
{
Console.WriteLine(customer.CustomerID);
}
- The API of OData client for server-side paging support is improved.
- New asynchronize API in .NET 4.0 format is supported.
0 comments