I just started working with the Office 365 OData API and was a little fustrated with the samples because all the strongly typed classes they provide for using the OData APIs contains nowhere near all of properties the odata returns.
So I looked around for some way to generate the strongly typed classes directly from the OData metadata.
The metadata for the exchange odata endpoints can be downloaded from this url https://outlook.office365.com/ews/odata/$metadata.
So I just needed a tool for generating the classes. First I tried with DataSvcUtil.exe, but I had no luck with that. So instead I installed the following Visual Studio extension OData Client Code Generator.
.
The tool is very simple to use it adds a new Item template type called “OData Client” when added to a project you get a new a *.odata.config file and t4 template and that can turn a edmx schema from a OData metadata endpoint into a odata client class with strongly typed classes for types exposed.
You need to edit the *.odata.config to point to your edmx source file or a OData service. In my case with the Exchange odata, I downloaded the edmx file from the https://outlook.office365.com/ews/odata/$metadata and pointed to the file on disk to avoid having to login inside Visual Studio.
Here’s what my config file looks like
<?xml version="1.0" encoding="utf-8" ?> <Parameters> <!-- Value of MetadataDocumentUri must be set to a valid service document uri or a local file path eg : http://services.odata.org/V4/OData/OData.svc/ or File://C://Odata.edmx --> <Parameter Name="MetadataDocumentUri" Value="File://C://Users//Simon Pedersen//Documents//Visual Studio 2013//Projects//AccessOfficeAPI//AccessOfficeAPI//ews.edmx" /> <!-- Value must be true or false --> <Parameter Name="UseDataServiceCollection" Value="true" /> <!-- Namespace prefix will replace the original namspace, unless the mode has several namespaces.--> <Parameter Name="NamespacePrefix" Value="ews" /> <!-- Value of TargetLanguage must be CSharp or VB --> <Parameter Name="TargetLanguage" Value="CSharp" /> </Parameters>
And here’s a snippet of what the generated code for the Event data type.
/// <summary> /// There are no comments for Event in the schema. /// </summary> /// <KeyProperties> /// Id /// </KeyProperties> [global::Microsoft.OData.Client.Key("Id")] public partial class Event : Item { /// <summary> /// Create a new Event object. /// </summary> /// <param name="ID">Initial value of Id.</param> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public static Event CreateEvent(string ID) { Event @event = new Event(); @event.Id = ID; return @event; } /// <summary> /// There are no comments for Property Start in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Nullable<global::System.DateTimeOffset> Start { get { return this._Start; } set { this.OnStartChanging(value); this._Start = value; this.OnStartChanged(); this.OnPropertyChanged("Start"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Nullable<global::System.DateTimeOffset> _Start; partial void OnStartChanging(global::System.Nullable<global::System.DateTimeOffset> value); partial void OnStartChanged(); /// <summary> /// There are no comments for Property End in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Nullable<global::System.DateTimeOffset> End { get { return this._End; } set { this.OnEndChanging(value); this._End = value; this.OnEndChanged(); this.OnPropertyChanged("End"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Nullable<global::System.DateTimeOffset> _End; partial void OnEndChanging(global::System.Nullable<global::System.DateTimeOffset> value); partial void OnEndChanged(); /// <summary> /// There are no comments for Property Location in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::ews.Microsoft.Exchange.Services.OData.Model.Location Location { get { return this._Location; } set { this.OnLocationChanging(value); this._Location = value; this.OnLocationChanged(); this.OnPropertyChanged("Location"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::ews.Microsoft.Exchange.Services.OData.Model.Location _Location; partial void OnLocationChanging(global::ews.Microsoft.Exchange.Services.OData.Model.Location value); partial void OnLocationChanged(); /// <summary> /// There are no comments for Property ShowAs in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::ews.Microsoft.Exchange.Services.OData.Model.FreeBusyStatus ShowAs { get { return this._ShowAs; } set { this.OnShowAsChanging(value); this._ShowAs = value; this.OnShowAsChanged(); this.OnPropertyChanged("ShowAs"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::ews.Microsoft.Exchange.Services.OData.Model.FreeBusyStatus _ShowAs; partial void OnShowAsChanging(global::ews.Microsoft.Exchange.Services.OData.Model.FreeBusyStatus value); partial void OnShowAsChanged(); /// <summary> /// There are no comments for Property IsAllDay in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Nullable<bool> IsAllDay { get { return this._IsAllDay; } set { this.OnIsAllDayChanging(value); this._IsAllDay = value; this.OnIsAllDayChanged(); this.OnPropertyChanged("IsAllDay"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Nullable<bool> _IsAllDay; partial void OnIsAllDayChanging(global::System.Nullable<bool> value); partial void OnIsAllDayChanged(); /// <summary> /// There are no comments for Property IsCancelled in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Nullable<bool> IsCancelled { get { return this._IsCancelled; } set { this.OnIsCancelledChanging(value); this._IsCancelled = value; this.OnIsCancelledChanged(); this.OnPropertyChanged("IsCancelled"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Nullable<bool> _IsCancelled; partial void OnIsCancelledChanging(global::System.Nullable<bool> value); partial void OnIsCancelledChanged(); /// <summary> /// There are no comments for Property IsOrganizer in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Nullable<bool> IsOrganizer { get { return this._IsOrganizer; } set { this.OnIsOrganizerChanging(value); this._IsOrganizer = value; this.OnIsOrganizerChanged(); this.OnPropertyChanged("IsOrganizer"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Nullable<bool> _IsOrganizer; partial void OnIsOrganizerChanging(global::System.Nullable<bool> value); partial void OnIsOrganizerChanged(); /// <summary> /// There are no comments for Property ResponseRequested in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Nullable<bool> ResponseRequested { get { return this._ResponseRequested; } set { this.OnResponseRequestedChanging(value); this._ResponseRequested = value; this.OnResponseRequestedChanged(); this.OnPropertyChanged("ResponseRequested"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Nullable<bool> _ResponseRequested; partial void OnResponseRequestedChanging(global::System.Nullable<bool> value); partial void OnResponseRequestedChanged(); /// <summary> /// There are no comments for Property Type in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::ews.Microsoft.Exchange.Services.OData.Model.EventType Type { get { return this._Type; } set { this.OnTypeChanging(value); this._Type = value; this.OnTypeChanged(); this.OnPropertyChanged("Type"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::ews.Microsoft.Exchange.Services.OData.Model.EventType _Type; partial void OnTypeChanging(global::ews.Microsoft.Exchange.Services.OData.Model.EventType value); partial void OnTypeChanged(); /// <summary> /// There are no comments for Property SeriesId in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public string SeriesId { get { return this._SeriesId; } set { this.OnSeriesIdChanging(value); this._SeriesId = value; this.OnSeriesIdChanged(); this.OnPropertyChanged("SeriesId"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private string _SeriesId; partial void OnSeriesIdChanging(string value); partial void OnSeriesIdChanged(); /// <summary> /// There are no comments for Property Attendees in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::System.Collections.ObjectModel.ObservableCollection<global::ews.Microsoft.Exchange.Services.OData.Model.Attendee> Attendees { get { return this._Attendees; } set { this.OnAttendeesChanging(value); this._Attendees = value; this.OnAttendeesChanged(); this.OnPropertyChanged("Attendees"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::System.Collections.ObjectModel.ObservableCollection<global::ews.Microsoft.Exchange.Services.OData.Model.Attendee> _Attendees = new global::System.Collections.ObjectModel.ObservableCollection<global::ews.Microsoft.Exchange.Services.OData.Model.Attendee>(); partial void OnAttendeesChanging(global::System.Collections.ObjectModel.ObservableCollection<global::ews.Microsoft.Exchange.Services.OData.Model.Attendee> value); partial void OnAttendeesChanged(); /// <summary> /// There are no comments for Property Recurrence in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::ews.Microsoft.Exchange.Services.OData.Model.PatternedRecurrence Recurrence { get { return this._Recurrence; } set { this.OnRecurrenceChanging(value); this._Recurrence = value; this.OnRecurrenceChanged(); this.OnPropertyChanged("Recurrence"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::ews.Microsoft.Exchange.Services.OData.Model.PatternedRecurrence _Recurrence; partial void OnRecurrenceChanging(global::ews.Microsoft.Exchange.Services.OData.Model.PatternedRecurrence value); partial void OnRecurrenceChanged(); /// <summary> /// There are no comments for Property Calendar in the schema. /// </summary> [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] public global::ews.Microsoft.Exchange.Services.OData.Model.Calendar Calendar { get { return this._Calendar; } set { this.OnCalendarChanging(value); this._Calendar = value; this.OnCalendarChanged(); this.OnPropertyChanged("Calendar"); } } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "1.0.0")] private global::ews.Microsoft.Exchange.Services.OData.Model.Calendar _Calendar; partial void OnCalendarChanging(global::ews.Microsoft.Exchange.Services.OData.Model.Calendar value); partial void OnCalendarChanged(); }
Categories: Programming Software
2 replies ›