diff --git a/sdk/core/core-client/review/core-client.api.md b/sdk/core/core-client/review/core-client.api.md
index 1681e51a5672..e647e4e5be33 100644
--- a/sdk/core/core-client/review/core-client.api.md
+++ b/sdk/core/core-client/review/core-client.api.md
@@ -17,30 +17,20 @@ import { TransferProgressEvent } from '@azure/core-https';
// @public (undocumented)
export interface BaseMapper {
- // (undocumented)
constraints?: MapperConstraints;
- // (undocumented)
defaultValue?: any;
- // (undocumented)
isConstant?: boolean;
- // (undocumented)
nullable?: boolean;
- // (undocumented)
readOnly?: boolean;
- // (undocumented)
required?: boolean;
- // (undocumented)
serializedName?: string;
- // (undocumented)
type: MapperType;
- // (undocumented)
xmlElementName?: string;
- // (undocumented)
xmlIsAttribute?: boolean;
- // (undocumented)
xmlIsWrapped?: boolean;
- // (undocumented)
xmlName?: string;
+ xmlNamespace?: string;
+ xmlNamespacePrefix?: string;
}
// @public (undocumented)
diff --git a/sdk/core/core-client/src/interfaces.ts b/sdk/core/core-client/src/interfaces.ts
index dd38df47b315..f2e29f0da31c 100644
--- a/sdk/core/core-client/src/interfaces.ts
+++ b/sdk/core/core-client/src/interfaces.ts
@@ -375,17 +375,61 @@ export interface EnumMapperType {
}
export interface BaseMapper {
+ /**
+ * Name for the xml element
+ */
xmlName?: string;
+ /**
+ * Xml element namespace
+ */
+ xmlNamespace?: string;
+ /**
+ * Xml element namespace prefix
+ */
+ xmlNamespacePrefix?: string;
+ /**
+ * Determines if the current property should be serialized as an attribute of the parent xml element
+ */
xmlIsAttribute?: boolean;
+ /**
+ * Name for the xml elements when serializing an array
+ */
xmlElementName?: string;
+ /**
+ * Whether or not the current propery should have a wrapping XML element
+ */
xmlIsWrapped?: boolean;
+ /**
+ * Whether or not the current propery is readonly
+ */
readOnly?: boolean;
+ /**
+ * Whether or not the current propery is a constant
+ */
isConstant?: boolean;
+ /**
+ * Whether or not the current propery is required
+ */
required?: boolean;
+ /**
+ * Whether or not the current propery allows mull as a value
+ */
nullable?: boolean;
+ /**
+ * The name to use when serializing
+ */
serializedName?: string;
+ /**
+ * Type of the mapper
+ */
type: MapperType;
+ /**
+ * Default value when one is not explicitly provided
+ */
defaultValue?: any;
+ /**
+ * Constraints to test the current value against
+ */
constraints?: MapperConstraints;
}
diff --git a/sdk/core/core-client/src/serializer.ts b/sdk/core/core-client/src/serializer.ts
index d63a83efe684..82cb24707674 100644
--- a/sdk/core/core-client/src/serializer.ts
+++ b/sdk/core/core-client/src/serializer.ts
@@ -153,11 +153,29 @@ class SerializerImpl implements Serializer {
} else if (mapperType.match(/^Base64Url$/i) !== null) {
payload = serializeBase64UrlType(objectName, object);
} else if (mapperType.match(/^Sequence$/i) !== null) {
- payload = serializeSequenceType(this, mapper as SequenceMapper, object, objectName);
+ payload = serializeSequenceType(
+ this,
+ mapper as SequenceMapper,
+ object,
+ objectName,
+ Boolean(this.isXML)
+ );
} else if (mapperType.match(/^Dictionary$/i) !== null) {
- payload = serializeDictionaryType(this, mapper as DictionaryMapper, object, objectName);
+ payload = serializeDictionaryType(
+ this,
+ mapper as DictionaryMapper,
+ object,
+ objectName,
+ Boolean(this.isXML)
+ );
} else if (mapperType.match(/^Composite$/i) !== null) {
- payload = serializeCompositeType(this, mapper as CompositeMapper, object, objectName);
+ payload = serializeCompositeType(
+ this,
+ mapper as CompositeMapper,
+ object,
+ objectName,
+ Boolean(this.isXML)
+ );
}
}
return payload;
@@ -481,7 +499,8 @@ function serializeSequenceType(
serializer: Serializer,
mapper: SequenceMapper,
object: any,
- objectName: string
+ objectName: string,
+ isXml: boolean
): any {
if (!Array.isArray(object)) {
throw new Error(`${objectName} must be of type Array.`);
@@ -495,7 +514,19 @@ function serializeSequenceType(
}
const tempArray = [];
for (let i = 0; i < object.length; i++) {
- tempArray[i] = serializer.serialize(elementType, object[i], objectName);
+ const serializedValue = serializer.serialize(elementType, object[i], objectName);
+ if (isXml && elementType.xmlNamespace) {
+ const xmlnsKey = elementType.xmlNamespacePrefix
+ ? `xmlns:${elementType.xmlNamespacePrefix}`
+ : "xmlns";
+ if (elementType.type.name === "Composite") {
+ tempArray[i] = { ...serializedValue, $: { [xmlnsKey]: elementType.xmlNamespace } };
+ } else {
+ tempArray[i] = { _: serializedValue, $: { [xmlnsKey]: elementType.xmlNamespace } };
+ }
+ } else {
+ tempArray[i] = serializedValue;
+ }
}
return tempArray;
}
@@ -504,7 +535,8 @@ function serializeDictionaryType(
serializer: Serializer,
mapper: DictionaryMapper,
object: any,
- objectName: string
+ objectName: string,
+ isXml: boolean
): any {
if (typeof object !== "object") {
throw new Error(`${objectName} must be of type object.`);
@@ -518,8 +550,18 @@ function serializeDictionaryType(
}
const tempDictionary: { [key: string]: any } = {};
for (const key of Object.keys(object)) {
- tempDictionary[key] = serializer.serialize(valueType, object[key], objectName + "." + key);
+ const serializedValue = serializer.serialize(valueType, object[key], objectName);
+ // If the element needs an XML namespace we need to add it within the $ property
+ tempDictionary[key] = getXmlObjectValue(valueType, serializedValue, isXml);
}
+
+ // Add the namespace to the root element if needed
+ if (isXml && mapper.xmlNamespace) {
+ const xmlnsKey = mapper.xmlNamespacePrefix ? `xmlns:${mapper.xmlNamespacePrefix}` : "xmlns";
+
+ return { ...tempDictionary, $: { [xmlnsKey]: mapper.xmlNamespace } };
+ }
+
return tempDictionary;
}
@@ -568,7 +610,8 @@ function serializeCompositeType(
serializer: Serializer,
mapper: CompositeMapper,
object: any,
- objectName: string
+ objectName: string,
+ isXml: boolean
): any {
if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
mapper = getPolymorphicMapper(serializer, mapper, object, "clientName");
@@ -609,6 +652,12 @@ function serializeCompositeType(
}
if (parentObject !== undefined && parentObject !== null) {
+ if (isXml && mapper.xmlNamespace) {
+ const xmlnsKey = mapper.xmlNamespacePrefix
+ ? `xmlns:${mapper.xmlNamespacePrefix}`
+ : "xmlns";
+ parentObject.$ = { ...parentObject.$, [xmlnsKey]: mapper.xmlNamespace };
+ }
const propertyObjectName =
propertyMapper.serializedName !== ""
? objectName + "." + propertyMapper.serializedName
@@ -630,16 +679,17 @@ function serializeCompositeType(
propertyObjectName
);
if (serializedValue !== undefined && propName !== undefined && propName !== null) {
- if (propertyMapper.xmlIsAttribute) {
+ const value = getXmlObjectValue(propertyMapper, serializedValue, isXml);
+ if (isXml && propertyMapper.xmlIsAttribute) {
// $ is the key attributes are kept under in xml2js.
// This keeps things simple while preventing name collision
// with names in user documents.
parentObject.$ = parentObject.$ || {};
parentObject.$[propName] = serializedValue;
- } else if (propertyMapper.xmlIsWrapped) {
- parentObject[propName] = { [propertyMapper.xmlElementName!]: serializedValue };
+ } else if (isXml && propertyMapper.xmlIsWrapped) {
+ parentObject[propName] = { [propertyMapper.xmlElementName!]: value };
} else {
- parentObject[propName] = serializedValue;
+ parentObject[propName] = value;
}
}
}
@@ -665,6 +715,22 @@ function serializeCompositeType(
return object;
}
+function getXmlObjectValue(propertyMapper: Mapper, serializedValue: any, isXml: boolean) {
+ if (!isXml || !propertyMapper.xmlNamespace) {
+ return serializedValue;
+ }
+
+ const xmlnsKey = propertyMapper.xmlNamespacePrefix
+ ? `xmlns:${propertyMapper.xmlNamespacePrefix}`
+ : "xmlns";
+ const xmlNamespace = { [xmlnsKey]: propertyMapper.xmlNamespace };
+
+ if (["Composite"].includes(propertyMapper.type.name)) {
+ return { $: xmlNamespace, ...serializedValue };
+ }
+ return { _: serializedValue, $: xmlNamespace };
+}
+
function isSpecialXmlProperty(propertyName: string): boolean {
return ["$", "_"].includes(propertyName);
}
diff --git a/sdk/core/core-client/src/serviceClient.ts b/sdk/core/core-client/src/serviceClient.ts
index a8d761d767e7..fba4f29eed04 100644
--- a/sdk/core/core-client/src/serviceClient.ts
+++ b/sdk/core/core-client/src/serviceClient.ts
@@ -250,7 +250,14 @@ export function serializeRequestBody(
);
const bodyMapper = operationSpec.requestBody.mapper;
- const { required, serializedName, xmlName, xmlElementName } = bodyMapper;
+ const {
+ required,
+ serializedName,
+ xmlName,
+ xmlElementName,
+ xmlNamespace,
+ xmlNamespacePrefix
+ } = bodyMapper;
const typeName = bodyMapper.type.name;
try {
@@ -267,13 +274,21 @@ export function serializeRequestBody(
const isStream = typeName === MapperTypeNames.Stream;
if (operationSpec.isXML) {
+ const xmlnsKey = xmlNamespacePrefix ? `xmlns:${xmlNamespacePrefix}` : "xmlns";
+ const value = getXmlValueWithNamespace(xmlNamespace, xmlnsKey, typeName, request.body);
+
if (typeName === MapperTypeNames.Sequence) {
request.body = stringifyXML(
- prepareXMLRootList(request.body, xmlElementName || xmlName || serializedName!),
+ prepareXMLRootList(
+ value,
+ xmlElementName || xmlName || serializedName!,
+ xmlnsKey,
+ xmlNamespace
+ ),
{ rootName: xmlName || serializedName }
);
} else if (!isStream) {
- request.body = stringifyXML(request.body, {
+ request.body = stringifyXML(value, {
rootName: xmlName || serializedName
});
}
@@ -317,6 +332,24 @@ export function serializeRequestBody(
}
}
+/**
+ * Adds an xml namespace to the xml serialized object if needed, otherwise it just returns the value itself
+ */
+function getXmlValueWithNamespace(
+ xmlNamespace: string | undefined,
+ xmlnsKey: string,
+ typeName: string,
+ serializedValue: any
+): any {
+ // Composite and Sequence schemas already got their root namespace set during serialization
+ // We just need to add xmlns to the other schema types
+ if (xmlNamespace && !["Composite", "Sequence", "Dictionary"].includes(typeName)) {
+ return { _: serializedValue, $: { [xmlnsKey]: xmlNamespace } };
+ }
+
+ return serializedValue;
+}
+
function createDefaultPipeline(
options: { baseUri?: string; credential?: TokenCredential } = {}
): Pipeline {
@@ -338,11 +371,20 @@ function createDefaultPipeline(
return pipeline;
}
-function prepareXMLRootList(obj: any, elementName: string): { [key: string]: any[] } {
+function prepareXMLRootList(
+ obj: any,
+ elementName: string,
+ xmlNamespaceKey?: string,
+ xmlNamespace?: string
+): { [key: string]: any[] } {
if (!Array.isArray(obj)) {
obj = [obj];
}
- return { [elementName]: obj };
+ if (!xmlNamespaceKey || !xmlNamespace) {
+ return { [elementName]: obj };
+ }
+
+ return { [elementName]: obj, $: { [xmlNamespaceKey]: xmlNamespace } };
}
function flattenResponse(
diff --git a/sdk/core/core-client/test/serviceClient.spec.ts b/sdk/core/core-client/test/serviceClient.spec.ts
index 5eb10b91bfd7..e7c9984aafc1 100644
--- a/sdk/core/core-client/test/serviceClient.spec.ts
+++ b/sdk/core/core-client/test/serviceClient.spec.ts
@@ -25,6 +25,7 @@ import { stringifyXML } from "@azure/core-xml";
import { serializeRequestBody } from "../src/serviceClient";
import { getOperationArgumentValueFromParameter } from "../src/operationHelpers";
import { deserializationPolicy } from "../src/deserializationPolicy";
+import { Mappers } from "./testMappers";
describe("ServiceClient", function() {
it("should serialize headerCollectionPrefix", async function() {
@@ -189,7 +190,7 @@ describe("ServiceClient", function() {
200: {
bodyMapper: {
type: {
- name: "Sequence",
+ name: MapperTypeNames.Sequence,
element: {
type: {
name: "Number"
@@ -233,6 +234,34 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, `"body value"`);
});
+ it("should serialize a JSON String request body with namespace, ignoring namespace", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "https://example.com",
+ xmlNamespacePrefix: "foo",
+ serializedName: "bodyArg",
+ type: {
+ name: "String"
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer()
+ }
+ );
+ assert.strictEqual(httpRequest.body, `"body value"`);
+ });
+
it("should serialize a JSON ByteArray request body", () => {
const httpRequest = createPipelineRequest({ url: "https://example.com" });
serializeRequestBody(
@@ -259,6 +288,34 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, `"SmF2YXNjcmlwdA=="`);
});
+ it("should serialize a JSON ByteArray request body, ignoring xml properties", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: stringToByteArray("Javascript")
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "https://microsoft.com",
+ xmlNamespacePrefix: "test",
+ serializedName: "bodyArg",
+ type: {
+ name: MapperTypeNames.ByteArray
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer()
+ }
+ );
+ assert.strictEqual(httpRequest.body, `"SmF2YXNjcmlwdA=="`);
+ });
+
it("should serialize a JSON Stream request body", () => {
const httpRequest = createPipelineRequest({ url: "https://example.com" });
serializeRequestBody(
@@ -286,6 +343,35 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, "body value");
});
+ it("should serialize a JSON Stream request body", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "http://microsoft.com",
+ xmlNamespacePrefix: "test",
+ serializedName: "bodyArg",
+ type: {
+ name: MapperTypeNames.Stream
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer()
+ },
+ stringifyXML
+ );
+ assert.strictEqual(httpRequest.body, "body value");
+ });
+
it("should serialize an XML String request body", () => {
const httpRequest = createPipelineRequest({ url: "https://example.com" });
serializeRequestBody(
@@ -317,6 +403,38 @@ describe("ServiceClient", function() {
);
});
+ it("should serialize an XML String request body, with namespace", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ type: {
+ name: MapperTypeNames.String
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `body value`
+ );
+ });
+
it("should serialize an XML ByteArray request body", () => {
const httpRequest = createPipelineRequest({ url: "https://example.com" });
serializeRequestBody(
@@ -337,7 +455,7 @@ describe("ServiceClient", function() {
}
},
responses: { 200: {} },
- serializer: createSerializer(),
+ serializer: createSerializer(undefined, true /** isXML */),
isXML: true
},
stringifyXML
@@ -368,7 +486,7 @@ describe("ServiceClient", function() {
}
},
responses: { 200: {} },
- serializer: createSerializer(),
+ serializer: createSerializer(undefined, true /** isXML */),
isXML: true
},
stringifyXML
@@ -376,6 +494,420 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, "body value");
});
+ it("should serialize an XML Stream request body, with namespace", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "https://microsoft.com",
+ serializedName: "bodyArg",
+ type: {
+ name: MapperTypeNames.Stream
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(httpRequest.body, "body value");
+ });
+
+ it("should serialize an XML ByteArray request body with namespace and prefix", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: stringToByteArray("Javascript")
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ xmlNamespace: "https://microsoft.com",
+ xmlNamespacePrefix: "sample",
+ required: true,
+ serializedName: "bodyArg",
+ type: {
+ name: MapperTypeNames.ByteArray
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `SmF2YXNjcmlwdA==`
+ );
+ });
+
+ it("should serialize an XML Composite request body", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ requestBody: {
+ updated: new Date("2020-08-12T23:36:18.308Z"),
+ content: { type: "application/xml", queueDescription: { maxDeliveryCount: 15 } }
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: Mappers.requestBody1,
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `2020-08-12T23:36:18.308Z15`
+ );
+ });
+
+ it("should serialize a JSON Composite request body, ignoring XML metadata", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ requestBody: {
+ updated: new Date("2020-08-12T23:36:18.308Z"),
+ content: { type: "application/xml", queueDescription: { maxDeliveryCount: 15 } }
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: Mappers.requestBody1,
+ responses: { 200: {} },
+ serializer: createSerializer()
+ }
+ );
+
+ assert.deepEqual(
+ httpRequest.body,
+ '{"updated":"2020-08-12T23:36:18.308Z","content":{"type":"application/xml","queueDescription":{"maxDeliveryCount":15}}}'
+ );
+ });
+
+ it("should serialize an XML Array request body with namespace and prefix", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: ["Foo", "Bar"]
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ xmlElementName: "testItem",
+ type: {
+ name: MapperTypeNames.Sequence,
+ element: {
+ xmlNamespace: "https://microsoft.com/element",
+ type: { name: "String" }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `FooBar`
+ );
+ });
+
+ it("should serialize a JSON Array request body, ignoring XML metadata", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: ["Foo", "Bar"]
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ xmlElementName: "testItem",
+ type: {
+ name: MapperTypeNames.Sequence,
+ element: {
+ xmlNamespace: "https://microsoft.com/element",
+ type: { name: "String" }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer()
+ }
+ );
+ assert.deepEqual(httpRequest.body, JSON.stringify(["Foo", "Bar"]));
+ });
+
+ it("should serialize an XML Array of composite elements, namespace and prefix", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: [
+ { foo: "Foo1", bar: "Bar1" },
+ { foo: "Foo2", bar: "Bar2" },
+ { foo: "Foo3", bar: "Bar3" }
+ ]
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ xmlElementName: "testItem",
+ type: {
+ name: MapperTypeNames.Sequence,
+ element: {
+ xmlNamespace: "https://microsoft.com/element",
+ type: {
+ name: "Composite",
+ modelProperties: {
+ foo: {
+ serializedName: "foo",
+ xmlNamespace: "https://microsoft.com/foo",
+ xmlName: "Foo",
+ type: {
+ name: "String"
+ }
+ },
+ bar: {
+ xmlNamespacePrefix: "bar",
+ xmlNamespace: "https://microsoft.com/bar",
+ xmlName: "Bar",
+ serializedName: "bar",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `Foo1Bar1Foo2Bar2Foo3Bar3`
+ );
+ });
+
+ it("should serialize an XML Composite request body with namespace and prefix", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ bodyArg: { foo: "Foo", bar: "Bar" }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ type: {
+ name: MapperTypeNames.Composite,
+ modelProperties: {
+ foo: {
+ serializedName: "foo",
+ xmlNamespace: "https://microsoft.com/foo",
+ xmlName: "Foo",
+ type: {
+ name: "String"
+ }
+ },
+ bar: {
+ xmlNamespacePrefix: "bar",
+ xmlNamespace: "https://microsoft.com/bar",
+ xmlName: "Bar",
+ serializedName: "bar",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `FooBar`
+ );
+ });
+
+ it("should serialize an XML Dictionary request body", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ metadata: {
+ alpha: "hello",
+ beta: "world"
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "metadata",
+ mapper: {
+ serializedName: "metadata",
+ type: {
+ name: "Dictionary",
+ value: {
+ type: {
+ name: "String"
+ }
+ }
+ },
+ headerCollectionPrefix: "foo-bar-"
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `helloworld`
+ );
+ });
+
+ it("should serialize an XML Dictionary request body, with namespace and prefix", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ metadata: {
+ alpha: "hello",
+ beta: "world"
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "metadata",
+ mapper: {
+ xmlNamespacePrefix: "sample",
+ xmlNamespace: "https://microsoft.com",
+ serializedName: "metadata",
+ type: {
+ name: "Dictionary",
+ value: {
+ xmlNamespacePrefix: "el",
+ xmlNamespace: "https://microsoft.com/element",
+ type: {
+ name: "String"
+ }
+ }
+ },
+ headerCollectionPrefix: "foo-bar-"
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer(undefined, true /** isXML */),
+ isXML: true
+ },
+ stringifyXML
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `helloworld`
+ );
+ });
+
+ it("should serialize a JSON Dictionary request body, ignoring xml metadata", () => {
+ const httpRequest = createPipelineRequest({ url: "https://example.com" });
+ serializeRequestBody(
+ httpRequest,
+ {
+ metadata: {
+ alpha: "hello",
+ beta: "world"
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "metadata",
+ mapper: {
+ xmlNamespacePrefix: "sample",
+ xmlNamespace: "https://microsoft.com",
+ serializedName: "metadata",
+ type: {
+ name: "Dictionary",
+ value: {
+ xmlNamespacePrefix: "el",
+ xmlNamespace: "https://microsoft.com/element",
+ type: {
+ name: "String"
+ }
+ }
+ },
+ headerCollectionPrefix: "foo-bar-"
+ }
+ },
+ responses: { 200: {} },
+ serializer: createSerializer()
+ },
+ stringifyXML
+ );
+ assert.deepEqual(httpRequest.body, `{"alpha":"hello","beta":"world"}`);
+ });
+
it("should serialize a string send to a text/plain endpoint as just a string", () => {
const httpRequest = createPipelineRequest({ url: "https://example.com" });
serializeRequestBody(
diff --git a/sdk/core/core-client/test/testMappers.ts b/sdk/core/core-client/test/testMappers.ts
index 1db4895d63a9..88022ffa533e 100644
--- a/sdk/core/core-client/test/testMappers.ts
+++ b/sdk/core/core-client/test/testMappers.ts
@@ -1,5 +1,268 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
+
+import { CompositeMapper } from "../src/interfaces";
+
+const QueueDescription: CompositeMapper = {
+ serializedName: "QueueDescription",
+ xmlName: "QueueDescription",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Composite",
+ className: "QueueDescription",
+ modelProperties: {
+ lockDuration: {
+ serializedName: "lockDuration",
+ xmlName: "LockDuration",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ maxSizeInMegabytes: {
+ serializedName: "maxSizeInMegabytes",
+ xmlName: "MaxSizeInMegabytes",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ requiresDuplicateDetection: {
+ serializedName: "requiresDuplicateDetection",
+ xmlName: "RequiresDuplicateDetection",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ requiresSession: {
+ serializedName: "requiresSession",
+ xmlName: "RequiresSession",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ defaultMessageTimeToLive: {
+ serializedName: "defaultMessageTimeToLive",
+ xmlName: "DefaultMessageTimeToLive",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ deadLetteringOnMessageExpiration: {
+ serializedName: "deadLetteringOnMessageExpiration",
+ xmlName: "DeadLetteringOnMessageExpiration",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ duplicateDetectionHistoryTimeWindow: {
+ serializedName: "duplicateDetectionHistoryTimeWindow",
+ xmlName: "DuplicateDetectionHistoryTimeWindow",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ maxDeliveryCount: {
+ serializedName: "maxDeliveryCount",
+ xmlName: "MaxDeliveryCount",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ enableBatchedOperations: {
+ serializedName: "enableBatchedOperations",
+ xmlName: "EnableBatchedOperations",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ sizeInBytes: {
+ serializedName: "sizeInBytes",
+ xmlName: "SizeInBytes",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ messageCount: {
+ serializedName: "messageCount",
+ xmlName: "MessageCount",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ isAnonymousAccessible: {
+ serializedName: "isAnonymousAccessible",
+ xmlName: "IsAnonymousAccessible",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ status: {
+ serializedName: "status",
+ xmlName: "Status",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ forwardTo: {
+ serializedName: "forwardTo",
+ xmlName: "ForwardTo",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ userMetadata: {
+ serializedName: "userMetadata",
+ xmlName: "UserMetadata",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ createdAt: {
+ serializedName: "createdAt",
+ xmlName: "CreatedAt",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "DateTime"
+ }
+ },
+ updatedAt: {
+ serializedName: "updatedAt",
+ xmlName: "UpdatedAt",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "DateTime"
+ }
+ },
+ accessedAt: {
+ serializedName: "accessedAt",
+ xmlName: "AccessedAt",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "DateTime"
+ }
+ },
+ supportOrdering: {
+ serializedName: "supportOrdering",
+ xmlName: "SupportOrdering",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ autoDeleteOnIdle: {
+ serializedName: "autoDeleteOnIdle",
+ xmlName: "AutoDeleteOnIdle",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ enablePartitioning: {
+ serializedName: "enablePartitioning",
+ xmlName: "EnablePartitioning",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ entityAvailabilityStatus: {
+ serializedName: "entityAvailabilityStatus",
+ xmlName: "EntityAvailabilityStatus",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ enableExpress: {
+ serializedName: "enableExpress",
+ xmlName: "EnableExpress",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ forwardDeadLetteredMessagesTo: {
+ serializedName: "forwardDeadLetteredMessagesTo",
+ xmlName: "ForwardDeadLetteredMessagesTo",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+
+const CreateQueueBodyContent: CompositeMapper = {
+ serializedName: "CreateQueueBodyContent",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ name: "Composite",
+ className: "CreateQueueBodyContent",
+ modelProperties: {
+ type: {
+ defaultValue: "application/xml",
+ serializedName: "type",
+ xmlName: "type",
+ xmlIsAttribute: true,
+ type: {
+ name: "String"
+ }
+ },
+ queueDescription: {
+ serializedName: "queueDescription",
+ xmlName: "QueueDescription",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ ...QueueDescription.type
+ }
+ }
+ }
+ }
+};
+
+const CreateQueueBody: CompositeMapper = {
+ serializedName: "CreateQueueBody",
+ xmlName: "entry",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ name: "Composite",
+ className: "CreateQueueBody",
+ modelProperties: {
+ updated: {
+ serializedName: "updated",
+ xmlName: "updated",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ name: "DateTime"
+ }
+ },
+ content: {
+ serializedName: "content",
+ xmlName: "content",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ ...CreateQueueBodyContent.type
+ }
+ }
+ }
+ }
+};
+
const internalMappers: any = {};
internalMappers.SimpleProduct = {
@@ -750,4 +1013,9 @@ internalMappers.discriminators = {
"Pet.Dog": internalMappers.Dog
};
+internalMappers.requestBody1 = {
+ parameterPath: "requestBody",
+ mapper: CreateQueueBody
+};
+
export const Mappers = internalMappers;
diff --git a/sdk/core/core-http/review/core-http.api.md b/sdk/core/core-http/review/core-http.api.md
index ec6cd89c7816..0586887a7575 100644
--- a/sdk/core/core-http/review/core-http.api.md
+++ b/sdk/core/core-http/review/core-http.api.md
@@ -54,30 +54,20 @@ export type Authenticator = (challenge: object) => Promise;
// @public (undocumented)
export interface BaseMapper {
- // (undocumented)
constraints?: MapperConstraints;
- // (undocumented)
defaultValue?: any;
- // (undocumented)
isConstant?: boolean;
- // (undocumented)
nullable?: boolean;
- // (undocumented)
readOnly?: boolean;
- // (undocumented)
required?: boolean;
- // (undocumented)
serializedName?: string;
- // (undocumented)
type: MapperType;
- // (undocumented)
xmlElementName?: string;
- // (undocumented)
xmlIsAttribute?: boolean;
- // (undocumented)
xmlIsWrapped?: boolean;
- // (undocumented)
xmlName?: string;
+ xmlNamespace?: string;
+ xmlNamespacePrefix?: string;
}
// @public (undocumented)
diff --git a/sdk/core/core-http/src/serializer.ts b/sdk/core/core-http/src/serializer.ts
index 1b32f489f496..685f4d9f076d 100644
--- a/sdk/core/core-http/src/serializer.ts
+++ b/sdk/core/core-http/src/serializer.ts
@@ -144,11 +144,29 @@ export class Serializer {
} else if (mapperType.match(/^Base64Url$/i) !== null) {
payload = serializeBase64UrlType(objectName, object);
} else if (mapperType.match(/^Sequence$/i) !== null) {
- payload = serializeSequenceType(this, mapper as SequenceMapper, object, objectName);
+ payload = serializeSequenceType(
+ this,
+ mapper as SequenceMapper,
+ object,
+ objectName,
+ Boolean(this.isXML)
+ );
} else if (mapperType.match(/^Dictionary$/i) !== null) {
- payload = serializeDictionaryType(this, mapper as DictionaryMapper, object, objectName);
+ payload = serializeDictionaryType(
+ this,
+ mapper as DictionaryMapper,
+ object,
+ objectName,
+ Boolean(this.isXML)
+ );
} else if (mapperType.match(/^Composite$/i) !== null) {
- payload = serializeCompositeType(this, mapper as CompositeMapper, object, objectName);
+ payload = serializeCompositeType(
+ this,
+ mapper as CompositeMapper,
+ object,
+ objectName,
+ Boolean(this.isXML)
+ );
}
}
return payload;
@@ -352,6 +370,7 @@ function serializeBasicTypes(typeName: string, objectName: string, value: any):
}
}
}
+
return value;
}
@@ -462,7 +481,8 @@ function serializeSequenceType(
serializer: Serializer,
mapper: SequenceMapper,
object: any,
- objectName: string
+ objectName: string,
+ isXml: boolean
): any[] {
if (!Array.isArray(object)) {
throw new Error(`${objectName} must be of type Array.`);
@@ -476,7 +496,20 @@ function serializeSequenceType(
}
const tempArray = [];
for (let i = 0; i < object.length; i++) {
- tempArray[i] = serializer.serialize(elementType, object[i], objectName);
+ const serializedValue = serializer.serialize(elementType, object[i], objectName);
+
+ if (isXml && elementType.xmlNamespace) {
+ const xmlnsKey = elementType.xmlNamespacePrefix
+ ? `xmlns:${elementType.xmlNamespacePrefix}`
+ : "xmlns";
+ if (elementType.type.name === "Composite") {
+ tempArray[i] = { ...serializedValue, $: { [xmlnsKey]: elementType.xmlNamespace } };
+ } else {
+ tempArray[i] = { _: serializedValue, $: { [xmlnsKey]: elementType.xmlNamespace } };
+ }
+ } else {
+ tempArray[i] = serializedValue;
+ }
}
return tempArray;
}
@@ -485,7 +518,8 @@ function serializeDictionaryType(
serializer: Serializer,
mapper: DictionaryMapper,
object: any,
- objectName: string
+ objectName: string,
+ isXml: boolean
): { [key: string]: any } {
if (typeof object !== "object") {
throw new Error(`${objectName} must be of type object.`);
@@ -499,8 +533,18 @@ function serializeDictionaryType(
}
const tempDictionary: { [key: string]: any } = {};
for (const key of Object.keys(object)) {
- tempDictionary[key] = serializer.serialize(valueType, object[key], objectName + "." + key);
+ const serializedValue = serializer.serialize(valueType, object[key], objectName);
+ // If the element needs an XML namespace we need to add it within the $ property
+ tempDictionary[key] = getXmlObjectValue(valueType, serializedValue, isXml);
}
+
+ // Add the namespace to the root element if needed
+ if (isXml && mapper.xmlNamespace) {
+ const xmlnsKey = mapper.xmlNamespacePrefix ? `xmlns:${mapper.xmlNamespacePrefix}` : "xmlns";
+
+ return { ...tempDictionary, $: { [xmlnsKey]: mapper.xmlNamespace } };
+ }
+
return tempDictionary;
}
@@ -549,7 +593,8 @@ function serializeCompositeType(
serializer: Serializer,
mapper: CompositeMapper,
object: any,
- objectName: string
+ objectName: string,
+ isXml: boolean
): any {
if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
mapper = getPolymorphicMapper(serializer, mapper, object, "clientName");
@@ -589,6 +634,12 @@ function serializeCompositeType(
}
if (parentObject != undefined) {
+ if (isXml && mapper.xmlNamespace) {
+ const xmlnsKey = mapper.xmlNamespacePrefix
+ ? `xmlns:${mapper.xmlNamespacePrefix}`
+ : "xmlns";
+ parentObject.$ = { ...parentObject.$, [xmlnsKey]: mapper.xmlNamespace };
+ }
const propertyObjectName =
propertyMapper.serializedName !== ""
? objectName + "." + propertyMapper.serializedName
@@ -609,17 +660,19 @@ function serializeCompositeType(
toSerialize,
propertyObjectName
);
+
if (serializedValue !== undefined && propName != undefined) {
- if (propertyMapper.xmlIsAttribute) {
+ const value = getXmlObjectValue(propertyMapper, serializedValue, isXml);
+ if (isXml && propertyMapper.xmlIsAttribute) {
// $ is the key attributes are kept under in xml2js.
// This keeps things simple while preventing name collision
// with names in user documents.
parentObject.$ = parentObject.$ || {};
parentObject.$[propName] = serializedValue;
- } else if (propertyMapper.xmlIsWrapped) {
- parentObject[propName] = { [propertyMapper.xmlElementName!]: serializedValue };
+ } else if (isXml && propertyMapper.xmlIsWrapped) {
+ parentObject[propName] = { [propertyMapper.xmlElementName!]: value };
} else {
- parentObject[propName] = serializedValue;
+ parentObject[propName] = value;
}
}
}
@@ -645,6 +698,22 @@ function serializeCompositeType(
return object;
}
+function getXmlObjectValue(propertyMapper: Mapper, serializedValue: any, isXml: boolean) {
+ if (!isXml || !propertyMapper.xmlNamespace) {
+ return serializedValue;
+ }
+
+ const xmlnsKey = propertyMapper.xmlNamespacePrefix
+ ? `xmlns:${propertyMapper.xmlNamespacePrefix}`
+ : "xmlns";
+ const xmlNamespace = { [xmlnsKey]: propertyMapper.xmlNamespace };
+
+ if (["Composite"].includes(propertyMapper.type.name)) {
+ return { $: xmlNamespace, ...serializedValue };
+ }
+ return { _: serializedValue, $: xmlNamespace };
+}
+
function isSpecialXmlProperty(propertyName: string): boolean {
return ["$", "_"].includes(propertyName);
}
@@ -960,17 +1029,61 @@ export interface EnumMapperType {
}
export interface BaseMapper {
+ /**
+ * Name for the xml element
+ */
xmlName?: string;
+ /**
+ * Xml element namespace
+ */
+ xmlNamespace?: string;
+ /**
+ * Xml element namespace prefix
+ */
+ xmlNamespacePrefix?: string;
+ /**
+ * Determines if the current property should be serialized as an attribute of the parent xml element
+ */
xmlIsAttribute?: boolean;
+ /**
+ * Name for the xml elements when serializing an array
+ */
xmlElementName?: string;
+ /**
+ * Whether or not the current propery should have a wrapping XML element
+ */
xmlIsWrapped?: boolean;
+ /**
+ * Whether or not the current propery is readonly
+ */
readOnly?: boolean;
+ /**
+ * Whether or not the current propery is a constant
+ */
isConstant?: boolean;
+ /**
+ * Whether or not the current propery is required
+ */
required?: boolean;
+ /**
+ * Whether or not the current propery allows mull as a value
+ */
nullable?: boolean;
+ /**
+ * The name to use when serializing
+ */
serializedName?: string;
+ /**
+ * Type of the mapper
+ */
type: MapperType;
+ /**
+ * Default value when one is not explicitly provided
+ */
defaultValue?: any;
+ /**
+ * Constraints to test the current value against
+ */
constraints?: MapperConstraints;
}
diff --git a/sdk/core/core-http/src/serviceClient.ts b/sdk/core/core-http/src/serviceClient.ts
index 1bed817c86d4..4f67810a9f6f 100644
--- a/sdk/core/core-http/src/serviceClient.ts
+++ b/sdk/core/core-http/src/serviceClient.ts
@@ -538,7 +538,14 @@ export function serializeRequestBody(
);
const bodyMapper = operationSpec.requestBody.mapper;
- const { required, xmlName, xmlElementName, serializedName } = bodyMapper;
+ const {
+ required,
+ xmlName,
+ xmlElementName,
+ serializedName,
+ xmlNamespace,
+ xmlNamespacePrefix
+ } = bodyMapper;
const typeName = bodyMapper.type.name;
try {
@@ -555,16 +562,25 @@ export function serializeRequestBody(
const isStream = typeName === MapperType.Stream;
if (operationSpec.isXML) {
+ const xmlnsKey = xmlNamespacePrefix ? `xmlns:${xmlNamespacePrefix}` : "xmlns";
+ const value = getXmlValueWithNamespace(
+ xmlNamespace,
+ xmlnsKey,
+ typeName,
+ httpRequest.body
+ );
if (typeName === MapperType.Sequence) {
httpRequest.body = stringifyXML(
utils.prepareXMLRootList(
- httpRequest.body,
- xmlElementName || xmlName || serializedName!
+ value,
+ xmlElementName || xmlName || serializedName!,
+ xmlnsKey,
+ xmlNamespace
),
{ rootName: xmlName || serializedName }
);
} else if (!isStream) {
- httpRequest.body = stringifyXML(httpRequest.body, {
+ httpRequest.body = stringifyXML(value, {
rootName: xmlName || serializedName
});
}
@@ -610,6 +626,24 @@ export function serializeRequestBody(
}
}
+/**
+ * Adds an xml namespace to the xml serialized object if needed, otherwise it just returns the value itself
+ */
+function getXmlValueWithNamespace(
+ xmlNamespace: string | undefined,
+ xmlnsKey: string,
+ typeName: string,
+ serializedValue: any
+): any {
+ // Composite and Sequence schemas already got their root namespace set during serialization
+ // We just need to add xmlns to the other schema types
+ if (xmlNamespace && !["Composite", "Sequence", "Dictionary"].includes(typeName)) {
+ return { _: serializedValue, $: { [xmlnsKey]: xmlNamespace } };
+ }
+
+ return serializedValue;
+}
+
function getValueOrFunctionResult(
value: undefined | string | ((defaultValue: string) => string),
defaultValueCreator: () => string
diff --git a/sdk/core/core-http/src/util/utils.ts b/sdk/core/core-http/src/util/utils.ts
index 8c116895286d..10cdc1a92363 100644
--- a/sdk/core/core-http/src/util/utils.ts
+++ b/sdk/core/core-http/src/util/utils.ts
@@ -189,11 +189,21 @@ export function promiseToServiceCallback(promise: Promise {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "https://example.com",
+ xmlNamespacePrefix: "foo",
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.String
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer()
+ }
+ );
+ assert.strictEqual(httpRequest.body, `"body value"`);
+ });
+
it("should serialize a JSON ByteArray request body", () => {
const httpRequest = new WebResource();
serializeRequestBody(
@@ -509,6 +539,33 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, `"SmF2YXNjcmlwdA=="`);
});
+ it("should serialize a JSON ByteArray request body with namespace, ignoring xml properties", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: stringToByteArray("Javascript")
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.ByteArray
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, false /** isXML */)
+ }
+ );
+ assert.strictEqual(httpRequest.body, `"SmF2YXNjcmlwdA=="`);
+ });
+
it("should serialize a JSON Stream request body", () => {
const httpRequest = new WebResource();
serializeRequestBody(
@@ -536,6 +593,34 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, "body value");
});
+ it("should serialize a JSON Stream request body, ignore namespace", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "http://microsoft.com",
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.Stream
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer()
+ }
+ );
+ assert.strictEqual(httpRequest.body, "body value");
+ });
+
it("should serialize an XML String request body", () => {
const httpRequest = new WebResource();
serializeRequestBody(
@@ -567,6 +652,38 @@ describe("ServiceClient", function() {
);
});
+ it("should serialize an XML String request body with namespace", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ type: {
+ name: MapperType.String
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true /** isXML*/),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `body value`
+ );
+ });
+
it("should serialize an XML ByteArray request body", () => {
const httpRequest = new WebResource();
serializeRequestBody(
@@ -588,7 +705,7 @@ describe("ServiceClient", function() {
}
},
responses: { 200: {} },
- serializer: new Serializer(),
+ serializer: new Serializer(undefined, true /** isXml */),
isXML: true
}
);
@@ -598,6 +715,453 @@ describe("ServiceClient", function() {
);
});
+ it("should serialize an XML Dictionary request body", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ metadata: {
+ alpha: "hello",
+ beta: "world"
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "metadata",
+ mapper: {
+ serializedName: "metadata",
+ type: {
+ name: "Dictionary",
+ value: {
+ type: {
+ name: "String"
+ }
+ }
+ },
+ headerCollectionPrefix: "foo-bar-"
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true /** isXml */),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `helloworld`
+ );
+ });
+
+ it("should serialize an XML Dictionary request body, with namespace and prefix", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ metadata: {
+ alpha: "hello",
+ beta: "world"
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "metadata",
+ mapper: {
+ xmlNamespacePrefix: "sample",
+ xmlNamespace: "https://microsoft.com",
+ serializedName: "metadata",
+ type: {
+ name: "Dictionary",
+ value: {
+ xmlNamespacePrefix: "el",
+ xmlNamespace: "https://microsoft.com/element",
+ type: {
+ name: "String"
+ }
+ }
+ },
+ headerCollectionPrefix: "foo-bar-"
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true /** isXml */),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `helloworld`
+ );
+ });
+
+ it("should serialize a JSON Dictionary request body, ignoring xml metadata", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ metadata: {
+ alpha: "hello",
+ beta: "world"
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "metadata",
+ mapper: {
+ xmlNamespacePrefix: "sample",
+ xmlNamespace: "https://microsoft.com",
+ serializedName: "metadata",
+ type: {
+ name: "Dictionary",
+ value: {
+ xmlNamespacePrefix: "el",
+ xmlNamespace: "https://microsoft.com/element",
+ type: {
+ name: "String"
+ }
+ }
+ },
+ headerCollectionPrefix: "foo-bar-"
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer()
+ }
+ );
+ assert.deepEqual(httpRequest.body, `{"alpha":"hello","beta":"world"}`);
+ });
+
+ it("should serialize a Json ByteArray request body, ignoring namespace", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: stringToByteArray("Javascript")
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ xmlNamespace: "https://google.com",
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.ByteArray
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, false /** isXML */)
+ }
+ );
+ assert.strictEqual(httpRequest.body, `"SmF2YXNjcmlwdA=="`);
+ });
+
+ it("should serialize an XML ByteArray request body with namespace", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: stringToByteArray("Javascript")
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ xmlNamespace: "https://microsoft.com",
+ required: true,
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.ByteArray
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `SmF2YXNjcmlwdA==`
+ );
+ });
+
+ it("should serialize an XML ByteArray request body with namespace and prefix", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: stringToByteArray("Javascript")
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ xmlNamespace: "https://microsoft.com",
+ xmlNamespacePrefix: "sample",
+ required: true,
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.ByteArray
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `SmF2YXNjcmlwdA==`
+ );
+ });
+
+ it("should serialize an XML Composite request body", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ requestBody: {
+ updated: new Date("2020-08-12T23:36:18.308Z"),
+ content: { type: "application/xml", queueDescription: { maxDeliveryCount: 15 } }
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: requestBody1,
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true /** isXML */),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `2020-08-12T23:36:18.308Z15`
+ );
+ });
+
+ it("should serialize a JSON Composite request body, ignoring XML metadata", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ requestBody: {
+ updated: new Date("2020-08-12T23:36:18.308Z"),
+ content: { type: "application/xml", queueDescription: { maxDeliveryCount: 15 } }
+ }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: requestBody1,
+ responses: { 200: {} },
+ serializer: new Serializer()
+ }
+ );
+
+ assert.deepEqual(
+ httpRequest.body,
+ '{"updated":"2020-08-12T23:36:18.308Z","content":{"type":"application/xml","queueDescription":{"maxDeliveryCount":15}}}'
+ );
+ });
+
+ it("should serialize an XML Array request body with namespace and prefix", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: ["Foo", "Bar"]
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ xmlElementName: "testItem",
+ type: {
+ name: MapperType.Sequence,
+ element: {
+ xmlNamespace: "https://microsoft.com/element",
+ type: { name: "String" }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `FooBar`
+ );
+ });
+
+ it("should serialize a JSON Array request body, ignoring XML metadata", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: ["Foo", "Bar"]
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ xmlElementName: "testItem",
+ type: {
+ name: MapperType.Sequence,
+ element: {
+ xmlNamespace: "https://microsoft.com/element",
+ type: { name: "String" }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer()
+ }
+ );
+ assert.deepEqual(httpRequest.body, JSON.stringify(["Foo", "Bar"]));
+ });
+
+ it("should serialize an XML Array of composite elements, namespace and prefix", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: [
+ { foo: "Foo1", bar: "Bar1" },
+ { foo: "Foo2", bar: "Bar2" },
+ { foo: "Foo3", bar: "Bar3" }
+ ]
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ xmlElementName: "testItem",
+ type: {
+ name: MapperType.Sequence,
+ element: {
+ xmlNamespace: "https://microsoft.com/element",
+ type: {
+ name: "Composite",
+ modelProperties: {
+ foo: {
+ serializedName: "foo",
+ xmlNamespace: "https://microsoft.com/foo",
+ xmlName: "Foo",
+ type: {
+ name: "String"
+ }
+ },
+ bar: {
+ xmlNamespacePrefix: "bar",
+ xmlNamespace: "https://microsoft.com/bar",
+ xmlName: "Bar",
+ serializedName: "bar",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `Foo1Bar1Foo2Bar2Foo3Bar3`
+ );
+ });
+
+ it("should serialize an XML Composite request body with namespace and prefix", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: { foo: "Foo", bar: "Bar" }
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ xmlNamespace: "https://microsoft.com",
+ type: {
+ name: MapperType.Composite,
+ modelProperties: {
+ foo: {
+ serializedName: "foo",
+ xmlNamespace: "https://microsoft.com/foo",
+ xmlName: "Foo",
+ type: {
+ name: "String"
+ }
+ },
+ bar: {
+ xmlNamespacePrefix: "bar",
+ xmlNamespace: "https://microsoft.com/bar",
+ xmlName: "Bar",
+ serializedName: "bar",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(undefined, true),
+ isXML: true
+ }
+ );
+ assert.strictEqual(
+ httpRequest.body,
+ `FooBar`
+ );
+ });
+
it("should serialize an XML Stream request body", () => {
const httpRequest = new WebResource();
serializeRequestBody(
@@ -626,6 +1190,34 @@ describe("ServiceClient", function() {
assert.strictEqual(httpRequest.body, "body value");
});
+ it("should serialize an XML Stream request body, with namespace", () => {
+ const httpRequest = new WebResource();
+ serializeRequestBody(
+ new ServiceClient(),
+ httpRequest,
+ {
+ bodyArg: "body value"
+ },
+ {
+ httpMethod: "POST",
+ requestBody: {
+ parameterPath: "bodyArg",
+ mapper: {
+ required: true,
+ serializedName: "bodyArg",
+ type: {
+ name: MapperType.Stream
+ }
+ }
+ },
+ responses: { 200: {} },
+ serializer: new Serializer(),
+ isXML: true
+ }
+ );
+ assert.strictEqual(httpRequest.body, "body value");
+ });
+
it("should serialize a string send to a text/plain endpoint as just a string", () => {
const httpRequest = new WebResource();
serializeRequestBody(
diff --git a/sdk/core/core-http/test/testMappers.ts b/sdk/core/core-http/test/testMappers.ts
new file mode 100644
index 000000000000..06053b8e785c
--- /dev/null
+++ b/sdk/core/core-http/test/testMappers.ts
@@ -0,0 +1,266 @@
+import { CompositeMapper, OperationParameter } from "../src/coreHttp";
+
+const QueueDescription: CompositeMapper = {
+ serializedName: "QueueDescription",
+ xmlName: "QueueDescription",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Composite",
+ className: "QueueDescription",
+ modelProperties: {
+ lockDuration: {
+ serializedName: "lockDuration",
+ xmlName: "LockDuration",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ maxSizeInMegabytes: {
+ serializedName: "maxSizeInMegabytes",
+ xmlName: "MaxSizeInMegabytes",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ requiresDuplicateDetection: {
+ serializedName: "requiresDuplicateDetection",
+ xmlName: "RequiresDuplicateDetection",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ requiresSession: {
+ serializedName: "requiresSession",
+ xmlName: "RequiresSession",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ defaultMessageTimeToLive: {
+ serializedName: "defaultMessageTimeToLive",
+ xmlName: "DefaultMessageTimeToLive",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ deadLetteringOnMessageExpiration: {
+ serializedName: "deadLetteringOnMessageExpiration",
+ xmlName: "DeadLetteringOnMessageExpiration",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ duplicateDetectionHistoryTimeWindow: {
+ serializedName: "duplicateDetectionHistoryTimeWindow",
+ xmlName: "DuplicateDetectionHistoryTimeWindow",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ maxDeliveryCount: {
+ serializedName: "maxDeliveryCount",
+ xmlName: "MaxDeliveryCount",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ enableBatchedOperations: {
+ serializedName: "enableBatchedOperations",
+ xmlName: "EnableBatchedOperations",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ sizeInBytes: {
+ serializedName: "sizeInBytes",
+ xmlName: "SizeInBytes",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ messageCount: {
+ serializedName: "messageCount",
+ xmlName: "MessageCount",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Number"
+ }
+ },
+ isAnonymousAccessible: {
+ serializedName: "isAnonymousAccessible",
+ xmlName: "IsAnonymousAccessible",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ status: {
+ serializedName: "status",
+ xmlName: "Status",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ forwardTo: {
+ serializedName: "forwardTo",
+ xmlName: "ForwardTo",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ userMetadata: {
+ serializedName: "userMetadata",
+ xmlName: "UserMetadata",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ createdAt: {
+ serializedName: "createdAt",
+ xmlName: "CreatedAt",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "DateTime"
+ }
+ },
+ updatedAt: {
+ serializedName: "updatedAt",
+ xmlName: "UpdatedAt",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "DateTime"
+ }
+ },
+ accessedAt: {
+ serializedName: "accessedAt",
+ xmlName: "AccessedAt",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "DateTime"
+ }
+ },
+ supportOrdering: {
+ serializedName: "supportOrdering",
+ xmlName: "SupportOrdering",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ autoDeleteOnIdle: {
+ serializedName: "autoDeleteOnIdle",
+ xmlName: "AutoDeleteOnIdle",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "TimeSpan"
+ }
+ },
+ enablePartitioning: {
+ serializedName: "enablePartitioning",
+ xmlName: "EnablePartitioning",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ entityAvailabilityStatus: {
+ serializedName: "entityAvailabilityStatus",
+ xmlName: "EntityAvailabilityStatus",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ },
+ enableExpress: {
+ serializedName: "enableExpress",
+ xmlName: "EnableExpress",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "Boolean"
+ }
+ },
+ forwardDeadLetteredMessagesTo: {
+ serializedName: "forwardDeadLetteredMessagesTo",
+ xmlName: "ForwardDeadLetteredMessagesTo",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ name: "String"
+ }
+ }
+ }
+ }
+};
+
+const CreateQueueBodyContent: CompositeMapper = {
+ serializedName: "CreateQueueBodyContent",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ name: "Composite",
+ className: "CreateQueueBodyContent",
+ modelProperties: {
+ type: {
+ defaultValue: "application/xml",
+ serializedName: "type",
+ xmlName: "type",
+ xmlIsAttribute: true,
+ type: {
+ name: "String"
+ }
+ },
+ queueDescription: {
+ serializedName: "queueDescription",
+ xmlName: "QueueDescription",
+ xmlNamespace: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
+ type: {
+ ...QueueDescription.type
+ }
+ }
+ }
+ }
+};
+
+const CreateQueueBody: CompositeMapper = {
+ serializedName: "CreateQueueBody",
+ xmlName: "entry",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ name: "Composite",
+ className: "CreateQueueBody",
+ modelProperties: {
+ updated: {
+ serializedName: "updated",
+ xmlName: "updated",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ name: "DateTime"
+ }
+ },
+ content: {
+ serializedName: "content",
+ xmlName: "content",
+ xmlNamespace: "http://www.w3.org/2005/Atom",
+ type: {
+ ...CreateQueueBodyContent.type
+ }
+ }
+ }
+ }
+};
+
+export const requestBody1: OperationParameter = {
+ parameterPath: "requestBody",
+ mapper: CreateQueueBody
+};