SAP Odata service metadata do not output fully in browser - odata

My MPC Provider is not fully providing metadata to the browser when called.
I am calling the service like follows:
http://SERVER/sap/opu/odata/sap/SERVICE/?$metadata
It's returning:
<app:service xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:sap="http://www.sap.com/Protocols/SAPData" xml:lang="en" xml:base="http://SERVER:8000/sap/opu/odata/sap/SERVICE/">
<app:workspace>
<atom:title type="text">Data</atom:title>
<app:collection sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1" href="hu_headerSet">
<atom:title type="text">hu_headerSet</atom:title>
<sap:member-title>hu_header</sap:member-title>
</app:collection>
<app:collection sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1" href="hu_itemSet">
<atom:title type="text">hu_itemSet</atom:title>
<sap:member-title>hu_item</sap:member-title>
</app:collection>
</app:workspace>
<atom:link rel="self" href="http://SERVER:8000/sap/opu/odata/sap/SERVICE/"/>
<atom:link rel="latest-version" href="http://SERVER:8000/sap/opu/odata/sap/SERVICE/"/>
</app:service>
I'm expecting it to return the details of the two entity sets, including the properties of the entities and the associations, which is what it should do.
I've debugged the MPC which is getting all the attributes, associations, and entities, but these are not being output when called. I'm trying to generate an EDMX to create a new App, I've done this manually before, but both of these entitysets have 40/50 fields.
I've checked SU53 and there's no failed Authorzations, I've cleared the cache every time that I've done a debug to make sure it's not that, and I've set the get_entity calls in the MPC to protected as a test.
Does anyone have any ideas?
For those who are more successful, here is a resource with some suggestions that I've already tried: https://blogs.sap.com/2016/06/15/entityset-of-an-odata-not-appearing-in-metadata/

Use
http://SERVER/sap/opu/odata/sap/SERVICE/$metadata
without the '?'
The responses are different.

Related

Simple Select-Dropdown for a NavigationProperty

For a current project, we're using Olingo in backend for OData v4 data access and openui5 as frontend framework. We know, that odata v4 is in a more experimental state in openui5 but we're doing not so bad with it. As it is normal for us, to use a workaround here and there, we're struggeling with following problem right now where I think there should be a really simple way instead of building a workaround.
Simplified oData v4 Model:
<EntityType Name="Notification">
<Key>
<PropertyRef Name="uid"/>
</Key>
<Property Name="uid" Type="Edm.Int32"/>
<Property Name="recievedAt" Type="Edm.Date"/>
<NavigationProperty Name="NotificationType" Type="rest.odata.BaseData" Nullable="false"/>
</EntityType>
<EntityType Name="BaseData">
<Key>
<PropertyRef Name="key"/>
</Key>
<Property Name="key" Type="Edm.String"/>
<Property Name="title" Type="Edm.String"/>
</EntityType>
The BaseData-Entity is used for different key-value-lists - in this case for a NotificationType. We have couple of types summarized and represented in an EntitySet:
<EntitySet Name="basedataNOTIFICATIONTYPES" EntityType="rest.odata.BaseData"/>
Now we're struggeling in the frontend with a simple sap.m.Select-Dropdown which should define the NotificationType of our Notification.
The Select-Control is defined like this:
var oControl = new sap.m.Select(sName, {selectedKey: "{NotificationType/key}"});
oControl.bindItems({
path: "/basedataNOTIFICATIONTYPES"
})
(I simplified the code very much)
The parent form is binded to a specific /Notification context.
This is what happens: The Select-Dropdown shows the current saved NotificationType of our specific /Notification. If I select another NotificationType from the dropdown, ui5 sends a PATCH Request to the EntitySet /basedataNOTIFICATIONTYPES. This is not the behaviour I expected. I need a PATCH Request sent to the specific /Notification(XXX)/NotificationType/key to update it.
Has anyone a hint for me?
Thanks in advance! :-)

How to select and expand on properties which are available only in derivedtypes

I have three entities, in an inheritance hierarchy as shown below.
<EntityType Name="Base" Abstract="true">
<Property Name="id" Type="Edm.String" Nullable="false" />
</EntityType>
<EntityType Name="Derived1" Abstract="true" BaseType="Base">
<NavigationProperty Name="idps" Type="Collection(Idps)" />
</EntityType>
<EntityType Name="Derived2" Abstract="true" BaseType="Base">
<NavigationProperty Name="attributes" Type="Collection(Attributes)" />
</EntityType>
I want to support $select and $expand query options for idps and attributes.
/base?$select=idps gives me below error
The query specified in the URI is not valid. Could not find a property named 'idps' on type 'Base'."
What would be the right odata option and how can I support that?
ODL supports type cast segment in the $select and $expand.
Here's some test cases that you can refer to:
1) https://github.com/OData/WebApi/blob/master/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/NavigationPropertyOnComplexType/SelectImprovementOnComplexTypeTests.cs#L141
2) https://github.com/OData/WebApi/blob/master/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/NavigationPropertyOnComplexType/SelectImprovementOnComplexTypeTests.cs#L284
The test cases cover the complex type type cast, so does it for entity type cast.
I was able to resolve this issue with a query similar to the following:
/base?$select=Derived1/idps
In my case, my OData entity types have an explicit namespace on them, so I had to actually use a query similar to the following:
/base?$select=Namespace.Derived1/idps

How can I use DataServiceContext to call an unbound action accepting an entity-reference parameter?

My OData v4 client uses generated classes based on the 6.x version of Microsoft.OData.Client.
Now it needs to call an action with the following definition:
<Action Name="Resolve">
<Parameter Name="CertRequestEntity" Type="CertificationRequest" />
<Parameter Name="CertRequestId" Type="Edm.String" Nullable="false" Unicode="false" />
<Parameter Name="RequestSuccess" Type="Edm.Boolean" Nullable="false" />
<Parameter Name="RejectedMessage" Type="Edm.String" Unicode="false" />
</Action>
It is easy to construct primitive parameters with the aid of the BodyOperationParameter class, but I cannot find any documentation on the proper way to construct an entity reference as a parameter. Is this possible? (I ended up using HttpClient with a hand-rolled JSON body.)
Note that the definition above, as written, is invalid; the type of the first parameter should be namespace qualified.
If you have control over the schema, the simplest solution would be to make this a bound action (IsBound="true" on the action definition). Bound actions are similar to extension methods in .NET -- the first (entity) parameter becomes the "binding parameter", and you would call the action by appending the action name (/Resolve) to the URL for the CertificationRequest that you wanted to resolve, passing the remaining (non-binding) parameters in the body.

how are actions defined in OData V3 metadata?

Hi i'm create a code generation tool for Odata, so far the odata v4 have been really simple to implement.
Regarding odata V3 i have been having troubles with the metadata because I don't know where actions are defined so far I have been only able to see FunctionImport on metadata but not actions, are FunctionImport an equivalent to actions for OData V3? if not can you point on which node of the metadata are the actions located ?
thanks
Actions can be bound or unbound and can be added to the metadata(EDM) as follows:
builder.Entity<entityname>.Action("actionname").Parameter<type>("paramtername").Returns<type>();
Here, builder can be either ODataBuilder or ConventionalOdataBuilder.
If you want the action to be unbound, you can remove the Entity and directly add it to the builder.
If you wish to add the action to IEdmModel directly, you can add the action as a schemaelement.
Source:https://learn.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v3/odata-actions
Edit: Actions are defined in metadata as follows:
<Schema Namespace="Default" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityContainer Name="Container" m:IsDefaultEntityContainer="true">
<EntitySet Name="Movies" EntityType="ODataActionsSample.Models.Movie" />
<FunctionImport Name="SetDueDate" ReturnType="ODataActionsSample.Models.Movie" IsBindable="true" EntitySet="Movies" m:IsAlwaysBindable="true">
<Parameter Name="bindingParameter" Type="ODataActionsSample.Models.Movie" />
<Parameter Name="DueDate" Type="Edm.DateTime" Nullable="false" />
</FunctionImport>
<FunctionImport Name="CreateMovie" ReturnType="ODataActionsSample.Models.Movie" EntitySet="Movies">
<Parameter Name="Title" Type="Edm.String" FixedLength="false" Unicode="false" />
</FunctionImport>
</EntityContainer>

Error in exposing an Entity with ODataService

while I'm Passing an entity in the URL its saying ...
Could not find an entity set or function import for 'Books'.
I'm trying to expose an "ODataService" of book and publisher in Java. Code is very long. so can you suggest me what might be the possible cause for this??
I guess that you didn't define an entity set (Books) for an entity type (Book for example) within your EDM provider. To check this, you can have the look at the root URL of your service (for example http://services.odata.org/V4/OData/OData.svc/). I think that, in your case, no collection entry is defined for Books :
<service xmlns="http://www.w3.org/2007/app"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:m="http://docs.oasis-open.org/odata/ns/metadata"
xml:base="http://services.odata.org/V4/OData/OData.svc/"
m:context="http://services.odata.org/V4/OData/OData.svc/$metadata">
<workspace>
<atom:title type="text">Default</atom:title>
<collection href="Books">
<atom:title type="text">Books</atom:title>
</collection>
(...)
</workspace>
</service>
You could also check if an entity type is defined of type Book. See a link like that http://services.odata.org/V4/OData/OData.svc/$metadata.
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
Namespace="ODataDemo">
<EntityType Name="Book">
(...)
</EntityType>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
The following link provides you a comprehensive description of how to implement an OData service with Olingo v4:
https://templth.wordpress.com/2015/04/27/implementing-an-odata-service-with-olingo/
See section "Implementing a custom EdmProvider" to see how to implement an EDM provider with Olingo.
Hope it will help you,
Thierry

Resources