Use Sabre SOAP API with iOS - ios

Does anyone know how to use sabre SOAP web services with IOS? anyone has done that ? I am using AFNetworking for the network call.
I am using AFHTTPRequestOperation to make a call to web service but that web service require authentication.
Authentication parameters are username , password , and IPCC. I can set username and password by
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"aaaaa" password:#"aaaaaa" persistence:NSURLCredentialPersistenceNone];
[operation setCredential:credential];
but how can set that IPCC parameter?

Something like (quick and dirty):
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:eb=\"http://www.ebxml.org/namespaces/messageHeader\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">"
" <SOAP-ENV:Header>"
" <eb:MessageHeader SOAP-ENV:mustUnderstand=\"1\" eb:version=\"1.0\">"
" <eb:ConversationId/>"
" <eb:From>"
" <eb:PartyId type=\"urn:x12.org:IO5:01\">999999</eb:PartyId>"
" </eb:From>"
" <eb:To>"
" <eb:PartyId type=\"urn:x12.org:IO5:01\">123123</eb:PartyId>"
" </eb:To>"
" <eb:CPAId>IPCC</eb:CPAId>"
" <eb:Service eb:type=\"OTA\">SessionCreateRQ</eb:Service>"
" <eb:Action>SessionCreateRQ</eb:Action>"
" <eb:MessageData>"
" <eb:MessageId>1000</eb:MessageId>"
" <eb:Timestamp>2001-02-15T11:15:12Z</eb:Timestamp>"
" <eb:TimeToLive>2001-02-15T11:15:12Z</eb:TimeToLive>"
" </eb:MessageData>"
" </eb:MessageHeader>"
" <wsse:Security xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2002/12/secext\" xmlns:wsu=\"http://schemas.xmlsoap.org/ws/2002/12/utility\">"
" <wsse:UsernameToken>"
" <wsse:Username>%#</wsse:Username>"
" <wsse:Password>%#</wsse:Password>"
" <Organization>%#</Organization>"
" <Domain>DEFAULT</Domain>"
" </wsse:UsernameToken>"
" </wsse:Security>"
" </SOAP-ENV:Header>"
" <SOAP-ENV:Body>"
" <eb:Manifest SOAP-ENV:mustUnderstand=\"1\" eb:version=\"1.0\">"
" <eb:Reference xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"cid:rootelement\" xlink:type=\"simple\"/>"
" </eb:Manifest>"
" </SOAP-ENV:Body>"
"</SOAP-ENV:Envelope>"
,username
,password
,ipccValue
];
I assume you mean the ipccValue in the Organization block, rather than the eb:CPAId block
from https://developer.sabre.com/docs/read/soap_basics/Authentication
and credits to send parameter in soap web service from ios

When i tried the above snippet its returning me this
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd1="http://www.opentravel.org/OTA/2002/11" xmlns:tns="https://webservices.sabre.com/websvc" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" targetNamespace="https://webservices.sabre.com/websvc">
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.opentravel.org/OTA/2002/11" schemaLocation="SessionCreateRQRS.xsd"/>
<xsd:import namespace="http://www.ebxml.org/namespaces/messageHeader" schemaLocation="msg-header-2_0.xsd"/>
<xsd:import namespace="http://schemas.xmlsoap.org/ws/2002/12/secext" schemaLocation="wsse.xsd"/>
</xsd:schema>
</types>
<message name="GetSessionCreateInput">
<part name="header" element="eb:MessageHeader"/>
<part name="header2" element="wsse:Security"/>
<part name="body" element="xsd1:SessionCreateRQ"/>
</message>
<message name="GetSessionCreateOutput">
<part name="header" element="eb:MessageHeader"/>
<part name="header2" element="wsse:Security"/>
<part name="body" element="xsd1:SessionCreateRS"/>
</message>
<portType name="SessionCreatePortType">
<operation name="SessionCreateRQ">
<input message="tns:GetSessionCreateInput"/>
<output message="tns:GetSessionCreateOutput"/>
</operation>
</portType>
<binding name="SessionCreateSoapBinding" type="tns:SessionCreatePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="SessionCreateRQ">
<soap:operation soapAction="OTA"/>
<input>
<soap:header message="tns:GetSessionCreateInput" part="header" use="literal"/>
<soap:header message="tns:GetSessionCreateInput" part="header2" use="literal"/>
<soap:body parts="body" use="literal"/>
</input>
<output>
<soap:header message="tns:GetSessionCreateOutput" part="header" use="literal"/>
<soap:header message="tns:GetSessionCreateOutput" part="header2" use="literal"/>
<soap:body parts="body" use="literal"/>
</output>
</operation>
</binding>
<service name="SessionCreateRQService">
<port name="SessionCreatePortType" binding="tns:SessionCreateSoapBinding">
<soap:address location="https://webservices.sabre.com"/>
</port>
</service>
</definitions>

Related

Why destructor of an extended binding is not called when extending binding is removed?

Creating a XulRunner application for Windows I found that if binding B extends binding A. And B is being removed, then only destructor of B is called, not followed by a call of A's destructor.
Is there something wrong with my code, or this is a XulRunner bug (I haven't find matching bug in bugzilla)?
Here is an example that I tested on XulRunner 23 and 35:
main.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<!--<binding-a id="A" style="-moz-binding: url('binding.xml#binding-a')"/>-->
<binding-b id="B" style="-moz-binding: url('binding.xml#binding-b')"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
binding.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="binding-a">
<content>
<xul:label anonid="label" value="Binding A"/>
</content>
<implementation>
<constructor><![CDATA[
var label = document.getAnonymousElementByAttribute(this, "anonid", "label");
label.value = label.value + " A.constructor";
window.print("A.constructor");
]]></constructor>
<destructor><![CDATA[
window.print("A.destructor");
]]></destructor>
<method name="f">
<body><![CDATA[
window.print("A.f");
]]></body>
</method>
</implementation>
</binding>
<binding id="binding-b" extends="#binding-a">
<content>
<xul:label anonid="label" value="Binding B"/>
</content>
<implementation>
<constructor><![CDATA[
window.print("B.constructor");
]]></constructor>
<destructor><![CDATA[
window.print("B.destructor");
]]></destructor>
</implementation>
</binding>
</bindings>
here is the solution for your problem:
bindings.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="binding-a">
<content>
<xul:label anonid="label" value="Binding A"/>
</content>
<implementation>
<constructor><![CDATA[
var label = document.getAnonymousElementByAttribute(this, "anonid", "label");
label.value = label.value + " A.constructor";
window.print("A.constructor");
]]></constructor>
<destructor><![CDATA[
this.destruct();
]]></destructor>
<method name="f">
<body><![CDATA[
window.print("A.f");
]]></body>
</method>
<method name="destruct">
<body><![CDATA[
window.print("A.destructor");
]]></body>
</method>
</implementation>
</binding>
<binding id="binding-b" extends="#binding-a">
<content>
<xul:label anonid="label" value="Binding B"/>
</content>
<implementation>
<constructor><![CDATA[
window.print("B.constructor");
]]></constructor>
<destructor><![CDATA[
this.destruct();
]]></destructor>
<method name="destruct">
<body><![CDATA[
this.__proto__.__proto__.destruct.call(this);
window.print("B.destructor");
]]></body>
</method>
</implementation>
</binding>
</bindings>
bindings.css:
#namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
binding-a { -moz-binding: url("bindings.xml#binding-a"); }
binding-b { -moz-binding: url("bindings.xml#binding-b"); }
main.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="bindings.css" type="text/css"?>
<window id="main" title="My App" width="500" height="300" sizemode="normal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<script><![CDATA[
function print(aString) {
document.getElementById("log_msg").value += aString + "\n";
}
function removeElementById(aId) {
document.getElementById(aId).remove();
};
function callF(aId) {
document.getElementById(aId).f();
}
]]></script>
<vbox flex="1">
<label onclick="removeElementById('A')">remove A</label>
<label onclick="removeElementById('B')">remove B</label>
<label onclick="callF('A')">Call A.f()</label>
<label onclick="callF('B')">Call B.f()</label>
<binding-a id="A"/>
<binding-b id="B"/>
<textbox id="log_msg" label="Text" placeholder="placeholder" multiline="true" rows="6"/>
</vbox>
</window>
I know that it is a hack in fact but it works.

SharePoint Online BCS OData External Content Can't Update, View or Delete

Using Visual Studio 2013, I created an Entity Model over an existing database. Each table has a GUID for it's primary key. I created an MVC Web API project with related OData Bindings and Controllers.
Here is how I create the OData Binding;
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<HRPosition>("HRPositions").EntityType.HasKey(p=>p.HTPositionGuid);
Here is a sample controller for the HRPositions Entity.
public class HRPositionsController : ODataController
{
private EFSEntities db = new EFSEntities();
// GET: odata/HRPositions
[EnableQuery]
public IQueryable<HRPosition> GetHRPositions()
{
return db.HRPositions;
}
// GET: odata/HRPositions(5)
[EnableQuery]
public SingleResult<HRPosition> GetHRPosition([FromODataUri] Guid key)
{
return SingleResult.Create(db.HRPositions.Where(hRPosition => hRPosition.HTPositionGuid == key));
}
// PUT: odata/HRPositions(5)
public async Task<IHttpActionResult> Put([FromODataUri] Guid key, Delta<HRPosition> patch)
{
Validate(patch.GetEntity());
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
HRPosition hRPosition = await db.HRPositions.FindAsync(key);
if (hRPosition == null)
{
return NotFound();
}
patch.Put(hRPosition);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!HRPositionExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(hRPosition);
}
// POST: odata/HRPositions
public async Task<IHttpActionResult> Post(HRPosition hRPosition)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.HRPositions.Add(hRPosition);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (HRPositionExists(hRPosition.HTPositionGuid))
{
return Conflict();
}
else
{
throw;
}
}
return Created(hRPosition);
}
// PATCH: odata/HRPositions(5)
[AcceptVerbs("PATCH", "MERGE")]
public async Task<IHttpActionResult> Patch([FromODataUri] Guid key, Delta<HRPosition> patch)
{
Validate(patch.GetEntity());
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
HRPosition hRPosition = await db.HRPositions.FindAsync(key);
if (hRPosition == null)
{
return NotFound();
}
patch.Patch(hRPosition);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!HRPositionExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(hRPosition);
}
// DELETE: odata/HRPositions(5)
public async Task<IHttpActionResult> Delete([FromODataUri] Guid key)
{
HRPosition hRPosition = await db.HRPositions.FindAsync(key);
if (hRPosition == null)
{
return NotFound();
}
db.HRPositions.Remove(hRPosition);
await db.SaveChangesAsync();
return StatusCode(HttpStatusCode.NoContent);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool HRPositionExists(Guid key)
{
return db.HRPositions.Count(e => e.HTPositionGuid == key) > 0;
}
}
Once the OData Service is deployed and using Fiddler I am able to query the Service endpoints and retrieve the full list of data as well as single entity data.
I then created a SharePoint App in which I create an External Content Type by referencing the OData service. This creates the ECT Model definitions for each endpoint.
Here is the ECT for HRPositions;
<?xml version="1.0" encoding="utf-16"?>
<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="EFSData" xmlns="http://schemas.microsoft.com/windows/2007/BusinessDataCatalog">
<LobSystems>
<LobSystem Name="EFSODATA" Type="OData">
<Properties>
<Property Name="ODataServiceMetadataUrl" Type="System.String">https://efsodataapi.azurewebsites.net/OData/$metadata</Property>
<Property Name="ODataServiceMetadataAuthenticationMode" Type="System.String">PassThrough</Property>
<Property Name="ODataServicesVersion" Type="System.String">2.0</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<LobSystemInstances>
<LobSystemInstance Name="EFSODATA">
<Properties>
<Property Name="ODataServiceUrl" Type="System.String">https://efsodataapi.azurewebsites.net/OData</Property>
<Property Name="ODataServiceAuthenticationMode" Type="System.String">PassThrough</Property>
<Property Name="ODataFormat" Type="System.String">application/atom+xml</Property>
<Property Name="HttpHeaderSetAcceptLanguage" Type="System.Boolean">true</Property>
</Properties>
</LobSystemInstance>
</LobSystemInstances>
<Entities>
<Entity Name="HRPositions" DefaultDisplayName="HRPositions" Namespace="EFSData" Version="1.0.0.0" EstimatedInstanceCount="2000">
<Properties>
<Property Name="ExcludeFromOfflineClientForList" Type="System.String">False</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<Identifiers>
<Identifier Name="HTPositionGuid" TypeName="System.Guid" />
</Identifiers>
<Methods>
<Method Name="CreateHRPosition" DefaultDisplayName="Create HRPosition" IsStatic="false">
<Properties>
<Property Name="ODataEntityUrl" Type="System.String">/HRPositions</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<Parameters>
<Parameter Name="#HTPositionGuid" Direction="In">
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" CreatorField="true" />
</Parameter>
<Parameter Name="#PosistionCode" Direction="In">
<TypeDescriptor Name="PosistionCode" DefaultDisplayName="PosistionCode" TypeName="System.String" CreatorField="true" />
</Parameter>
<Parameter Name="#PositionName" Direction="In">
<TypeDescriptor Name="PositionName" DefaultDisplayName="PositionName" TypeName="System.String" CreatorField="true" />
</Parameter>
<Parameter Name="#Description" Direction="In">
<TypeDescriptor Name="Description" DefaultDisplayName="Description" TypeName="System.String" CreatorField="true" />
</Parameter>
<Parameter Name="#CreateHRPosition" Direction="Return">
<TypeDescriptor Name="CreateHRPosition" DefaultDisplayName="CreateHRPosition" TypeName="Microsoft.BusinessData.Runtime.DynamicType">
<TypeDescriptors>
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" ReadOnly="true" />
<TypeDescriptor Name="PosistionCode" DefaultDisplayName="PosistionCode" TypeName="System.String" />
<TypeDescriptor Name="PositionName" DefaultDisplayName="PositionName" TypeName="System.String" />
<TypeDescriptor Name="Description" DefaultDisplayName="Description" TypeName="System.String" />
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="CreateHRPosition" Type="Creator" ReturnParameterName="#CreateHRPosition" ReturnTypeDescriptorPath="CreateHRPosition">
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
</MethodInstance>
</MethodInstances>
</Method>
<Method Name="ReadSpecificHRPosition" DefaultDisplayName="Read Specific HRPosition" IsStatic="false">
<Properties>
<Property Name="ODataEntityUrl" Type="System.String">/HRPositions(HTPositionGuid=guid'#HTPositionGuid')</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<Parameters>
<Parameter Name="#HTPositionGuid" Direction="In">
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" />
</Parameter>
<Parameter Name="#HRPosition" Direction="Return">
<TypeDescriptor Name="HRPosition" DefaultDisplayName="HRPosition" TypeName="Microsoft.BusinessData.Runtime.DynamicType">
<TypeDescriptors>
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" ReadOnly="true" />
<TypeDescriptor Name="PosistionCode" DefaultDisplayName="PosistionCode" TypeName="System.String" />
<TypeDescriptor Name="PositionName" DefaultDisplayName="PositionName" TypeName="System.String" />
<TypeDescriptor Name="Description" DefaultDisplayName="Description" TypeName="System.String" />
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="ReadSpecificHRPosition" Type="SpecificFinder" Default="true" ReturnParameterName="#HRPosition" ReturnTypeDescriptorPath="HRPosition">
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
</MethodInstance>
</MethodInstances>
</Method>
<Method Name="ReadAllHRPosition" DefaultDisplayName="Read All HRPosition" IsStatic="false">
<Properties>
<Property Name="ODataEntityUrl" Type="System.String">/HRPositions?$top=#LimitHRPositionss</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<FilterDescriptors>
<FilterDescriptor Name="LimitFilter" DefaultDisplayName="LimitFilter" Type="Limit" />
</FilterDescriptors>
<Parameters>
<Parameter Name="#LimitHRPositionss" Direction="In">
<TypeDescriptor Name="LimitHRPositionss" DefaultDisplayName="LimitHRPositionss" TypeName="System.Int32" AssociatedFilter="LimitFilter">
<Properties>
<Property Name="LogicalOperatorWithPrevious" Type="System.String">None</Property>
<Property Name="Order" Type="System.String">0</Property>
</Properties>
<DefaultValues>
<DefaultValue MethodInstanceName="ReadAllHRPosition" Type="System.Int32">100</DefaultValue>
</DefaultValues>
</TypeDescriptor>
</Parameter>
<Parameter Name="#HRPositions" Direction="Return">
<TypeDescriptor Name="HRPositions" DefaultDisplayName="HRPositions" TypeName="Microsoft.BusinessData.Runtime.IDynamicTypeEnumerator" IsCollection="true">
<TypeDescriptors>
<TypeDescriptor Name="HRPosition" DefaultDisplayName="HRPosition" TypeName="Microsoft.BusinessData.Runtime.DynamicType">
<TypeDescriptors>
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" ReadOnly="true" />
<TypeDescriptor Name="PosistionCode" DefaultDisplayName="PosistionCode" TypeName="System.String" />
<TypeDescriptor Name="PositionName" DefaultDisplayName="PositionName" TypeName="System.String" />
<TypeDescriptor Name="Description" DefaultDisplayName="Description" TypeName="System.String" />
</TypeDescriptors>
</TypeDescriptor>
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="ReadAllHRPosition" Type="Finder" Default="true" ReturnParameterName="#HRPositions" ReturnTypeDescriptorPath="HRPositions">
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
</MethodInstance>
</MethodInstances>
</Method>
<Method Name="UpdateHRPosition" DefaultDisplayName="Update HRPosition" IsStatic="false">
<Properties>
<Property Name="ODataEntityUrl" Type="System.String">/HRPositions(HTPositionGuid=guid'#HTPositionGuid')</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<Parameters>
<Parameter Name="#HTPositionGuid" Direction="In">
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" UpdaterField="true" />
</Parameter>
<Parameter Name="#PosistionCode" Direction="In">
<TypeDescriptor Name="PosistionCode" DefaultDisplayName="PosistionCode" TypeName="System.String" UpdaterField="true" />
</Parameter>
<Parameter Name="#PositionName" Direction="In">
<TypeDescriptor Name="PositionName" DefaultDisplayName="PositionName" TypeName="System.String" UpdaterField="true" />
</Parameter>
<Parameter Name="#Description" Direction="In">
<TypeDescriptor Name="Description" DefaultDisplayName="Description" TypeName="System.String" UpdaterField="true" />
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="UpdateHRPosition" Type="Updater">
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
</MethodInstance>
</MethodInstances>
</Method>
<Method Name="DeleteHRPosition" DefaultDisplayName="Delete HRPosition" IsStatic="false">
<Properties>
<Property Name="ODataEntityUrl" Type="System.String">/HRPositions(HTPositionGuid=guid'#HTPositionGuid')</Property>
</Properties>
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
<Parameters>
<Parameter Name="#HTPositionGuid" Direction="In">
<TypeDescriptor Name="HTPositionGuid" DefaultDisplayName="HTPositionGuid" TypeName="System.Guid" IdentifierName="HTPositionGuid" />
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="DeleteHRPosition" Type="Deleter">
<AccessControlList>
<AccessControlEntry Principal="STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string">
<Right BdcRight="Edit" />
<Right BdcRight="Execute" />
<Right BdcRight="SelectableInClients" />
<Right BdcRight="SetPermissions" />
</AccessControlEntry>
</AccessControlList>
</MethodInstance>
</MethodInstances>
</Method>
</Methods>
</Entity>
</Entities>
</LobSystem>
</LobSystems>
</Model>
I uploaded the ECT into SharePoint Online BCS and all looks fine;
From there I create an external list and reference the HRPositions ECT, which creates and SP List but is missing the primary key (which is the GUID).
This view shows the proper data;
I am able to add a new item to the list;
And it shows in the read all view;
But I can't edit, delete or view any list item as I get this error for each operation;
I attached to the OData Web Service and could see why the issue is occurring. Turns out the Auto-Generated External Control Types (ECT) within Visual Studio that were reflected off the OData Service have an issue in that for some reason it is formulating the request as /HRPositions(HTPositionGuid=guid'#HTPositionGuid');
It should really only be /HRPositions(guid'#HTPositionGuid');
Can anyone tell me why it's including the HTPositionGuid= within the Parameter list?
I can manually edit the code-generated ECT files for each entity but that seems silly.

Return type in wsimport-generated service stub methods

Here is an example of wsimport-generated service stub method:
#WebMethod(operationName = "GetSynonym", action = "GetSynonymRequest")
#WebResult(name = "Synonyms", targetNamespace = "service.bnsf.com/contact/ContactMessages")
#RequestWrapper(localName = "GetSynonym", targetNamespace = "service.bnsf.com/contact/ContactMessages", className = "com.bnsf.service.contact.contactmessages.GetSynonymRequest")
#ResponseWrapper(localName = "GetSynonymResponse", targetNamespace = "service.bnsf.com/contact/ContactMessages", className = "com.bnsf.service.contact.contactmessages.GetSynonymResponse")
public Synonyms getSynonym(
#WebParam(name = "RequestContext", targetNamespace = "service.bnsf.com/contact/ContactMessages") RequestContext requestContext,
#WebParam(name = "SynonymId", targetNamespace = "service.bnsf.com/contact/ContactMessages") EntityId synonymId)
throws BusinessFaultMessage, ServiceFaultMessage;
Note that return type is Synonyms class.
Here are the relevant wsdl parts:
<xs:element name="GetSynonymResponse" type="GetSynonymResponse"/>
<xs:complexType name="GetSynonymResponse">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="Synonyms" type="account:Synonyms"/>
</xs:sequence>
</xs:complexType>
...
<wsdl:message name="GetSynonymResponse">
<wsdl:part element="msg:GetSynonymResponse" name="GetSynonymResponse"/>
</wsdl:message>
...
<wsdl:operation name="GetSynonym">
<soap:operation soapAction="GetSynonymRequest" style="document"/>
<wsdl:input name="GetSynonymRequestRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetSynonymRequestResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="BusinessFault">
<soap:fault name="BusinessFault" use="literal"/>
</wsdl:fault>
<wsdl:fault name="ServiceFault">
<soap:fault name="ServiceFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
By default wsimport has generated service method with Synonyms class as return type rather than GetSynonymResponse class.
My question is whether this is customizable - is there a possibility to make wsimport generate service methods with different signatures, particularly having GetSynonymResponse class as return type?
Thanks in advance,
Valery
Found how this is configurable:
The feature called "WrapperStyle" should be disabled to make generated method return xxxResponse type.
This is accomplishable by providing -b parameter to wsimport like
wsimport" -b binding.xml ContactService.wsdl
with binding.xml contents as
<jaxws:bindings wsdlLocation="ContactService.wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<!-- Turn off wrapper style Java method signature generation -->
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>

ZF2 and implementing a SOAP server returning a complex type

I'm trying to implement a SOAP server using Zend Framework 2 in PHP5.5. I've come as far as this:
library.php
<?php
namespace Library;
class IncrementedInt
{
/**
* #var integer
**/
public $original;
/**
* #var integer
**/
public $incremented;
public function __construct($num)
{
$this->original = $num;
$this->incremented = ++$num;
}
}
webservice.php
<?php
require_once 'library.php';
require_once 'Zend/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true));
$loader->register();
class Math
{
/**
* This method takes ...
*
* #param integer $inputParam
* #return \Library\IncrementedInt
*/
public function increment($inputParam)
{
return new \Library\IncrementedInt($inputParam);
}
}
if (isset($_GET['wsdl'])) {
$autodiscover = new \Zend\Soap\AutoDiscover();
$autodiscover->setClass('Math')
->setBindingStyle(array('style' => 'document'))
->setUri('http://localhost' . $_SERVER['SCRIPT_NAME']);
header('Content-type: application/xml');
echo $autodiscover->toXml();
}
else {
// pointing to the current file here
$soap = new \Zend\Soap\Server('http://localhost' . $_SERVER['SCRIPT_NAME'] . '?wsdl');
$soap->setClass('Math');
$soap->handle();
}
Loading the URL http://localhost/webservice.php?wsdl in a browser will output:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://localhost/webservice.php" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" name="Math" targetNamespace="http://localhost/webservice.php">
<script/>
<types>
<xsd:schema targetNamespace="http://localhost/webservice.php">
<xsd:element name="increment">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="inputParam" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="IncrementedInt">
<xsd:all>
<xsd:element name="original" type="xsd:int" nillable="true"/>
<xsd:element name="incremented" type="xsd:int" nillable="true"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="incrementResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="incrementResult" type="tns:IncrementedInt"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<portType name="MathPort">
<operation name="increment">
<documentation>This method takes ...</documentation>
<input message="tns:incrementIn"/>
<output message="tns:incrementOut"/>
</operation>
</portType>
<binding name="MathBinding" type="tns:MathPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="increment">
<soap:operation soapAction="http://localhost/webservice.php#increment"/>
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="MathService">
<port name="MathPort" binding="tns:MathBinding">
<soap:address location="http://localhost/webservice.php"/>
</port>
</service>
<message name="incrementIn">
<part name="parameters" element="tns:increment"/>
</message>
<message name="incrementOut">
<part name="parameters" element="tns:incrementResponse"/>
</message>
</definitions>
As you can see the IncrementedInt class and its properties original and incremented are defined. Yet when I call the service with sending this XML (using soapUI):
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://localhost/webservice.php">
<soapenv:Header/>
<soapenv:Body>
<web:increment>
<inputParam xsi:type="xsd:int">2</inputParam>
</web:increment>
</soapenv:Body>
</soapenv:Envelope>
The server will respond like:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/webservice.php" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:incrementResponse>
<return xsi:type="ns1:IncrementedInt"/>
</ns1:incrementResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
As you can see the return value is not expanded and it's just like the type is named. Has anyone successfully returned a complex type in ZF2 SOAP server? How? I searched the Internet for an example but I could not find any!
It turned out all I was missing was the fact that Zend Framework caches WSDLs by default. So all I needed to do was to:
<?php
require_once 'library.php';
require_once 'Zend/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true));
$loader->register();
class Math
{
/**
* This method takes ...
*
* #param integer $inputParam
* #return \Library\IncrementedInt
*/
public function increment($inputParam)
{
return new \Library\IncrementedInt($inputParam);
}
}
if (isset($_GET['wsdl'])) {
$autodiscover = new \Zend\Soap\AutoDiscover();
$autodiscover->setClass('Math')
->setUri('http://localhost' . $_SERVER['SCRIPT_NAME']);
header('Content-type: application/xml');
echo $autodiscover->toXml();
}
else {
// pointing to the current file here
$soap = new \Zend\Soap\Server('http://localhost' . $_SERVER['SCRIPT_NAME'] . '?wsdl', array('cache_wsdl' => WSDL_CACHE_NONE));
$soap->setClass('Math');
$soap->handle();
}
The changes are:
When instantiating a Server it is set as options to disable WSDL caching.
The ->setBindingStyle(array('style' => 'document')) method call to AutoDiscovery is omitted as it causes trouble and prevents a successful SOAP call.

Recieving SOAP error when requesting a WCF Web Service in Objective C (iOS App)

I am trying to call a web service from an iOS app. I have developed that service in WCF. The web service is hosted on IIS configured with BasicHTTPBinding. I have developed a simple iOS app that calls that web service hosted on a remote PC.
The iOS app is working fine but the SOAP service doesn't seem to understand the request I am sending from the iOS app. Here are all the details, the error I get is at the end.
The WSDL of web service is:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="SLService" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://10.211.55.4/TestService/SLService.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://10.211.55.4/TestService/SLService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ISLService_DoWork_InputMessage">
<wsdl:part name="parameters" element="tns:DoWork"/>
</wsdl:message>
<wsdl:message name="ISLService_DoWork_OutputMessage">
<wsdl:part name="parameters" element="tns:DoWorkResponse"/>
</wsdl:message>
<wsdl:portType name="ISLService">
<wsdl:operation name="DoWork">
<wsdl:input wsaw:Action="http://tempuri.org/ISLService/DoWork" message="tns:ISLService_DoWork_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/ISLService/DoWorkResponse" message="tns:ISLService_DoWork_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_ISLService" type="tns:ISLService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="DoWork">
<soap:operation soapAction="http://tempuri.org/ISLService/DoWork" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SLService">
<wsdl:port name="BasicHttpBinding_ISLService" binding="tns:BasicHttpBinding_ISLService">
<soap:address location="http://10.211.55.4/TestService/SLService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Here is how I am making the SOAP request in iOS, the problem is most probably here:
NSString *soapMessage = [NSString stringWithFormat:#"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><DoWork></DoWork></SOAP-ENV:Body></SOAP-ENV:Envelope>"];
NSURL *url=[NSURL URLWithString:#"http://10.211.55.4/TestService/SLService.svc/"];
NSMutableURLRequest *theRequest= [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: #"urn:SLService/DoWork" forHTTPHeaderField:#"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
responseData = [[NSMutableData data] retain];
} else {
messageTextView.text=#"Failed";
}
Here is what's inside the WCF Web Service class:
namespace TestSilverlight.Web{
public class SLService : ISLService
{
public string DoWork()
{
return "Service Works!";
}
}}
Here is the content of web.config file in WCF web service:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Here is the SOAP response (error) I get in the responseData object:
a:ActionNotSupportedThe message with Action 'urn:ISLService/DoWork' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
I suck at asking questions here, I hope you guys understand this one. Please help.
The problem is with your SOAPAction header. I suspect the issue is the same as this calling wcf webservice using basichttpbinding without REST or JSON.
The solution will be to change your SOAPAction from
urn:SLService/DoWork
to
http://tempuri.org/SLService/DoWork
or maybe even
http://tempuri.org/ISLService/DoWork

Resources