moh-hassan / odata2poco Goto Github PK
View Code? Open in Web Editor NEWgenerate POCO classes from OData service
License: MIT License
generate POCO classes from OData service
License: MIT License
I would find it very useful if the used options were recorded in the header of the output file.
Something along the lines of:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated using OData2Poco System.
// Service Url: https://my.service.url/$metadata
// MetaData Version: 4.0
// Generated On: 2021-02-23T20:21:31
// parameters: -f PocoFileName -a key req max -b
// </auto-generated>
//------------------------------------------------------------------------------
//
Also when using a local file with -r the "Service Url" part of this header is blank - it would be nice if that also contained the value of the -r parameter.
Starting Release 6.2.0, the application o2pgen.exe
and all odata2poco.xxx.nupkg
packages are signed.
Code signing is applied only to odata2poco project code in the odata2poco repository and built on AppVeyor.
The odata2poco.xxx.nupkg packages contain third-party libraries used by odata2poco, which may or may not be signed.
The project uses the free code signing provided by SignPath.io, and a certificate by the SignPath Foundation.
Thanks to SignPath.io and Thanks to @paul Savoie for help and support.
Is there any options to generate poco for certain dynamic365 entities? Actually I don't need all ~3591 in my case, but only some.
An OData API that I am using requires an API Key included as a header in the request. I don't see a way to provide this using the OData2POCO tool. Is this possible now, or could it be added as a feature?
Hi moh-hassan,
It's not an issue but a question: Are you aware of a way to get the maxlength of a string attribute?
It doesn't appear to be in the metadata but I hope I'm overlooking it.
Thanks
For more details, read wiki Generating Parameterized Constructor
For more details, read wiki Type Visibility
For more details, read wiki Using Proxy Server
Clean up /refactor with latest C# 12 features.
Re-order class members based on the Design guidelines.
Move global tool dotnet o2pgen
to net8.
No binary breaking change.
This is a wonderful program. Thank you.
Microsoft Dataverse/Common Data Service has a feature(?) in that it will automatically name columns in the tables for you based on the name given, and there is no way for the end user to change it. It also ensures uniqueness across the workspace, resulting in some peculiar names. For example, one might add "First Name" to a table, and if it was used before it might get named something like "crf9sa_firstname" as the column name. Not really the name of a property I want to see no matter the capitalization rule applied.
The display name can be changed, so it is not a safe bet to use that as a property name. Rather, it would be great if an external file could be used to map the column name to an arbitrary property name. Bonus points if it supports a regex e.g. triggered when the source name starts with a ^. And double bonus points if there is a way to print out a template file to be used as a starting point.
E.g.:
{
{ "crf9sa_firstname", "FirstName" },
{ "^.*$firstname.*$", "FirstName" }
}
An auto generated template file might be like:
{
{ "crf9sa_firstname", "crf9sa_firstname" }
}
for easy editing.
I'm happy to have a go at this if it sounds like a feature you would be willing to merge.
Thanks again.
Hi,
Currently members that cannot be null have the "not null" comment beside them:
I have to programatically determine not nulls members to ensure my users enter a value for them but I don't see a way to do it with the comment.
Could a "[Not Null]" annotation or something similar be added that could be used to programatically determine if a member cannot be null?
Thanks
Would it be possible to support the Pascal Casing of Camel Case properties in the edmx? For instance if you have an edmx with a entity type of Person and properties email, firstName, lastName, and login, the C# that will be generated would be as such:
public class Person
{
public Person();
public string email { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string login { get; set; }
}
However, many C# coding standards desire properties to be pascal-cased, not camel cased. JSON.NET supports adding an attribute to a class that preserves the original camelCased property name.
So would it be possible to get an option added to the PocoSettings/command line argument that would generate the following instead?
public class Person
{
public Person();
[JsonProperty(PropertyName = "email")]
public string Email { get; set; }
[JsonProperty(PropertyName = "firstName")]
public string FirstName { get; set; }
[JsonProperty(PropertyName = "lastName")]
public string LastName { get; set; }
[JsonProperty(PropertyName = "login")]
public string Login { get; set; }
}
When testing the dotnet o2pgen against a SAP S/4 OData endpoint I discovered an issue with the fact that the SAP metadata is returned from the metadata endpoint with Content-Encoding set to gzip.
This results in the following error
Information: Start processing url: https://sandbox.api.sap.com/s4hanacloud/sap/opu/odata/sap/API_SALES_ORDER_SRV
Error: Error in executing o2pgen
Error: '▼', hexadecimal value 0x1F, is an invalid character. Line 1, position 1.
Information: Error details with Stack trace are written to the file: 'c:\Temp\error.txt'
Information: Application Exit code: 2
The contents of the error.txt file are as follows:
'�', hexadecimal value 0x1F, is an invalid character. Line 1, position 1.
Exception Details:
System.Xml.XmlException: '�', hexadecimal value 0x1F, is an invalid character. Line 1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
at System.Xml.XmlTextReaderImpl.ThrowInvalidChar(Char[] data, Int32 length, Int32 invCharPos)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlReader.MoveToContent()
at OData2Poco.Helper.GetMetadataVersion(String metadataString) in C:\projects\odata2poco\OData2PocoLib\Helper.cs:line 68
at OData2Poco.MetaDataReader.LoadMetaDataHttpAsync(OdataConnectionString odataConnString) in C:\projects\odata2poco\OData2PocoLib\MetaDataReader.cs:line 14
at OData2Poco.MetaDataReader.LoadMetadataAsync(OdataConnectionString odataConnString) in C:\projects\odata2poco\OData2PocoLib\MetaDataReader.cs:line 66
at OData2Poco.PocoFactory.GenerateModel(OdataConnectionString connectionString, PocoSetting setting) in C:\projects\odata2poco\OData2PocoLib\PocoFactory.cs:line 35
at OData2Poco.Api.O2P.GenerateModel(OdataConnectionString odataConnString) in C:\projects\odata2poco\OData2PocoLib\Api\O2P.cs:line 35
at OData2Poco.Api.O2P.GenerateCsAsync(OdataConnectionString odataConnString) in C:\projects\odata2poco\OData2PocoLib\Api\O2P.cs:line 71
at OData2Poco.Api.O2P.GenerateAsync(OdataConnectionString odataConnString) in C:\projects\odata2poco\OData2PocoLib\Api\O2P.cs:line 52
at OData2Poco.CommandLine.CsCommand.GenerateCodeCommandAsync() in C:\projects\odata2poco\OData2Poco.Cli\CsCommand.cs:line 146
at OData2Poco.CommandLine.CsCommand.Execute() in C:\projects\odata2poco\OData2Poco.Cli\CsCommand.cs:line 43
at OData2Poco.CommandLine.ArgumentParser.RunCommandAsync(Options options) in C:\projects\odata2poco\OData2Poco.Cli\ArgumentParser.cs:line 47
at OData2Poco.CommandLine.ArgumentParser.<>c__DisplayClass15_0.<<RunOptionsAsync>b__0>d.MoveNext() in C:\projects\odata2poco\OData2Poco.Cli\ArgumentParser.cs:line 29
--- End of stack trace from previous location ---
at OData2Poco.CommandLine.ArgumentParser.RunOptionsAsync(String[] args, Func`2 func) in C:\projects\odata2poco\OData2Poco.Cli\ArgumentParser.cs:line 26
at OData2Poco.CommandLine.ArgumentParser.RunOptionsAsync(String[] args) in C:\projects\odata2poco\OData2Poco.Cli\ArgumentParser.cs:line 43
at OData2Poco.CommandLine.StartUp.RunOptionsAsync(String[] args) in C:\projects\odata2poco\OData2Poco.Cli\StartUp.cs:line 117
at OData2Poco.CommandLine.StartUp.Run(String[] args) in C:\projects\odata2poco\OData2Poco.Cli\StartUp.cs:line 78
I have created a PR #47 with a simple fix to allow the http response message content to be automatically decompressed and read as a string.
An enum on our API side reads like so:
public enum FeeVariant
{
Normal = 1,
StdAbs = 2,
AddAbs = 3,
Holiday = 4,
// others here...
}
The generated enum by odata2poco is:
public enum FeeVariant { Normal, StdAbs, AddAbs, Holiday, /* others here... */ }
As a result, the index of the generated enum values is wrong.
Hi,
First oft all, thanks for this great library. I was really missing such a simple to use tool for generation of model classes.
Unfortunately I receive some minor errors in the generated code when running odata2poco as a local dotnet tool (see command below).
dotnet tool run dotnet-o2pgen `
--url "$organizationUrl/api/data/v9.1/" `
--auth oauth2 `
--user $clientId `
--password $clientSecret `
--token-endpoint "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" `
--token-params "scope=$organizationUrl/.default" `
--navigation `
--nullable `
--include *
The type or namespace name 'Library' does not exist in the namespace 'Microsoft.OData.Edm'
public virtual Microsoft.OData.Edm.Library.Date birthdate {get;set;}
~~~~~~~
Microsoft removed the Library
namespace starting with v7 of the EDM library. The correct namespace is Microsoft.OData.Edm.Date
. I could remove this part manually but upon re-generation of the model the changes get overriden, which is kind of suboptimal. So is it possible for you to update this dependency or is there any configuration I am missing?
The type or namespace name 'JsonProperty' could not be found.`
[JsonProperty("event")]
~~~~~~~~~~~~
public virtual string Event {get;set;}
JsonProperty
is part of Newtonsoft.Json namespace. Microsoft removed this namespace from dotnet core 3 and introduced an own namespace for JSON de-/serialization. As mentioned before I could easily fix this problem by replacing JsonProperty
with JsonPropertyName
and adding a using for System.Text.Json.Serialization
but I have to do it everytime the schema changes. So it would be awesome if you switch to System.Text.Json
or provide a commandline option which package to use.
Thanks in advance!
I am using odata2poco with SAP service layer. Some of the enum or object members are null from the api. I am using the -b, --nullable option. It works for C# primitives, but enums and objects from the api are not nullable. The newtonsoft JSON deserialization library can't deserialize the response object because there are fields with null value which are not nullable in the generated file.
If i put the "?" after the type definitions everything works. Is it possible to make every member variable nullable with the nullable option?
Hi,
is there are specific reason why nullable Microsoft.OData.Edm.Date
is not implemented?
If I understand your source correctly this should just be a small change in OData2PocoLib/Helper.cs
/// <summary>
/// Nullable DataType
/// </summary>
public static readonly Dictionary<string, string> NullableDataTypes = new Dictionary<string, string>
{
{"object" , ""},
{"string" , ""},
{"bool" , "?"},
{"byte" , "?"},
{"char" , "?"},
{"decimal" , "?"},
{"double" , "?"},
{"short" , "?"},
{"int" , "?"},
{"long" , "?"},
{"sbyte" , "?"},
{"float" , "?"},
{"ushort" , "?"},
{"uint" , "?"},
{"ulong" , "?"},
{"void" , "?"},
////Nullable DateTime issue #3 , included in v2.3.0
{"DateTime","?" },
{"DateTimeOffset","?" },
{"TimeSpan","?" },
{"Guid","?" },
// THIS IS NEW
{"Microsoft.OData.Edm.Date","?"},
{"Microsoft.OData.Edm.TimeOfDay","?"}
};
Can I provide a pull request for this feature?
Thanks in advance!
As of the new pre-release version 3.0.0-RC1.240, navigation properties are missing from generated classes.
The xml:
<EntityType Name="SomeClass">
<NavigationProperty Name="Something" Type="AnotherClass"/>
</EntityType>
produces the following output:
public class SomeClass
{
}
HI,
Your tool looks like a perfect fit but I can't tell if it will connect Microsoft's D365 F&O odata end points.
Here is how I connect to it using POST MAN:
https://community.dynamics.com/365/financeandoperations/b/365foandaxtechnicalworld/archive/2018/07/03/dynamics-365-finance-amp-operation-webapi-with-post-man
Is there a way to connect using odata2poco as shown for POST MAN?
Hi!
We find this tool very useful for generating models from our odata service. However, we would like to be able to generate a nullable DateTime property (using the -b option to the o2pgen command line tool).
As far as I understand DateTime is simply not included in the list of nullable data types.
Do you plan to address this in any future release?
poco generated for Northwind V2 service:
dotnet -o2pgen -l -r http://services.odata.org/V2/Northwind/Northwind.svc -n
The o2pgen does not support the d/results/metadata structure of the odata response?
e.g.
{
"d": {
"results": [
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Shippers(1)",
"type": "NorthwindModel.Shipper"
},
"ShipperID": 1,
"CompanyName": "Speedy Express",
"Phone": "(503) 555-9831",
"Orders": {
"__deferred": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Shippers(1)/Orders"
}
}
},
{
client code:
_httpClient.BaseAddress = new Uri("http://services.odata.org");
_httpClient.Timeout = new TimeSpan(0, 0, 30);
_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await _httpClient.GetAsync("/V2/Northwind/Northwind.svc/Shippers");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var shipperList = new List();
shipperList = JsonConvert.DeserializeObject<List>(content);
I got 'Time' class of property.
Is it 'TimeSpan'?
You should add the max
attribute value option to the documentation. Both the readme, the wiki and the commandline output.
I had to dig into the code to find this, very useful, option.
Test at work. Intranet. SharePoint. Ntlm Auth. Failed. I will still test.
Hi,
Using odata2poco as a class library has been been seamless and has saved me so much time.
I now have a need to generate the metadata document xml file each time my app starts so I can parse out more info that is not part of the POCO class file.
Would be possible to add a parameter that if passed would write the metadata document file instead of the POCO class file?
Thanks!
Input
<SchemaName1>
<EntityName>
<SchemaName2>
<EntityName>
Output
public class EntityName
In this case, I will get only one entity, which is an incorrect case of inheritance and navigation (links)
Expected output
namespace SchemaName1
{
public class EntityName
{
}
}
namespace SchemaName2
{
public class EntityName
{
}
}
The dotnet-o2pgen tool does not run unless version 2.1.0 specifically of the .NET Core framework is installed. That means that even if one has .NET Core 3.x or .NET 5 or .NET 6 installed, the tool will not run until .NET Core 2.1.0 is installed. It is expected that the tool should be able to run on 2.1.0 or newer versions of the .NET Core framework, including .NET 5+.
I am using Odata2poco as a library in a small project I am experimenting with and I have 2 questions that I could not figure out:
a. Is there an option to control the behavior of the read-only feature that was introduced in #27 ? In my case I need to get the POCO with {get;set;} no matter what is configured in the edmx.
b. Is there a way to provide the OData service metadata to OData2Poco as a string instead of providing the url or filename ?
(I have workarounds for the above, but they are a bit ugly, eg string replace the generated code and use a temporary file)
thanks!
Hi,
I've added the generated POCO class to my project for the first time and getting a lot of compile errors due to 2 issues.
The first issue is values are key words:
If you could add "@" in front of key words that will fix it
The second is due to "members name cannot be the same as enclosing type"
The only resolution I can find is if the member and class name are the same then your codes changes the member name but I hate that solution. Any ideas?
Thanks
Is there a possibility to apply -c option to poco class names, enum type names? For properties works as expected.
Thanks for your work!!
One more question: let's assume that I have a bunch of lookup fields in my data. It doesn't appear that EntityFrameworkCore can handle scaffolding a database with anything other than generic types. So if I instead of a primitive string, bool, or int, I have a data definition that is a List(Of ), it doesn't know how to handle it. Can the POCO classes generated by this library handle that somehow?
Hello! This is some awesome code. Really efficient, and overwhelmingly accurate. I have a question. For the fields in my OData EDMX, I have descriptions that I'd eventually like to integrate into my data model. Example:
<!-- https://ddwiki.reso.org/display/DDW17/AboveGradeFinishedArea+Field
Finished area within the structure that is at or above the surface of the ground. -->
<Property Name="AboveGradeFinishedArea" Type="Edm.Decimal" Precision="14" Scale="2" />
As you can see, it provides additional informational details about properties in the OData API. Is there a way to expose that in the exported POCOs?
I am attempting to create a poco from Microsoft Business Central, which is admittedly ODataV4 . I am getting desperately close, except that some properties of entities in the Metadata is marked as read-only, but it comes into the generated poco with {get; set;} modifiers. Is there a switch I am missing, or is this currently not supported?
I am using odata2poco with SAP Business One. The api of the SAP was updated since we last used the tool, and now we get the following error:
Error in executing the command: o2pgen --case none --filename poco.cs --auth none --url https://192.168.10.9:50000/b1s/v1/ --nullable Error Message: Encountered the following errors when parsing the EDMX document: UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3512, 44) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3579, 48) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3622, 46) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3716, 47) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3729, 48) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3778, 61) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3800, 51) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3813, 47) UnexpectedXmlAttribute : The attribute 'OpenType' was not expected in the given context. : (3901, 56)
The meta file is the following:
sap-metadata.xml.txt
It's planned in the next release of dropping net45.
The reason is that targeting net45 limit the use of the new features in the higher frameworks.
The minimum support version will be net472.
You are welcome for the discussion if you have any comments.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.