Not able to call Odata Service in UI5 - odata

I am calling Odata service for my UI5 application. I am using below mentioned code for creating the model.
var oModel = new sap.ui.model.json.JSONModel("https://<>/sap/opu/odata/SIE/MED_TEST_OSIRIS_SRV/SalesOrderSet?$format=json");
//Getting the Data and putting in list model
sap.ui.getCore().setModel(oModel,"table");
With this code , I can call the Odata and display the results in a table.
But now when I am applying filter like this :
https://<>/sap/opu/odata/SIE/MED_TEST_OSIRIS_SRV/SalesOrderSet?$filter=Country_SP
eq 'DE'
I can get the results in browser's address bar but not in the code like :
var sUrl = "https://<>/sap/opu/odata/SIE/MED_TEST_OSIRIS_SRV/SalesOrderSet?$filter=Country_SP eq 'DE'";
var oModel = new sap.ui.model.json.JSONModel(sUrl);
what I am doing wrong ? I can filter the results in the browser with the same url :(
Regards,
Mayank

Try with synchronous call.
var oModelData = new sap.ui.model.json.JSONModel();
oModelData.loadData(sUrl, null, false);

The UI5 ODataModel only supports the base address of the OData service. The model will construct filtered and sorted queries based on that base address. It will do that for example when you supply Filters or Sorters to an aggregation binding.
You can however use a JSONModel in your case. It's agnostic to the OData query parameters and will simply call the given URL and store the results.

You need to encode URI component the filters, and then append to the base URL
var filter = "Country_SP eq 'DE'";
var baseUrl = "https://<>/sap/opu/odata/SIE/MED_TEST_OSIRIS_SRV/SalesOrderSet";
var sUrl = baseUrl+encodeURIComponent(filter);
var oModel = new sap.ui.model.json.JSONModel(sUrl);

Related

Dynamic binding model for use in HttpClient

I have a Web Api that takes a complex object and adds it to the database.
var myWidgit= new Widgit() {
Name = "WidgitName",
Price = 50,
Category = "Appliance" };
HttpResponseMessage response = client.PostAsync("api/createwidgit", myWidgit);
I need to make a one off call to the API and I would like to avoid creating a separate class file for Widgit.
Is there a way to define the Widgit class and assign it values in the method that makes use of it? Sort of like a dynamic class just used in this method.
I think I figured it out ...
HttpResponseMessage response = client.PostAsync("api/createwidgit", new StringContent(string.Format("Name={0}&Price={1}&Category={2}", HttpUtility.UrlEncode("WidgitName"), HttpUtility.UrlEncode(50), HttpUtility.UrlEncode("Appliance"), Encoding.UTF8, "application/x-www-form-urlencoded"));
Essentially the dynamic object I was looking to create is accomplished using
new StringContent(string.Format("Name={0}&Price={1}&Category={2}", HttpUtility.UrlEncode("WidgitName"), HttpUtility.UrlEncode(50)), HttpUtility.UrlEncode("Appliance"), Encoding.UTF8,
"application/x-www-form-urlencoded")
Sorry I could not figure out better formatting

SingleResult<T> not serializable in Web API when querying by key

Trying to find single record using primary key CourseID against odata web.api using this:
var editedcourse = container.Courses.Where(c => c.CourseID == ID).SingleOrDefault();
This is error:
<m:innererror>
<m:message>The 'ObjectContent`1' type failed to serialize the response body for content type 'application/atom+xml; charset=utf-8'.</m:message>
<m:type>System.InvalidOperationException</m:type>
<m:stacktrace></m:stacktrace>
<m:internalexception>
<m:message>'SingleResult`1' cannot be serialized using the ODataMediaTypeFormatter.</m:message>
<m:type>System.Runtime.Serialization.SerializationException</m:type>
The web.api controller method by default was not queriable, thus client failed. Added annotation to fix: [Queryable(AllowedOrderByProperties = "Id")]
Try adding the code below to your WebApiConfig.cs file.
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
I think the first two lines are optional if you don't use Json format.
Refer to
http://social.msdn.microsoft.com/Forums/vstudio/en-US/a5adf07b-e622-4a12-872d-40c753417645/web-api-error-the-objectcontent1-type-failed-to-serialize-the-response-body-for-content?forum=wcf
I think you have to make sure any relations are loaded. As a workaround you could create a new DTO (data transfer object) and put all you need in it.

Breeze is not working with some project settings

I have a problem using breeze on a project based on John Papa's HotTowel. I configured breeze like:
var mgr = new breeze.EntityManager('breeze/Breeze');
everything is ok but in the case I change the Project properties Start Action from Current Page to Specific Page: HotTowel/Index and breeze doesn't work properly.
I've checked the requests using firebug. It seems in this case application sends a GET request like this:
http://localhost:53180/HotTowel/Index/breeze/Breeze/Metadata
instead of
http://localhost:53180/breeze/Breeze/Metadata
I've also checked this part of breeze.js which is going to send get request.
The url parameter is set to breeze/Breeze/Metadata in both cases which seems correct.
ctor.prototype.fetchMetadata = function (metadataStore, dataService) {
var serviceName = dataService.serviceName;
var url = dataService.makeUrl("Metadata");
var deferred = Q.defer();
var that = this;
ajaxImpl.ajax({
url: url,
dataType: 'json',...
I've also tried ~/breeze/Breeze but it didn't work as remote service name.
As I'm new to web, probably it's not related to breeze.
The question is why the ajax call (or breeze) depends on how the project activates?
Add a / character to your configuration to execute the request relative to the base directory:
var mgr = new breeze.EntityManager('/breeze/Breeze');
The reason why this happens is because you specified a relative path for the EntityManager and if your url is localhost:53180/HotTowel/Index then the relative url for the EntityManager is localhost:53180/HotTowel/Index + /breeze/Breeze.
To correct the issue, change your EntityManager path to the following:
var mgr = new breeze.EntityManager('breeze/Breeze');

Using OData with breeze - query not executed

i am trying to query webapi asp.net odata controller using breeze
in my query
function getIncidentsInternal() {
var query = breeze.EntityQuery
.from("Customers");
//var serverAddress = "http://localhost:53809/odata/";
var serverAddress = "/odata";
var manager = new breeze.EntityManager(serverAddress);
return manager.executeQuery(query)
.then(getSucceededInternal); // caller to handle failure
after the metadata request there is no actual request to get the items
i see one error of
OPTIONS http://localhost:53809/odata/$metadata 405 (Method Not Allowed)
after this request there is a GEt request with the metadata which pass but no query
If you got a 405, I bet you have issues with CORS. Does you OData service support CORS? Also, looks like you need to change breeze to use OData instead of web api. you can do that like so..
breeze.config.initializeAdapterInstances({ dataService: "OData" });

Retrieving entries by key without using filter in Breezejs

When we query for an entity in Breezejs with its key, the framework is creating an url using the $filter property.
/api/orderCollection?$filter=orderId%20eq%20'0001'
Is it possible to force breeze to use the odata format?
/api/orderCollection(0001)
I have a standard odata service and it doesn't support the first url...
this is my query:
var query = new breeze.EntityQuery().from("OrderCollection");
var pred = breeze.Predicate.create('orderId', '==', orderId);
query = query.where(pred);
kr,
Joachim
Breeze always generates OData queries using the $filter operator because that gives us the most flexibility and consistency as you add Predicate expressions. This is part of the OData spec.
However, if you really need the alternative expression you can actually pass the entire URL as a string to Breeze to execute as a query, i.e.
var query = "orderCollection(0001)";
myEntityManager.executeQuery(query).then(function (data) {
...
});
Breeze should still return the same results that this will
var query = new breeze.EntityQuery().from("OrderCollection")
.where('orderId', '==', orderId);
myEntityManager.executeQuery(query).then(function (data) {
...
});

Resources