我一直在谷歌搜索和测试几天没有成功。如果有人可以给我一个指示我指向正确方向的提示,那么我将非常感激。
我的目标是什么:从OData服务获取一些数据并在UI5 oTable中显示。稍后,我将不得不进行CRUD操作,但目前的目的只是成功显示数据。
到目前为止我得到了什么:我有一个MVC项目。我创建了一个OpenUI5Controller.cs,其目的是表示一个ODataService:
public class OpenUI5Controller : Controller
{
private MyEntities myEntities = new MyEntities();
public JsonResult GetAllContragents()
{
try
{
IQueryable<Contragent> contragents = myEntities.Contragent.OrderBy(x => x.Code);
// for now, take the first 100 only
contragents = contragents.Take(100);
var jsonData = new
{
rows = contragents.ToList()
//rows = "123"
};
var res = Json(jsonData, JsonRequestBehavior.AllowGet);
return res;
}
catch (Exception e)
{
LoggingService.WriteLog("Error in OpenUI5Controller.GetAllContragents()", e);
return null;
}
}
}
之后,我尝试使用这样的数据:
var oModel = new sap.ui.model.odata.v2.ODataModel('/OpenUI5/GetAllContragents', {
//maxDataServiceVersion: '2.0',
json: true,
skipMetadataAnnotationParsing: true,
// none of those callbacks is ever triggered, even the requestFailed...!?
requestSent: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestFailed: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
batchRequestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
useBatch : false
});
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
var vfewgvfewgv4 = oModel.getProperty('contragents');
var vfewgvfewgv5 = oModel.getProperty('/contragents');
var vfewgvfewgv6 = oModel.getProperty('Contragents');
var vfewgvfewgv7 = oModel.getProperty('/Contragents');
debugger;
在此断点处停止时,我在Chrome开发者工具中看到了这一点:
走得更远,我来到this并尝试阅读()那些会员:
oModel.read('/Contragents', {
success: function (event) {
debugger;
// event.root I guess should be the received data as jsonString
// As I guess, I will have to get it and give it to oModel.oData manually, or am I wrong? I guess this would cause update(), delete()... calls to fail later on. Anyways...
sap.ui.getCore().setModel(oModel); // https://archive.sap.com/discussions/thread/3746588 - seems not to work like this
if (withJsonModel !== true) { https://help.sap.com/saphelp_uiaddon20/helpdata/en/12/32241b99d7437ba3614698d53dfa4b/content.htm
oTable.setModel(oModel);
oTable.bindRows("/");
//oTable.bindRows("/rows");
oTable.placeAt('tblContragents', "only");
}
},
error: function (event) {
debugger;
}
});
在这里,既没有成功也没有错误回调被触发。
在这次read()尝试之后,我又来了:
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
var vfewgvfewgv4 = oModel.getProperty('contragents');
var vfewgvfewgv5 = oModel.getProperty('/contragents');
var vfewgvfewgv6 = oModel.getProperty('Contragents');
var vfewgvfewgv7 = oModel.getProperty('/Contragents');
之后,我有oTable = new sap.ui.table.Table(...);
最后,我试试这个:
sap.ui.getCore().setModel(oModel);
//oTable.setModel(oModel); // or maybe should be this one directly?
oTable.bindRows("/Contragents");
oTable.placeAt('tblContragents', "only");
结果,我得到一张空桌子。 我想我应该告诉你我在Fiddler中看到的内容:我看到了这个请求:1 200 HTTP localhost:55714 / OpenUI5 / GetAllContragents / $ metadata 因此,在响应部分的TextView中,我将数据视为json,我需要在表中显示。
如何使其工作并在表格中显示数据?
从02.02.2017编辑:我有1%的进度。经过一些越来越多的测试和谷歌搜索,我决定尝试这样。
首先,在一段时间之前(真的不记得何时),在看到a good example for OdataServices后,我决定创建一个像这样的专用控制器:
public class ContragentsController : ODataController
{
private MyEntities db = new MyEntities();
//public System.Web.Mvc.JsonResult GetContragents()
public string GetContragents()
{
try
{
IQueryable<Contragent> contragents = db.Contragent.OrderBy(x => x.Code);
// for now, give me first 100
contragents = contragents.Take(100);
var jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var rows = jsSerializer.Serialize(contragents.ToList());
//var jsonData = new
//{
// rows = model
//};
//var res = new System.Web.Mvc.JsonResult();
//res.Data = jsonData;
//res.JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet;
return rows;
}
catch (Exception e)
{
//...some errorLogging
return null;
}
}
之后,我将调用更改为ODataModel():
var oModel = new sap.ui.model.odata.v2.ODataModel(BASE_HREF + 'odata/', {
//maxDataServiceVersion: '2.0',
json: true,
skipMetadataAnnotationParsing: true,
// those callbacks still do not get called at all
requestSent: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestFailed: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
batchRequestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
useBatch : false
});
整个戏剧是SapUI5在向odata / Contragents提出实际请求之前运行$元数据请求。正如在这种情况下预期的那样,我在Fiddler中看到,服务器404-s到该请求:http://localhost:55714/odata/Contragents/ $元数据并且它没有到达向Contragents发出请求的时刻。我知道,为了防止这个$元数据请求运行,我不得不在某处更改库的源代码,我不想这样做。所以在Fiddler的Composer中,我尝试了以下内容:localhost:55714 / odata / $ metadata,它返回了一些带有所需元数据的xml(可能确实很重要,但我还没有理解为什么)。下一步是修改对sap.ui.model.odata.v2.ODataModel()的调用;如上所示。事实上,最重要的是oModel.read('/ Contragents',{...});显示出生命迹象!现在,成功回调被调用并在event.root中我将这些contragents作为json字符串。 然后呢?我试过oModel.setData(JSON.parse(event.root));但它给了我这个错误:
另外,如果我设法以这种方式工作,我不太明白,oModel的CRUD方法是否有效? oModel.setData() - 从我玩JSONModel()时起就是我所熟悉的东西:
oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataForGrid); // this works like a charm
但是使用JSONModel()意味着,我不能使用sap.ui.model.odata.v2.ODataModel()的insert(),update()...方法,因为JSONModel();我没有提供它们,这是正常的,只要我通过标准的$ .ajax()调用获取dataForGrid。
edit2:在调试时,我注意到,方法ContragentsController.GetContragents();被调用两次,在控制台中,我看到此错误消息:
edit3:关注the good example for ODataService后,我向控制器添加了一个“选择”方法,如下所示:
// GET: odata/Contragents(5)
[EnableQuery]
public SingleResult<Contragent> GetContragents([FromODataUri] string key)
{
return SingleResult.Create(db.Contragent.Where(contragent => contragent.Code == key));
}
在Fiddler中,它是404-s并且根本不会被调用,无论我是这样写的:http://localhost:55714/Contragents(2)
还是这样:http://localhost:55714/odata/Contragents(2)
几分钟后,我有几个百分点的进步。我在教程中看得更近了,我注意到了一些东西,这让我改变了“选择”方法:
// GET: odata/Contragents(5)
[EnableQuery]
public SingleResult<Contragent> Get([FromODataUri] string key)
{
return SingleResult.Create(db.Contragent.Where(contragent => contragent.Code == key));
}
现在,当我撰写此请求时:http://localhost:55714/odata/Contragents(2),它现在不是404,而是406不可接受。我前段时间遇到过这个错误代码,我不明白它是什么原因以及它与ODataServices有什么关系。
我只是提醒自己406意味着什么,结果是控制器上的每个方法都必须以字符串形式返回json结果。因为,SapUI5将Accept-Type设置为“application / json”。