projects/wms-framework/src/lib/wcfserviceinvocationsupport/HttpBasicBinding.ts
Defines a custom {CommunicationBinding} object that interacts with a server by using standard SOAP messages.
Properties |
|
Methods |
|
constructor(serviceNamespace: string, contract: string)
|
||||||||||||
Creates an instance of HttpBasicBinding that is able to consume Soap messages from the given service http://server/IMyContract/MethodName
Parameters :
|
contract |
Type : string
|
Elements |
Type : BindingElementCollection
|
Default value : new BindingElementCollection()
|
serviceNamespace |
Type : string
|
Public CloseTimeout |
Type : any
|
Default value : null
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:38
|
Public EndpointSuffix |
Type : string
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:56
|
EndpointSuffix property |
Public OpenTimeout |
Type : any
|
Default value : null
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:36
|
Public ReceiveTimeout |
Type : any
|
Default value : null
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:37
|
Public SendTimeout |
Type : any
|
Default value : null
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:35
|
Public UsePost |
Type : boolean
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:47
|
UsePost property |
Private convertBooleanValue | ||||||||
convertBooleanValue(value: any)
|
||||||||
Converts the given value to a boolean value
Parameters :
Returns :
boolean
{boolean} |
Private convertCollectionValue | ||||||||||||||||
convertCollectionValue(prefix: string, value: any, collectionElementType: any)
|
||||||||||||||||
Converts a list of elements to be set to a ObservableCollection object.
Parameters :
Returns :
any
{*} |
Private convertDateValue | ||||||||
convertDateValue(value: any)
|
||||||||
Converts the given value to a Date object
Parameters :
Returns :
Date
a Date object |
Private convertNumberValue | ||||||||
convertNumberValue(value: any)
|
||||||||
Converts the given value to a number one
Parameters :
Returns :
number
{Number} |
Private convertStringValue | ||||||||
convertStringValue(value: any)
|
||||||||
Converts the given value to a string one
Parameters :
Returns :
string
{string} |
CreateBindingElements |
CreateBindingElements()
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:391
|
Returns :
BindingElementCollection
|
CreateMessage |
CreateMessage(baseUrl: string, methodName: string, args: any[])
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:58
|
Returns :
Message
|
CreateResponseMessage |
CreateResponseMessage(result: any, classConstructor?: any)
|
Inherited from
CommunicationBinding
|
Defined in
CommunicationBinding:70
|
Returns :
Message
|
Private extractNs | ||||||||
extractNs(data: any)
|
||||||||
Extracts the Envelope prefix, for the following definition it returns 's': xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
Parameters :
Returns :
string
{string} a namespace prefix. |
Private extractServiceNs | ||||||||||||
extractServiceNs(data: any, namespace: string)
|
||||||||||||
Extracts the service namespace attribute. For the folowing service namespace it returns 'a': xmlns:a="http://myserver.com/MyService/2011/11"
Parameters :
Returns :
string
a string with the prefix value for the given namespace |
Private extractValue | ||||||||||||||||
extractValue(prefix: string, value: any, property: PropertyInfo)
|
||||||||||||||||
Extracts the response value for a given property. Value is extracted depending on the property datatype, current support datatypes are String, Number, Boolean, Date and ObservableCollection
Parameters :
Returns :
any
{*} |
Private fillElement | ||||||||||||||||||||
fillElement(instance: any, element: any, prefix: string, classConstructor: any)
|
||||||||||||||||||||
Filles the given instance with all properties gien in element object.
Parameters :
Returns :
void
|
Private isNull | ||||||
isNull(value)
|
||||||
Checks if the given value matches the explicit null one.
Parameters :
Returns :
boolean
{boolean} |
Private processElements | ||||||||||||||||
processElements(data: any, classConstructor: any, prefix?: string)
|
||||||||||||||||
Creates a new object of the given class constructor and sets its properties to the values in data.
Parameters :
Returns :
any[]
{*} a new object created using the given constructor |
Private processEnvelopeBody | ||||||||||||||||||||
processEnvelopeBody(message: SoapMessage, namespaceVar: string, body: any, classConstructor?: any)
|
||||||||||||||||||||
Process the sopa body section of an evelop. As a result it returns a new {SoapMessage} object containing
the results given in the body.
Body Sample:
<s:Body>
Parameters :
Returns :
SoapMessage
a {SoapMessage} containing the loaded response. |
import { Application } from '../basecomponentmodel/Application';
import { Exception } from '../baseframework';
import { ObservableCollection } from '../baseframework/collections';
import {
PropertyInfo,
ReflectionHelper,
} from '../baseframework/ReflectionSupport';
import { xml2json } from '../utils/XmlUtils';
import { BindingElementCollection } from './channels';
import { CommunicationBinding } from './CommunicationSupport';
import { Message } from './Message';
import { SoapMessage } from './SoapMessage';
/*****************************************************************************
* Copyright (C) Mobilize.Net <info@mobilize.net> - All Rights Reserved
*
* This file is part of the Mobilize Frameworks, which is
* proprietary and confidential.
*
* NOTICE: All information contained herein is, and remains
* the property of Mobilize.Net Corporation.
* The intellectual and technical concepts contained herein are
* proprietary to Mobilize.Net Corporation and may be covered
* by U.S. Patents, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Mobilize.Net Corporation.
******************************************************************************/
/**
* Defines a custom {CommunicationBinding} object that interacts with a server by using
* standard SOAP messages.
*
* @export
* @class HttpBasicBinding
* @extends {CommunicationBinding}
*/
export class HttpBasicBinding extends CommunicationBinding {
#serviceNamespace: string;
#contract: string;
/**
* Creates an instance of HttpBasicBinding that is able to consume Soap messages from
* the given service
* @param {string} serviceNamespace Namespace of the service to consume data from
* @param {string} contract contract name of the soap service, for instance in following sample
* http://server/IMyContract/MethodName
* @memberof HttpBasicBinding
*/
constructor(serviceNamespace: string, contract: string) {
super();
this.#serviceNamespace = serviceNamespace;
this.#contract = contract;
}
Elements: BindingElementCollection = new BindingElementCollection();
//inherited
CreateMessage(baseUrl: string, methodName: string, args: any[]): Message {
let message: SoapMessage = new SoapMessage(
baseUrl,
methodName,
this.#serviceNamespace,
this.#contract
);
message.requestArgs = args ?? [];
return message;
}
//inherited
CreateResponseMessage(result: any, classConstructor?: any): Message {
/* istanbul ignore else */
if (result.resultData) {
let data =
typeof result.resultData.d === 'undefined'
? result.resultData
: result.resultData.d;
let message: SoapMessage = result.resultData.message;
/* istanbul ignore else */
if (message) {
let jsonData: any = xml2json(data);
let namespaceVar = this.extractNs(jsonData);
/* istanbul ignore else */
if (namespaceVar) {
let envelope = jsonData[`${namespaceVar}:Envelope`];
/* istanbul ignore else */
if (envelope) {
return this.processEnvelopeBody(
message,
namespaceVar,
envelope[`${namespaceVar}:Body`],
classConstructor
);
}
}
}
}
return null;
}
/**
* Process the sopa body section of an evelop. As a result it returns a new {SoapMessage} object containing
* the results given in the body.
* Body Sample:
* <s:Body>
* <GetAllEmployeesResponse xmlns="http://myserver.com/MyService/2011/11">
* <GetAllEmployeesResult xmlns:a="http://myserver.com/MyService/2011/11" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
* <a:Employee>
* <a:Name>Olman</a:Name>
* ...
*
* @private
* @param {SoapMessage} message The {SoapMessage} body containing the server response.
* @param {*} body the actual Soap message body containing the result data
* @param {*} [classConstructor] Type of the elements to be loaded (Employee in above sample).
* @return {*} a {SoapMessage} containing the loaded response.
* @memberof HttpBasicBinding
*/
private processEnvelopeBody(
message: SoapMessage,
namespaceVar: string,
body: any,
classConstructor?: any
): SoapMessage {
/* istanbul ignore else */
if (body) {
let response = body[`${message.methodName}Response`];
/* istanbul ignore else */
if (response) {
let resultElement = response[`${message.methodName}Result`];
if (classConstructor) {
message.result = new ObservableCollection(
this.processElements(resultElement, classConstructor)
);
} else {
message.result = isNaN(resultElement)
? resultElement
: parseInt(resultElement);
}
} else {
throw new Exception(body[`${namespaceVar}:Fault`]['faultstring']['_']);
}
return message;
}
}
/**
* Creates a new object of the given class constructor and sets its properties to the values
* in data.
*
* @private
* @param {*} data the json value containing the object properties
* @param {*} classConstructor the constructor of the resulting object.
* @return {*} {*} a new object created using the given constructor
* @memberof HttpBasicBinding
*/
private processElements(
data: any,
classConstructor: any,
prefix?: string
): any[] {
let tempInstance = new classConstructor();
if (!prefix) {
let scheme = tempInstance.getScheme();
prefix = this.extractServiceNs(data, scheme);
}
data = data[`${prefix}:${tempInstance.getName()}`];
let result = [];
if (data instanceof Array) {
let elements: any[] = data;
elements.forEach((element) => {
let instance = new classConstructor();
result.push(instance);
this.fillElement(instance, element, prefix, classConstructor);
});
} else if (data) {
let instance = new classConstructor();
this.fillElement(instance, data, prefix, classConstructor);
result.push(instance);
}
return result;
}
/**
* Filles the given instance with all properties gien in element object.
*
* @private
* @param {*} instance the new object to fill
* @param {*} element the json object containing the properties to set in instance
* @param {string} prefix the namespace prefix
* @memberof HttpBasicBinding
*/
private fillElement(
instance: any,
element: any,
prefix: string,
classConstructor: any
) {
let prefixLen = prefix.length + 1; // plus ":"
let classInfo = ReflectionHelper.getTypeInfo(classConstructor);
for (const e in element) {
let name = e.substr(prefixLen);
instance[name] = this.extractValue(
prefix,
element[e],
classInfo.getProperty(name)
);
}
}
/**
* Extracts the response value for a given property. Value is extracted depending on the property
* datatype, current support datatypes are String, Number, Boolean, Date and ObservableCollection
*
* @private
* @param {string} prefix the namespace prefix of the custom data
* @param {*} value the value to be converted
* @param {PropertyInfo} property the property to be assigned
* @return {*} {*}
* @memberof HttpBasicBinding
*/
private extractValue(
prefix: string,
value: any,
property: PropertyInfo
): any {
/* istanbul ignore else */
if (this.isNull(value)) {
return null;
}
switch (property.propertyType.FullName) {
case 'String':
return this.convertStringValue(value);
case 'Number':
return this.convertNumberValue(value);
case 'Boolean':
return this.convertBooleanValue(value);
case 'Date':
return this.convertDateValue(value);
case 'ObservableCollection':
return this.convertCollectionValue(
prefix,
value,
property.collectionGenericType
);
}
return value;
}
/**
* Converts a list of elements to be set to a ObservableCollection object.
*
* @private
* @param {string} prefix the namespace prefix of the custom data
* @param {*} value the value to be converted
* @param {*} collectionElementType
* @return {*} {*}
* @memberof HttpBasicBinding
*/
private convertCollectionValue(
prefix: string,
value: any,
collectionElementType: any
): any {
/* istanbul ignore else */
if (collectionElementType) {
let collection = new ObservableCollection();
let newElement = this.processElements(
value,
collectionElementType,
prefix
);
collection.addRange(newElement);
return collection;
}
return value;
}
/**
* Converts the given value to a Date object
* @param value the value to be converted
* @returns a Date object
*/
private convertDateValue(value: any): Date {
return new Date(Date.parse(value));
}
/**
* Converts the given value to a boolean value
*
* @private
* @param {*} value the value to be converted
* @return {*} {boolean}
* @memberof HttpBasicBinding
*/
private convertBooleanValue(value: any): boolean {
return value === 'true';
}
/**
* Converts the given value to a number one
*
* @private
* @param {*} value The value to be converted
* @return {*} {Number}
* @memberof HttpBasicBinding
*/
private convertNumberValue(value: any): number {
return Number.parseFloat(value);
}
/**
* Converts the given value to a string one
*
* @private
* @param {*} value the value to be converted
* @return {*} {string}
* @memberof HttpBasicBinding
*/
private convertStringValue(value: any): string {
return value as string;
}
/**
* Checks if the given value matches the explicit null one.
*
* @private
* @param {*} value the value to test for
* @return {*} {boolean}
* @memberof HttpBasicBinding
*/
private isNull(value): boolean {
return value.$ && value['$']['i:nil'] === 'true';
}
/**
* Extracts the service namespace attribute. For the folowing service namespace it returns 'a':
* xmlns:a="http://myserver.com/MyService/2011/11"
*
* @private
* @param {*} data the json object representation of an xml
* @param {string} namespace the namespace to get the prefix for
* @return {string} a string with the prefix value for the given namespace
* @memberof HttpBasicBinding
*/
private extractServiceNs(data: any, namespace: string): string {
let sns = undefined;
let namespaces = data['$'];
/* istanbul ignore else */
if (namespaces) {
for (const e in namespaces) {
/* istanbul ignore else */
if (namespaces[e] === namespace) {
sns = e.substr(6);
break;
}
}
}
return sns;
}
/**
* Extracts the Envelope prefix, for the following definition it returns 's':
* xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
*
* @private
* @param {*} data the json representation of a soap xml
* @return {*} {string} a namespace prefix.
* @memberof HttpBasicBinding
*/
private extractNs(data: any): string {
let envelope: string = undefined;
let ns: string = undefined;
// extract main object
for (const element in data) {
envelope = element;
break;
}
// extract the "$" element containing the namespace defintion
/* istanbul ignore else */
if (envelope && data[envelope] && data[envelope]['$']) {
for (const e in data[envelope]['$']) {
ns = e.substr(6);
break;
}
}
return ns;
}
//inherited
CreateBindingElements(): BindingElementCollection {
return this.Elements;
}
}