[Announcement] OData Client Code Generator 2.0.0 release

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


  • 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:

    1. 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.
    2. 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

    1. It supports query options that shouldn’t be supported by singletons logically. (e.g. $filter, $orderby, and etc.
    2. 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
    3. 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

    1. Has its native implementation of OData query options supported by singletons
    2. Doesn’t implements IEnumerable<T> or IQueryable<T> so that users may not iterate through it
    3. Has a GetValue() method whose return type is the type of the singleton
    4. 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:



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();


  • 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.


  • 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.


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)




  •  The API of OData client for server-side paging support is improved.
  • New asynchronize API in .NET 4.0 format is supported.
Comments (41)

  1. Amalah &#39;MSDN&#39; says:


    Many aspects that were missing in previous version are now there!:

    – Actions, Access by keys, Singleton, Navigation properties…

  2. AdamCaviness says:

    Thank you!  These are nice improvements we'll start using immediately.  Thanks for the prompt post about it as well.

  3. saramgsilva says:

    This can used for Office 365 REST API


    I know there is the Office 365 API Preview, but I am not talking about it… :)

  4. saramgsilva says:

    my last comment is a question, I wasn´t clear :/

  5. Yi Ding - MSFT says:


    Yes, it can. But there are a few things to notice when you do that:

    1. The access to metadata document of the Office 365 APIs needs authentication. The OData Client Code Generator doesn't have a native support for metadata document authentication. In order to generate the client proxy for those APIs, you need to download the metadata document of them using browser and save it as a local file, from which you can generate proxy. After the proxy is generated, you can using that to consume Office 365 APIs. The credential can be set using DataServiceContext.Credentials.

    2. Compared to our generated proxy, the "Office 365 API Tools – Preview" has a lot of customization to the O365 APIs and has different design philosophy applied to it. For example, all the request sending methods in it's SDK are asynchronize APIs, and it follows an explicit execution pattern that you must explicitly call "ExecuteAsync()" to send the request. It's also has great tooling UI. You can choose either one which best meet your requirement. :)

  6. Junlin Zheng says:


    And in addition, the code generated by O365 API Tools may not work as expected when you need change tracking. :)

  7. ta.speot.is says:

    This requires Microsoft.OData.Client 6.5.0 which drops SL5 support. So if you're using a PCL target that includes SL5 (whether you actually develop for it or not) it seems that you can't upgrade to 6.5.0

  8. LMK says:

    Hi, is there any chance of supporting the linq "Contains" function in order to generate multiple-or filters automatically? This would be really useful. See here: stackoverflow.com/…/odata-where-id-in-list-query

  9. Stephen says:

    Thanks for the update.  What is the best way for us to report issues or bugs with this release?  Is there a project on CodePlex?



  10. Yi Ding - MSFT says:


    It's already supported.

    e.g. By writing the following code calling the proxy generated against the V4 sample service services.odata.org/…/odata.svc:

    var context = new DemoService(new Uri("services.odata.org/…/"));

    var products = context.Products.Where(c => c.Name.Contains("a"));

    foreach (var product in products)




    The request captured in Fiddler is GET /V4/OData/OData.svc/Products?$filter=contains(Name,'a').

  11. Yi Ding - MSFT says:


    There is a project on CodePlex: http://odata.codeplex.com. But it's currently only for sharing the source code of the client.

    Currently there are following ways for you to report the issue:

    1. Comment on this blog post.

    2. Write an email reporting the issue to odatafeedback@microsoft.com

    3. Report the issue to the Visual Studio Gallery entry of the project.

    We are planning on having better ways for you to report issues and as soon as it's ready, we will announce on this blog.

  12. LMK says:

    Sorry, if you have a look at that StackOverflow article, I'm not talking about string contains (AKA SQL "like"), I'm talking about collection contains.

    i.e being able to do

    dim coll = {"X", "Y", "Z"}

    dim result = cx.items.where(function(i) coll.Contains(i.name))

    Which would translate into something like:

    $filter=(name eq 'X') or (name eq 'Y') or (name eq 'Z')

    That is a very common construct and would be highly useful if OData proxy supported it. Thanks.

  13. ImGonaRot says:

    Not sure where to post BUGS. I posted 2 bugs visualstudiogallery.msdn.microsoft.com/…/Discussions and will re-post them here just so they don't get missed.

  14. ImGonaRot says:

    Let's assume you have an odata model called customer with 2 properties. ID and CustomerName. Let's also assume there is NO customer record in the database that has an ID of 2.

    Now from the client you have the following:

    (from x in dbContext.Customer where x.ID = 2 select x.ID, x.CustomerName)

    This line of code will fail.

    "The 'ObjectContent`1' type failed to serialize the response body for content type" AND

    ""'SingleResult`1' cannot be serialized using the ODataMediaTypeFormatter."

    but if you change to code to use the "AddQueryOption" then it works.

    (from x in dbContext.Customer.AddQueryOption("$filter", "ID eq 2") select x.ID, x.CustomerName)

    works just fine.

    Please NOTE there is NO customer record of ID = 2 in the database.

  15. ImGonaRot says:

    Let's assume you have an odata model called customer with 2 properties. ID and CustomerName.

    Now from the client you have the following:

    (from x in dbContext.Customer where x.ID == 3 select x.ID)

    This line of code will fail.

    "No HTTP resource was found that matches the request URI 'http://localhost:63344/odata/Customer(3)/ID&quot;

    but if you change to code to select more property then it works.

    (from x in dbContext.Customer where x.ID == 3 select x.ID, x.CustomerName)

    works just fine.


    Notice the URL has the select where the previous URL does not.

  16. AdamCaviness says:

    How do I keep the OData Client Code Generator from generating the singleton classes that derive from the new DataServiceQuerySingle<T> class?  With hundreds of models I don't want those generated.  I don't currently have a use case for the new singleton feature.  Could you modify the generator to inspect the $metadata of the server to determine when to emit these new "Single" classes?  Thanks for your assistance.

  17. Junlin Zheng says:


    Hi LMK, I may suggest you to accomplish what you want by implementing an unbound function to be used in "$filter" in your service if I didn't understand your needs wrong. Based on what you're asking for, it's more like a specific function which may accept a collection and a string(name) as its arguments does. Then in your service, you can implement this function as to check whether the string(name) is contained by the collection. That will make more sense to me in this way.

    Please kindly note that because of the indirect usage that might come with unbound operations generated in client(except operation imports), we didn't support generating unbound operations in T4 template yet. If you actually give what I said above a try, you can call it in client with AddQueryOption("$filter", qualifiedFunctionNameWithInlineParameters) in DataServiceQuery.

  18. Yi Ding - MSFT says:


    Currently there is no such configuration of ignoring desired parts of the model. And we would probably not add such a configuration because of the following reasons:

    1. The elements in the EDM model reflects what the service implementer wants to expose to its consumer. The code generated proxy should also stick to it by generate everything it recognizes in the model.

    2. The requirement behind this configuration seems to be a very unique one to your purpose but the work to do if we were to support it may be huge if we do it generically. If we were to add configuration for ignoring singletons in the model, we would also need to think about implementing similar ones for ignoring actions, functions, entity sets, properties, navigation properties, relationships, and so on. There are much work needed but probably very few of users will ever use them.

    3. The workarounds for your asks are pretty simple and straightforward:

       a. if you are the implementer of the service, you can hide the singletons from the metadata document.

       b. if you are familiar with the T4 template, you can customize it by commenting out the part for generating singleton classes.

       c. you can delete the singleton classes generated in the proxy code.

    We would also suggest that you can just not use the generated singleton classes by not using them in your client application code. Maybe you can elaborate more on the scenarios of why you want the singleton classes not generated (e.g. you are developing a mobile app using the generated proxy and the proxy containing too many things are causing your app size too big and mobile app size usually matters). And you can also turn to the three workarounds provided above if you really need to not generate them.

  19. Junlin Zheng says:


    Hi, I tried your sample code with our own service but all the exceptions occurred to you didn't show up.

    var id = (from x in Context.Customers where x.ID == 10000 select x.ID).Single();

    var idAndName = (from x in Context.Customers where x.ID == 10000 select new Customer {ID = x.ID, Name = x.Name}).Single();

    The above sentences are all working fine, with respectively urls as



    Exceptions are only thrown when there's no Customer corresponding to the specific ID exists, and the exceptions will be NOT FOUND. Besides, I don't see code like "from x in dbContext.Customer where x.ID = 2 select x.ID, x.CustomerName" will pass the compilation.

  20. ImGonaRot says:

    @Junlin Zheng

    I should have specified that the sample code is VB.NET.

  21. ImGonaRot says:

    Bug when returning string array. — VB.NET

    Let's assume you have a odata service that returns a string array.

    If you try to run the OData client template against the OData service that returns the string array then the generated client code will have a have a namespace of "System" and a class of "String[]".

    This will of course break all code since it is using the "System" namespace.

    'Generation date: 7/31/2014 4:56:19 PM

    Namespace System


       '''There are no comments for String[] in the schema.


    <Global.Microsoft.OData.Client.OriginalNameAttribute("String[]")>  _

       Partial Public Class String[]

           Implements Global.System.ComponentModel.INotifyPropertyChanged

           ''' <summary>

           ''' This event is raised when the value of the property is changed

           ''' </summary>

           <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "2.0.0")>  _

           Public Event PropertyChanged As Global.System.ComponentModel.PropertyChangedEventHandler Implements Global.System.ComponentModel.INotifyPropertyChanged.PropertyChanged

           ''' <summary>

           ''' The value of the property is changed

           ''' </summary>

           ''' <param name="property">property name</param>

           <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "2.0.0")>  _

           Protected Overridable Sub OnPropertyChanged(ByVal [property] As String)

               If (Not (Me.PropertyChangedEvent) Is Nothing) Then

                   RaiseEvent PropertyChanged(Me, New Global.System.ComponentModel.PropertyChangedEventArgs([property]))

               End If

           End Sub

       End Class

       ''' <summary>

       ''' Class containing all extension methods

       ''' </summary>

       Public Module ExtensionMethods

       End Module

    End Namespace

  22. ImGonaRot says:

    Just for clarification. The return from the OData service from a browser looks like this…






  23. ImGonaRot says:

    Let me resend the "BUGS" in C# format and post a link to a sample VS Solution.

    ISSUE / BUG (1)

    // Press the "No Record / No QueryOption" button on the form to see the problem

    var data = (from x in dbContext.Products where x.Id == 10000 select new { ID = x.Id, Name = x.Name }).SingleOrDefault();

    // where there is no record with ID = 10000

    You will receive a StatusCode = 500 with exception "The 'ObjectContent`1' type failed to serialize the response body…"

    // Press the "No Record / Yes QueryOption" button on the form to see that the call works fine if using the AddQueryOption even if the record does not exist

    var data = (from x in dbContext.Products.AddQueryOption("$filter", "Id eq 10000") select new { ID = x.Id, Name = x.Name }).SingleOrDefault();

    // where there is no record with ID = 10000

    This will work fine without an exception and will give you a "NULL" record.

    I think you are missing the point that they are the same odata call but they are getting translated different in the OData v4 2.0 client.

    If I am using a "$filter" that is really the same thing as using the "where" clause in Linq.

    ISSUE / BUG (2)

    // Press the "Single Field / No QueryOption" button on the form to see the problem

    var data = (from x in dbContext.Products where x.Id == 1 select x.Name).SingleOrDefault();

    // where there is a record with ID =1

    You will receive "No HTTP resource was found that matches the request URI 'http://localhost:52389/odata/Products(1)/Name'&quot;

    // Press the "Single Field / Yes QueryOption" button on the form to see the call works fine and the url is formatted correctly with "http://localhost:52389/odata/Products(1)/?$select=Name&quot;

    var data = dbContext.Products.AddQueryOption("$select", "Name").Where(x => x.Id == 1).SingleOrDefault();

    // where there is a record with ID = 1

    HERE is the link to a sample project.


  24. AdamCaviness says:

    @Yi Ding, you stated "if you are the implementer of the service, you can hide the singletons from the metadata document."; how does one do that?  Thanks.

  25. AdamCaviness says:

    @Yi Ding, It is also possible that I am misunderstanding the purpose for the client generated classes ending in "Single".  If they are singleton classes, why are they generated at all when I don't define any singletons in the OData 4 service?  Reading the following http://www.asp.net/…/using-a-singleton-in-an-odata-endpoint-in-web-api-22 suggests that singletons are opt-in on the server but now they are opt-out on the client?  By this I mean I have to enable the IEdmModel of the server to be aware of any singletons with HasSingletonBinding() or ODataConventionModelBuilder.Singleton<T>() (again I have not done this at all) but with the OData Client Generator it assumes that every regular EntitySet on the server needs a singleton version on the client (I would have to opt-out somehow such as modifying the T4 template).  You state "if you are the implementer of the service, you can hide the singletons from the metadata document." but when I search my metadata document generated by my server, there isn't any mention of a "single" or "singleton" so what instructs OData Client Generator to generate them on the client?  All help in both understanding and changing this is appreciated.

  26. Yi Ding - MSFT says:


    Sorry for having misunderstood your question. I thought you were asking about the singleton properties in the derived class of DataServiceContext. Having read it twice, you are actually asking about the XxxSingle classes.

    They are not only for singletons and they are very important for the user experience of the generated proxy. In one sentence, they enables the delayed query and composing story of entity types.

    Examples should be a better way to explain this. Let's say I'm writing a client for the sample service services.odata.org/…/odata.svc and I would like to get the Categories of the Product whose ID is 1. The request should be as follows:

    GET services.odata.org/…/Categories

    The response payload should only contain the categories. However, the proxy generated by version 1.0.0 generator can't achieve that, when I try to write some query like

    var categories = context.Products.Where(c => c.ID == 1).Categories.Execute();

    I won't be able to. As the Where clause returns a DataServiceQuery<Product>, and the property Categories is not on it. So, I can only mitigate this problem by writing something like

    var categories = context.Products.Where(c => c.ID == 1).First().Categories;

    But I will soon find out there is nothing in the categories object. As the context.Products.Where(c => c.ID == 1).First() is translated to

    GET services.odata.org/…/Products(1)

    so the response payload does't have Categories at all because it's a navigation property.

    Then I can further mitigate this problem by writing

    var product = context.Products.Where(c => c.ID == 1).Expand(c => c.Categories).First();

    var categories = product.Categories;

    Ah, I finally get my Categories… But the payload has primitive and contained properties of the Product(1), which I don't necessarily want and they definitely increase the payload size. Moreover, for cases like

    GET services.odata.org/…/Products

    I can do nothing because in the only DataServiceQuery<T> design, I can't write anything to achieve this.

  27. Yi Ding - MSFT says:



    That's why we came up with DataServiceQuerySingle<T>. It perfectly resolve this composablility problem and enables delayed query (I can append as many query options and navigation properties to the query as I want and finally calls Execute() to get exactly the things I want back). In this new design in version 2.0.0, the query can be written as

    var products = context.Products.ByKey(new Dictionary<string, object>() {{"ID", 1}}).Categories.ByKey(new Dictionary<string, object>() {{"ID", 1}}).Products.Execute();

    We'll definitely improve the design of ByKey() method to ease the usage but this gives you an idea of how DataServiceQuerySingle<T> is useful. It is used as return type of query segment where the returned thing is a single entity type object. So, it's not only useful in such navigation property cases, but also useful in composing scenarios where the return type of a composable function is an entity type. For details, please kindly refer to this blog post written by Junlin describing the delayed query supported in version 2.0.0 thanks to these new DataServiceQuerySingle<T> classes: blogs.msdn.com/…/client-delayed-query.aspx

    Hope now you'll find them useful. (^-^)

  28. Yi Ding - MSFT says:


    The commenting system automatically translated the URLs in my text to hyperlinks and shortened them. You can hover your mouse onto them to see the actual URL.

  29. AdamCaviness says:

    @Yi Ding, this is an excellent response.  Thank you!!!

  30. ImGonaRot says:

    @Yi Ding

    Have you been able to look over the two bugs I posted?

    Did the source code help clarify the issues?

    I can post more snippets of code if it would help.

    I did post a third bug on using string array but it doesn't seem to be a "client" issue. This bug is more of a OData server issue when using unbound functions / actions.

    I posted the function / action bug here for reference. aspnetwebstack.codeplex.com/…/2087

  31. Martin says:


    I'm not able to get the client generator to create entity type actions for me at present.

    Below is a cut down version of the $metadata

    Can you advise me how to troubleshoot this?

    I'm using Microsoft.OData.Client package, version 6.6.0

    Kind Regards


    <?xml version="1.0" encoding="UTF-8"?>

    <edmx:Edmx xmlns:edmx="docs.oasis-open.org/…/edmx" Version="4.0">


    <Schema xmlns="docs.oasis-open.org/…/edm" Namespace="x.WebApiOData4.Models">

    <EntityType Name="et1">


    <PropertyRef Name="ID"/>


    <Property Name="ID" Nullable="false" Type="Edm.Int32"/>

    <Property Name="Email" Type="Edm.String"/>


    <Action Name="EntityTypeSampleOp" IsBound="true">

    <Parameter Name="bindingParameter" Type="x.WebApiOData4.Models.et1"/>

    <Parameter Name="p1" Nullable="false" Type="Edm.DateTimeOffset"/>


    <EntityContainer Name="Container">

    <EntitySet Name="Licenses" EntityType="x.WebApiOData4.Models.et1">






  32. Junlin Zheng says:


    Hi, could you provide your $metadata to me for your first String error in VB? Only looking at the generated code I'm doubting that there's an EntityType or a ComplexType named "String[]" in your metadata. If that's the case I can totally understand it will break all the code because of compile errors. But please let me check with your metadata first if I may.

    And I've looked into the 2 bugs you filed.

    For the first one, though the Where clause seems like it should be translated into "$filter" literally, but in OData, when it's specifying the key of an entity, it'll be translated into the key segment, e.g. (1). Fortunately, since the semantic meanings of "Products(1)" and "Products?$filter=id eq 1" should be exactly identical, it might not be a problem that the final urls are not the same and we're surely expecting the identical behavior that the server treats them. However, in your case, it seems that the server is applying different ones to the different urls, which causes the different results of the two lines of code.

    But I won't consider this as a bug of OData Client or the code generator. How server responses to different urls should be taken care of by server's implementation. My suggestion is to check your service and get it acts the same for "Products(1)" as "Products?$filter=id eq 1".

    Explaining this much, the second one will be really simple because basically, it's the exactly same problem as the first one. Could you check whether your service can respond identically to the urls which are different but sharing the same meaning?


  33. Junlin Zheng says:


    Please check the xmlns:edmx and xmlns attributes.

    <edmx:Edmx xmlns:edmx="docs.oasis-open.org/…/edmx" Version="4.0">


    <Schema xmlns="docs.oasis-open.org/…/edm" Namespace="x.WebApiOData4.Models">

    They should be:

    <edmx:Edmx xmlns:edmx="docs.oasis-open.org/…/edmx" Version="4.0">


    <Schema xmlns="docs.oasis-open.org/…/edm" Namespace="x.WebApiOData4.Models">

  34. Martin says:

    Hi @Junlin – those namespaces are in place – it was just a consequence of pasting into this web page – any other ideas? NB other aspects of the interface are working – normal CRUD stuff.

  35. ImGonaRot says:

    @Junlin Zheng

    First let me thank you for replying.

    Now down to business..

    BUG 1 — this bug is caused when the OData client calls the service and there is no record to return.

    As you suggested, if I place the following in a browser then the service will return "type failed to serialize"

    NOTE: Product 10 does not exist…


    but if I place the following in the browser then I don't get an error, instead I get a blank json response.



    {"@odata.context":"localhost:52389/odata/$metadata#Products","value":[ ] }

    So it seems that this is not an OData client issue but a server issue. I will post the bug on aspnetwebstack.codeplex.com

    Now on to the next bug.

    BUG 2 — this bug occurs when I use LINQ to select a "single" field from the OData service.

    This seems to be some issue with the LINQ to OData projection.


    This works…

    var data = (from x in dbContext.Products where x.Id == 1 select new { Name = x.Name }).SingleOrDefault();

    But this does not work…

    var data = (from x in dbContext.Products where x.Id == 1 select x.Name ).SingleOrDefault();

    Notice that the "new" key word is required to make it work.

    So I agree that bug "1" is a server issue but bug "2" seems to be a client translation issue.

    The bug with function returning primitive types in an array is a server issue. I have already posted the bug to aspnetwebstack.codeplex.com/…/2087

    The metadata for it looks like this.


  36. Junlin Zheng says:


    Sorry for misunderstanding your problem. I thought you were not able to generate code using the code generator. Now I get that what you're asking is about Actions, say "EntityTypeSampleOp" in the sample metadata.

    So what's the issue? Is that the action didn't get generated into corresponding EntityType? Or it actually shows up in generated code but cannot work as expected? In fact, I've tried it with the metadata you provided and there're two "EntityTypeSampleOp" genreated. One is in Et1 class, and another is in ExtensionMethods class which is extended on DataServiceQuerySingle<Et1>.

  37. Jay says:

    I can create the proxy classes' code dynamically for OData V1/V2 from my C# project.

    Here is a code snippet of what was used:

    var entityGenerator = new EntityClassGenerator(LanguageOption.GenerateCSharpCode);

    entityGenerator.Version = DataServiceCodeVersion.V2;

    var errors = entityGenerator.GenerateCode(sourceReader, targetWriter, "proxy");

    The DataServiceCodeVersion only goes as far as V2 and I am struggling to find the corresponding code for OData V3/V4.

    I think OData Client Code Generator 2.0.0. uses the code generator for OData V1-V4.

    Is it possible to share this code?

  38. Andres Urena says:

    how can I add the Authorization header to the client call? b cause is always null.

  39. Allan says:

    I receive the following error from the client generated code (I'm assuming) since the request works fine in the browser and fiddler;

    Microsoft.OData.Core.ODataException: When writing a JSON response, a user model must be specified and the entity set and entity type must be passed to the ODataMessageWriter.CreateODataEntryWriter method or the ODataFeedAndEntrySerializationInfo must be set on the ODataEntry or ODataFeed that is being writen.

    The URL is jbsapplication.azurewebsites.net/Modules$filter=Name eq 'JBS Electronic forms'&$expand=Menus

    I have exposed this so that you can see the result.

    The c# client code is as follows:

               var context = new Default.Container(new Uri("jbsapplication.azurewebsites.net/"));

               _modules = new DataServiceCollection<Module>(context);

               var menuQuery = from module in context.Modules.Expand(e=>e.Menus)

                               where module.Name == "JBS Electronic forms"

                               select module;


    When I added the .Expand part the error occured.

    My question:  How do I expand navigation properties?

  40. szymm14 says:

    I've the same question like Andres Urena, please help me anyone.

  41. szymm14 says:

    I've the same question like Andres Urena, please help me anyone.