SAPUI5:键中的URI文本语法格式不正确



I使用"SAP Fiori Master Detail application"模板创建SAPUI5应用程序。我让主页面和详细信息页面正常工作,并正确连接到我的OData服务。我现在要做的是将详细信息页面路由到第二个(不同的)详细信息页面。

第一个Detail页面(我称之为Detail1)包含Detail2对象的列表。单击列表中的其中一个对象将进入Detail2页面(在那里它将显示更多信息)。

我使用WebIDE创建了一个新的Detail2视图和控制器,所以它附带了一些填充代码。我还在manifest.json文件中创建了一个新的路由:

{
"name": "detail2Object",
"pattern": "Detail2(Master={masterId},Id={detail1Id})",
"titleTarget": "",
"greedy": false,
"target": ["master", "detail2"]
}
"detail2Object": {
"viewType": "XML",
"transition": "slide",
"clearAggregation": true,
"viewName": "Detail2",
"title": "",
"viewId": "detail2page",
"viewLevel": 3
}

正如您从模式中看到的,服务接受两个参数:Master和ID(这是Master ID和第一个Defects ID)。

独立于我的应用程序测试服务返回的数据很好:http://{root}.com:{port}/sap/opu/odata/sap/TEST_SRV/Detail2(‌​Master='552364',Id='‌​0004')

我在Detail1控制器中创建了一个NavTo函数,以传入Master和Id参数:

_onNav : function (oEvent) {
// get the list item, either from the listItem parameter or from the event's source itself (will depend on the device-dependent mode).
this._showDetail2(oEvent.getParameter("listItem") || oEvent.getSource());
},
_showDetail2 : function (oItem) {
this.getRouter().navTo("detail2Object", {
masterId: oItem.getBindingContext().getProperty("Master"),
detail1Id: oItem.getBindingContext().getProperty("Id")
});
}

当我通过WebIDE测试(使用实时OData和我创建的Mockdata)运行应用程序时,点击Detail1页面中的Detail2对象会将我导航到显示此错误的新页面:

这<"ObjectName">不可用

进入F12工具,我看到以下错误:

MockServer:密钥"Id"-中的URI文本语法格式不正确

HTTP请求failed400,坏请求,{"error":{"code":400,"message":{"lang":"en","value":"格式不正确密钥"Id"中的URI文本语法{}}-

即使url正确地提取了参数,也会发生这种情况:

http://localhost:54634/webapp/test/mockServer.html?hc_reset&original url=mockServer.html&sap ui appCacheBuster=..%2F..%2F..%2F&sap ui xx componentPreload=off#/Detail2(主组件='552364',Id='0004')

通过大量研究,我唯一发现的是这个错误可能与元数据文件有关。然而,两个Id的类型都是Edm.String,而且它们的拼写方式完全相同,所以我认为这不是问题所在。此外,如前所述,使用独立于应用程序运行的相同参数,服务运行良好。

如有任何帮助,我们将不胜感激。

更新

包含Detail2对象列表的Detail1视图:

<List noDataText="Drop list items here" id="__list0" items="{DetailToDetail2}" headerText="Defects">
<items>
<ObjectListItem type="Navigation" title="{Detail2Title}" number="{Qty}" numberUnit="Detail Qty" press="_onNav">
<attributes>
<ObjectAttribute text="{Detail2_Attr}" id="__attribute11" title="Detail2 Attr"/>
<ObjectAttribute id="__attribute12" title="Detail2 Attr2" text="{Detail2_Attr2}"/>
</attributes>
</ObjectListItem>
</items>
</List>

item="{DetailToDetail2}"在服务的元数据中显示为NavigationProperty和Association。

这就是它在Detail1实体中的样子:

<NavigationProperty Name="DetailToDetail2" Relationship="TEST_SRV.DetailToDetail2" FromRole="FromRole_DetailToDetail2" ToRole="ToRole_DetailToDetail2"/>

这是整个Detail2实体:

<EntityType Name="Detail2" sap:content-version="1">
<Key>
<PropertyRef Name="Id"/>
<PropertyRef Name="Master"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false" MaxLength="4" sap:unicode="false" sap:label="Id" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Master" Type="Edm.String" Nullable="false" MaxLength="12" sap:unicode="false" sap:label="Master" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Attr1" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Attribute 1" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Qty" Type="Edm.Int32" sap:unicode="false" sap:label="Detail Qty" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Attr2" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Attribute 2" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Attr3" Type="Edm.String" MaxLength="4" sap:unicode="false" sap:label="Attribute 3" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
</EntityType>

这是DetailToDetail2协会:

<Association Name="DetailToDetail2" sap:content-version="1">
<End Type="TEST_SRV.Detail1" Multiplicity="1" Role="FromRole_DetailToDetail2"/>
<End Type="TEST_SRV.Detail2" Multiplicity="*" Role="ToRole_DetailToDetail2"/>
<ReferentialConstraint>
<Principal Role="FromRole_DetailToDetail2">
<PropertyRef Name="Id"/>
</Principal>
<Dependent Role="ToRole_DetailToDetail2">
<PropertyRef Name="Master"/>
</Dependent>
</ReferentialConstraint>
</Association>

我发现"格式错误的URI"错误不是发生在路由或导航上,而是发生在到达页面后的绑定上。

我的Detail2控制器_onObjectMatched函数如下所示:

_onObjectMatched : function (oEvent) { 
var sObjectMasterId =  oEvent.getParameter("arguments").masterId; 
var sObjectDetailId =  oEvent.getParameter("arguments").detail1Id; 
this.getModel().metadataLoaded().then( function() { 
var sObjectPath = this.getModel().createKey("Detail2", { 
masterId:  sObjectMasterId, 
detail1Id : sObjectDetailId 
}); 
this._bindView("/" + sObjectPath); 
}.bind(this)); 

通过调试,我发现sObjectPath变量被设置为Detail2(Id=null, Master=null)。也就是说,当我意识到masterIddetail1Id不是正确的参数名称时,因为我们没有绑定到路由,而是绑定到路径。所以我用Master代替masterId,用Id:代替detail1Id

_onObjectMatched : function (oEvent) { 
var sObjectMasterId =  oEvent.getParameter("arguments").masterId; 
var sObjectDetailId =  oEvent.getParameter("arguments").detail1Id; 
this.getModel().metadataLoaded().then( function() { 
var sObjectPath = this.getModel().createKey("Detail2", { 
Master:  sObjectMasterId, 
Id: sObjectDetailId 
}); 
this._bindView("/" + sObjectPath); 
}.bind(this)); 

哇,成功了!

感谢所有回应并将我从路线上指向绑定的人。我建议任何出现"格式错误的URI"错误的人查看所有绑定和导航,以验证所有参数的拼写是否正确。

复习"使用参数布线"教程也有很大帮助。

最新更新