Upon starting Campus Nexus Student the UI (user interface) will make a call to an OData feed that provides it with information about tables, fields, objects and navigational structures.
The feed is located at:
http://[Server]/Cmc.Nexus.Web/ds/campusnexus/$metadata
The OData feed has a structure that is similar to one shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version="1.0" encoding="utf-8"?> <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"> <edmx:DataServices> <Schema Namespace="Cmc.Nexus.Models.Academics" xmlns:cmcedm="http://www.campusmanagement.com/odata/ns/edm" xmlns="http://docs.oasis-open.org/odata/ns/edm"> <EntityType Name="..." cmcedm:DisplayName="..." cmcedm:PluralDisplayName="..." cmcedm:Description="..."> <Key> <PropertyRef Name="(FieldName)" /> </Key> <Property Name="(FieldName)" Type="Edm.(Type)" Nullable="(bool)" cmcedm:Browsable="(bool)" ... cmcedm:DisplayName="Id" /> <NavigationProperty Name="(FieldName)" Type="Cmc.Nexus.Models ..." cmcedm:Browsable="true" cmcedm:DisplayName="..." /> </EntityType> </Schema> <Schema Namespace="CampusNexus" xmlns:cmcedm="http://www.campusmanagement.com/odata/ns/edm" xmlns="http://docs.oasis-open.org/odata/ns/edm"> <Function Name="GetTaskTemplatesForUser" IsBound="true"> <Parameter Name="bindingParameter" Type="Collection(Cmc.Nexus.Models ...)" /> <Parameter Name="(Fieldname)" Type="Edm.Int32" Nullable="false" /> <ReturnType Type="Collection(Cmc.Nexus.Models....)" /> </Function> <EntityContainer Name="Container"> <EntitySet Name="..." EntityType="Cmc.Nexus.Models ..."> <NavigationPropertyBinding Path="..." Target="..." /> </EntitySet> <EntitySet Name="..." EntityType="..." /> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx> |
The details included in this OData feed are extracted directly from the generated models in the solution.
For example, a partial section of the metadata for the EntityType “StudentCourseStatusChange” is as follows:
1 2 3 4 5 6 7 |
<EntityType Name="StudentCourseStatusChange" ... > <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Id" Type="Edm.Int32" Nullable="false" cmcedm:Browsable="true" ... /> <Property Name="ClassSectionCode" Type="Edm.String" cmcedm:Browsable="true" ... /> </EntityType> |
The values shown above are generated directly from the values in the data model shown below:
1 2 3 4 5 6 7 8 9 10 11 12 |
namespace Cmc.Nexus.Models.Academics { public partial class StudentCourseStatusChange { [Key, Column("AdEnrollSchedStatusChangesID", TypeName="int", Order=1)] [Browsable(true), Required ] public int Id { get; set; } [Column("Section", TypeName="varchar")] [Browsable(true), Editable(true) ] public string ClassSectionCode { get; set; } } } |
As you can see from the generated model in Cmc.Nexus.Models.Academics.StudentCourseStatusChange, the attributes and properties of the fields in this model are automatically used to create the Odata feed.
The job of creating the metadeta, is performed by the Cmc.Core.Models.ModelAnnotator which simply takes advantage and extends the capabilities built into:
– System.Web.OData.Builder.ODataConventionModelBuilder
– Microsoft.Odata.Edm.IEdmModel
Now, how do we add additional custom properties to the Odata feed that may be data-driven?
In order to provide this capability, we have created the capability to create a “inject” a custom ODataAnnotator instance into the Cmc.Core.Models.ModelAnnotator.
1 2 3 4 5 6 7 8 9 10 |
namespace Cmc.Core.Models { public interface IDataAnnotator { void ApplyAnnotations(string name, IEdmModel model, IEdmElement element, string namespaceName); } } |
When the ModelAnnotator finds an instance of a custom ODataAnnotator is available, it will proceed to insert the logic of that custom annotator into the process of creating the OData feed.
In Campus Nexus, we have created a custom Data Annotator that takes advantage of this capability. It will insert the value of [ cmcedm:RequiredSystems=”ui” ] for all XML Elements in the feed that have been configured on the “syDictionary” to have a value of [UiRequired = 1]
To test this capability, you simply follow these steps:
1) Open the SQL table “syDictionary”
2) Find a record in this table that matches a table + field in the the OData feed
3) Update the field “UiRequired” for that table + field
* The “UiRequired” field is a boolean. Simply change its value to 1
Once this is completed, restart the Campus Nexus Solution. You will notice that the XML Element in the OData feed that relates to the Table + Field which you selected are now showing the following value:
1 2 |
<EntityType Name="(TableName)" ... > FieldName)" Type="Edm.(Type)" cmcedm:RequiredSystems="ui" ... /> |