You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,388 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
|
||||
class ActiveXSerializer
|
||||
{
|
||||
|
||||
byte[] byteBuffer;
|
||||
char[] charBuffer;
|
||||
object bufferLock = new object();
|
||||
|
||||
TKind[] TakeLockedBuffer<TKind>(out bool lockHeld, int size)
|
||||
{
|
||||
lockHeld = false;
|
||||
Monitor.Enter(this.bufferLock, ref lockHeld);
|
||||
if (typeof(byte) == typeof(TKind))
|
||||
{
|
||||
if (null == this.byteBuffer || size > this.byteBuffer.Length)
|
||||
this.byteBuffer = new byte[size];
|
||||
return this.byteBuffer as TKind[];
|
||||
}
|
||||
else if (typeof(char) == typeof(TKind))
|
||||
{
|
||||
if (null == this.charBuffer || size > this.charBuffer.Length)
|
||||
this.charBuffer = new char[size];
|
||||
return this.charBuffer as TKind[];
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
void ReleaseLockedBuffer()
|
||||
{
|
||||
Monitor.Exit(this.bufferLock);
|
||||
}
|
||||
|
||||
public object Deserialize(MemoryStream stream, int bodyType)
|
||||
{
|
||||
if (stream == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
|
||||
|
||||
VarEnum variantType = (VarEnum)bodyType;
|
||||
|
||||
byte[] bytes;
|
||||
byte[] newBytes;
|
||||
int size;
|
||||
int count;
|
||||
bool lockHeld;
|
||||
|
||||
switch (variantType)
|
||||
{
|
||||
case VarEnum.VT_LPSTR:
|
||||
bytes = stream.ToArray();
|
||||
size = bytes.Length;
|
||||
|
||||
lockHeld = false;
|
||||
try
|
||||
{
|
||||
char[] buffer = TakeLockedBuffer<char>(out lockHeld, size);
|
||||
System.Text.Encoding.ASCII.GetChars(bytes, 0, size, buffer, 0);
|
||||
return new String(buffer, 0, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockHeld)
|
||||
{
|
||||
ReleaseLockedBuffer();
|
||||
}
|
||||
}
|
||||
case VarEnum.VT_BSTR:
|
||||
case VarEnum.VT_LPWSTR:
|
||||
bytes = stream.ToArray();
|
||||
size = bytes.Length / 2;
|
||||
|
||||
lockHeld = false;
|
||||
try
|
||||
{
|
||||
char[] buffer = TakeLockedBuffer<char>(out lockHeld, size);
|
||||
System.Text.Encoding.Unicode.GetChars(bytes, 0, size * 2, buffer, 0);
|
||||
return new String(buffer, 0, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockHeld)
|
||||
{
|
||||
ReleaseLockedBuffer();
|
||||
}
|
||||
}
|
||||
case VarEnum.VT_VECTOR | VarEnum.VT_UI1:
|
||||
bytes = stream.ToArray();
|
||||
newBytes = new byte[bytes.Length];
|
||||
Array.Copy(bytes, newBytes, bytes.Length);
|
||||
|
||||
return newBytes;
|
||||
|
||||
case VarEnum.VT_BOOL:
|
||||
bytes = new byte[1];
|
||||
count = stream.Read(bytes, 0, 1);
|
||||
|
||||
if (count != 1)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return (bytes[0] != 0);
|
||||
|
||||
case VarEnum.VT_CLSID:
|
||||
bytes = new byte[16];
|
||||
count = stream.Read(bytes, 0, 16);
|
||||
|
||||
if (count != 16)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return new Guid(bytes);
|
||||
|
||||
case VarEnum.VT_CY:
|
||||
|
||||
bytes = new byte[8];
|
||||
count = stream.Read(bytes, 0, 8);
|
||||
|
||||
if (count != 8)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return Decimal.FromOACurrency(BitConverter.ToInt64(bytes, 0));
|
||||
|
||||
case VarEnum.VT_DATE:
|
||||
|
||||
bytes = new byte[8];
|
||||
count = stream.Read(bytes, 0, 8);
|
||||
|
||||
if (count != 8)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return new DateTime(BitConverter.ToInt64(bytes, 0));
|
||||
|
||||
case VarEnum.VT_I1:
|
||||
case VarEnum.VT_UI1:
|
||||
|
||||
bytes = new byte[1];
|
||||
count = stream.Read(bytes, 0, 1);
|
||||
|
||||
if (count != 1)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return bytes[0];
|
||||
|
||||
case VarEnum.VT_I2:
|
||||
bytes = new byte[2];
|
||||
count = stream.Read(bytes, 0, 2);
|
||||
|
||||
if (count != 2)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToInt16(bytes, 0);
|
||||
|
||||
case VarEnum.VT_UI2:
|
||||
bytes = new byte[2];
|
||||
count = stream.Read(bytes, 0, 2);
|
||||
|
||||
if (count != 2)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToUInt16(bytes, 0);
|
||||
|
||||
case VarEnum.VT_I4:
|
||||
bytes = new byte[4];
|
||||
count = stream.Read(bytes, 0, 4);
|
||||
|
||||
if (count != 4)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
|
||||
case VarEnum.VT_UI4:
|
||||
bytes = new byte[4];
|
||||
count = stream.Read(bytes, 0, 4);
|
||||
|
||||
if (count != 4)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToUInt32(bytes, 0);
|
||||
|
||||
case VarEnum.VT_I8:
|
||||
bytes = new byte[8];
|
||||
count = stream.Read(bytes, 0, 8);
|
||||
|
||||
if (count != 8)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToInt64(bytes, 0);
|
||||
|
||||
case VarEnum.VT_UI8:
|
||||
bytes = new byte[8];
|
||||
count = stream.Read(bytes, 0, 8);
|
||||
|
||||
if (count != 8)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToUInt64(bytes, 0);
|
||||
|
||||
case VarEnum.VT_R4:
|
||||
bytes = new byte[4];
|
||||
count = stream.Read(bytes, 0, 4);
|
||||
|
||||
if (count != 4)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
|
||||
case VarEnum.VT_R8:
|
||||
bytes = new byte[8];
|
||||
count = stream.Read(bytes, 0, 8);
|
||||
|
||||
if (count != 8)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
|
||||
|
||||
return BitConverter.ToDouble(bytes, 0);
|
||||
|
||||
case VarEnum.VT_NULL:
|
||||
return null;
|
||||
|
||||
|
||||
default:
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqInvalidTypeDeserialization)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Serialize(Stream stream, object obj, ref int bodyType)
|
||||
{
|
||||
if (stream == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
|
||||
|
||||
VarEnum variantType;
|
||||
if (obj is string)
|
||||
{
|
||||
int size = ((string)obj).Length * 2;
|
||||
|
||||
bool lockHeld = false;
|
||||
try
|
||||
{
|
||||
byte[] buffer = TakeLockedBuffer<byte>(out lockHeld, size);
|
||||
System.Text.Encoding.Unicode.GetBytes(((string)obj).ToCharArray(), 0, size / 2, buffer, 0);
|
||||
stream.Write(buffer, 0, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockHeld)
|
||||
{
|
||||
ReleaseLockedBuffer();
|
||||
}
|
||||
}
|
||||
variantType = VarEnum.VT_LPWSTR;
|
||||
}
|
||||
else if (obj is byte[])
|
||||
{
|
||||
byte[] bytes = (byte[])obj;
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
variantType = VarEnum.VT_UI1 | VarEnum.VT_VECTOR;
|
||||
}
|
||||
else if (obj is char[])
|
||||
{
|
||||
char[] chars = (char[])obj;
|
||||
int size = chars.Length * 2;
|
||||
|
||||
bool lockHeld = false;
|
||||
try
|
||||
{
|
||||
byte[] buffer = TakeLockedBuffer<byte>(out lockHeld, size);
|
||||
System.Text.Encoding.Unicode.GetBytes(chars, 0, size / 2, buffer, 0);
|
||||
stream.Write(buffer, 0, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockHeld)
|
||||
{
|
||||
ReleaseLockedBuffer();
|
||||
}
|
||||
}
|
||||
variantType = VarEnum.VT_LPWSTR;
|
||||
}
|
||||
else if (obj is byte)
|
||||
{
|
||||
stream.Write(new byte[] { (byte)obj }, 0, 1);
|
||||
variantType = VarEnum.VT_UI1;
|
||||
}
|
||||
else if (obj is bool)
|
||||
{
|
||||
if ((bool)obj)
|
||||
stream.Write(new byte[] { 0xff }, 0, 1);
|
||||
else
|
||||
stream.Write(new byte[] { 0x00 }, 0, 1);
|
||||
variantType = VarEnum.VT_BOOL;
|
||||
}
|
||||
else if (obj is char)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes((Char)obj);
|
||||
stream.Write(bytes, 0, 2);
|
||||
variantType = VarEnum.VT_UI2;
|
||||
}
|
||||
else if (obj is Decimal)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(Decimal.ToOACurrency((Decimal)obj));
|
||||
stream.Write(bytes, 0, 8);
|
||||
variantType = VarEnum.VT_CY;
|
||||
}
|
||||
else if (obj is DateTime)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(((DateTime)obj).Ticks);
|
||||
stream.Write(bytes, 0, 8);
|
||||
variantType = VarEnum.VT_DATE;
|
||||
}
|
||||
else if (obj is Double)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes((Double)obj);
|
||||
stream.Write(bytes, 0, 8);
|
||||
variantType = VarEnum.VT_R8;
|
||||
}
|
||||
else if (obj is Guid)
|
||||
{
|
||||
byte[] bytes = ((Guid)obj).ToByteArray();
|
||||
stream.Write(bytes, 0, 16);
|
||||
variantType = VarEnum.VT_CLSID;
|
||||
}
|
||||
else if (obj is Int16)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes((short)obj);
|
||||
stream.Write(bytes, 0, 2);
|
||||
variantType = VarEnum.VT_I2;
|
||||
}
|
||||
else if (obj is UInt16)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes((UInt16)obj);
|
||||
stream.Write(bytes, 0, 2);
|
||||
variantType = VarEnum.VT_UI2;
|
||||
}
|
||||
else if (obj is Int32)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes((int)obj);
|
||||
stream.Write(bytes, 0, 4);
|
||||
variantType = VarEnum.VT_I4;
|
||||
}
|
||||
else if (obj is UInt32)
|
||||
{
|
||||
|
||||
byte[] bytes = BitConverter.GetBytes((UInt32)obj);
|
||||
stream.Write(bytes, 0, 4);
|
||||
variantType = VarEnum.VT_UI4;
|
||||
}
|
||||
else if (obj is Int64)
|
||||
{
|
||||
|
||||
byte[] bytes = BitConverter.GetBytes((Int64)obj);
|
||||
stream.Write(bytes, 0, 8);
|
||||
variantType = VarEnum.VT_I8;
|
||||
}
|
||||
else if (obj is UInt64)
|
||||
{
|
||||
|
||||
byte[] bytes = BitConverter.GetBytes((UInt64)obj);
|
||||
stream.Write(bytes, 0, 8);
|
||||
variantType = VarEnum.VT_UI8;
|
||||
}
|
||||
else if (obj is Single)
|
||||
{
|
||||
|
||||
byte[] bytes = BitConverter.GetBytes((float)obj);
|
||||
stream.Write(bytes, 0, 4);
|
||||
variantType = VarEnum.VT_R4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MsmqInvalidTypeSerialization)));
|
||||
}
|
||||
|
||||
bodyType = (int)variantType;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,124 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ServiceModel;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Configuration;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceModel.Channels;
|
||||
using Config = System.ServiceModel.Configuration;
|
||||
using System.ServiceModel.Security;
|
||||
|
||||
using System.Xml;
|
||||
|
||||
public class MsmqIntegrationBinding : MsmqBindingBase
|
||||
{
|
||||
// private BindingElements
|
||||
MsmqIntegrationSecurity security = new MsmqIntegrationSecurity();
|
||||
|
||||
public MsmqIntegrationBinding()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public MsmqIntegrationBinding(string configurationName)
|
||||
{
|
||||
Initialize();
|
||||
ApplyConfiguration(configurationName);
|
||||
}
|
||||
|
||||
public MsmqIntegrationBinding(MsmqIntegrationSecurityMode securityMode)
|
||||
{
|
||||
if (!MsmqIntegrationSecurityModeHelper.IsDefined(securityMode))
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("securityMode", (int)securityMode, typeof(MsmqIntegrationSecurityMode)));
|
||||
Initialize();
|
||||
this.security.Mode = securityMode;
|
||||
}
|
||||
|
||||
public MsmqIntegrationSecurity Security
|
||||
{
|
||||
get { return this.security; }
|
||||
set { this.security = value; }
|
||||
}
|
||||
|
||||
internal Type[] TargetSerializationTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return (transport as MsmqIntegrationBindingElement).TargetSerializationTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
(transport as MsmqIntegrationBindingElement).TargetSerializationTypes = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(MsmqIntegrationDefaults.SerializationFormat)]
|
||||
public MsmqMessageSerializationFormat SerializationFormat
|
||||
{
|
||||
get { return (transport as MsmqIntegrationBindingElement).SerializationFormat; }
|
||||
set { (transport as MsmqIntegrationBindingElement).SerializationFormat = value; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeSecurity()
|
||||
{
|
||||
if (this.security.Mode != MsmqIntegrationSecurityMode.Transport)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.security.Transport.MsmqAuthenticationMode != MsmqDefaults.MsmqAuthenticationMode ||
|
||||
this.security.Transport.MsmqEncryptionAlgorithm != MsmqDefaults.MsmqEncryptionAlgorithm ||
|
||||
this.security.Transport.MsmqSecureHashAlgorithm != MsmqDefaults.MsmqSecureHashAlgorithm ||
|
||||
this.security.Transport.MsmqProtectionLevel != MsmqDefaults.MsmqProtectionLevel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
transport = new MsmqIntegrationBindingElement();
|
||||
}
|
||||
|
||||
void ApplyConfiguration(string configurationName)
|
||||
{
|
||||
Config.MsmqIntegrationBindingCollectionElement section = Config.MsmqIntegrationBindingCollectionElement.GetBindingCollectionElement();
|
||||
Config.MsmqIntegrationBindingElement element = section.Bindings[configurationName];
|
||||
if (element == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(
|
||||
SR.GetString(SR.ConfigInvalidBindingConfigurationName,
|
||||
configurationName,
|
||||
Config.ConfigurationStrings.MsmqIntegrationBindingCollectionElementName)));
|
||||
}
|
||||
else
|
||||
{
|
||||
element.ApplyConfiguration(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override BindingElementCollection CreateBindingElements()
|
||||
{ // return collection of BindingElements
|
||||
BindingElementCollection bindingElements = new BindingElementCollection();
|
||||
// order of BindingElements is important
|
||||
// add transport
|
||||
this.security.ConfigureTransportSecurity(transport);
|
||||
bindingElements.Add(transport);
|
||||
|
||||
return bindingElements.Clone();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.Net.Security;
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
public sealed class MsmqIntegrationBindingElement : MsmqBindingElementBase
|
||||
{
|
||||
MsmqMessageSerializationFormat serializationFormat;
|
||||
Type[] targetSerializationTypes;
|
||||
|
||||
public MsmqIntegrationBindingElement()
|
||||
{
|
||||
this.serializationFormat = MsmqIntegrationDefaults.SerializationFormat;
|
||||
}
|
||||
|
||||
MsmqIntegrationBindingElement(MsmqIntegrationBindingElement other)
|
||||
: base(other)
|
||||
{
|
||||
this.serializationFormat = other.serializationFormat;
|
||||
if (other.targetSerializationTypes != null)
|
||||
{
|
||||
this.targetSerializationTypes = other.targetSerializationTypes.Clone() as Type[];
|
||||
}
|
||||
}
|
||||
|
||||
public override string Scheme { get { return "msmq.formatname"; } }
|
||||
|
||||
internal override MsmqUri.IAddressTranslator AddressTranslator
|
||||
{
|
||||
get
|
||||
{
|
||||
return MsmqUri.FormatNameAddressTranslator;
|
||||
}
|
||||
}
|
||||
|
||||
// applicable on: client, server
|
||||
public MsmqMessageSerializationFormat SerializationFormat
|
||||
{
|
||||
get { return this.serializationFormat; }
|
||||
set
|
||||
{
|
||||
if (!MsmqMessageSerializationFormatHelper.IsDefined(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
|
||||
}
|
||||
|
||||
this.serializationFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
// applicable on: receiver
|
||||
public Type[] TargetSerializationTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == this.targetSerializationTypes)
|
||||
return null;
|
||||
else
|
||||
return this.targetSerializationTypes.Clone() as Type[];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (null == value)
|
||||
this.targetSerializationTypes = null;
|
||||
else
|
||||
this.targetSerializationTypes = value.Clone() as Type[];
|
||||
}
|
||||
}
|
||||
|
||||
public override BindingElement Clone()
|
||||
{
|
||||
return new MsmqIntegrationBindingElement(this);
|
||||
}
|
||||
|
||||
public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
return typeof(TChannel) == typeof(IOutputChannel);
|
||||
}
|
||||
|
||||
public override bool CanBuildChannelListener<TChannel>(BindingContext context)
|
||||
{
|
||||
return typeof(TChannel) == typeof(IInputChannel);
|
||||
}
|
||||
|
||||
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
}
|
||||
|
||||
if (typeof(TChannel) != typeof(IOutputChannel))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
|
||||
}
|
||||
|
||||
MsmqChannelFactoryBase<IOutputChannel> factory = new MsmqIntegrationChannelFactory(this, context);
|
||||
MsmqVerifier.VerifySender<IOutputChannel>(factory);
|
||||
return (IChannelFactory<TChannel>)(object)factory;
|
||||
}
|
||||
|
||||
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
}
|
||||
|
||||
if (typeof(TChannel) != typeof(IInputChannel))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
|
||||
}
|
||||
|
||||
MsmqIntegrationReceiveParameters receiveParameters = new MsmqIntegrationReceiveParameters(this);
|
||||
MsmqIntegrationChannelListener listener = new MsmqIntegrationChannelListener(this, context, receiveParameters);
|
||||
MsmqVerifier.VerifyReceiver(receiveParameters, listener.Uri);
|
||||
|
||||
return (IChannelListener<TChannel>)(object)listener;
|
||||
}
|
||||
|
||||
public override T GetProperty<T>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
}
|
||||
if (typeof(T) == typeof(MessageVersion))
|
||||
{
|
||||
return (T)(object)(MessageVersion.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.GetProperty<T>(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,178 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel;
|
||||
using System.Runtime.Serialization.Formatters.Binary; // for BinaryFormatter
|
||||
using System.Xml.Serialization; // for XmlSerializer
|
||||
using System.IO; // for Stream
|
||||
using System.Collections.Specialized; //For HybridDictionary
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
sealed class MsmqIntegrationChannelFactory : MsmqChannelFactoryBase<IOutputChannel>
|
||||
{
|
||||
ActiveXSerializer activeXSerializer;
|
||||
BinaryFormatter binaryFormatter;
|
||||
MsmqMessageSerializationFormat serializationFormat;
|
||||
HybridDictionary xmlSerializerTable;
|
||||
const int maxSerializerTableSize = 1024;
|
||||
|
||||
internal MsmqIntegrationChannelFactory(MsmqIntegrationBindingElement bindingElement, BindingContext context)
|
||||
: base(bindingElement, context, null)
|
||||
{
|
||||
this.serializationFormat = bindingElement.SerializationFormat;
|
||||
}
|
||||
|
||||
BinaryFormatter BinaryFormatter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.binaryFormatter == null)
|
||||
{
|
||||
lock (ThisLock)
|
||||
{
|
||||
if (this.binaryFormatter == null)
|
||||
this.binaryFormatter = new BinaryFormatter();
|
||||
}
|
||||
}
|
||||
|
||||
return this.binaryFormatter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ActiveXSerializer ActiveXSerializer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.activeXSerializer == null)
|
||||
{
|
||||
lock (ThisLock)
|
||||
{
|
||||
if (this.activeXSerializer == null)
|
||||
this.activeXSerializer = new ActiveXSerializer();
|
||||
}
|
||||
}
|
||||
|
||||
return this.activeXSerializer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XmlSerializer GetXmlSerializerForType(Type serializedType)
|
||||
{
|
||||
if (this.xmlSerializerTable == null)
|
||||
{
|
||||
lock (ThisLock)
|
||||
{
|
||||
if (this.xmlSerializerTable == null)
|
||||
this.xmlSerializerTable = new HybridDictionary();
|
||||
}
|
||||
}
|
||||
|
||||
XmlSerializer serializer = (XmlSerializer)this.xmlSerializerTable[serializedType];
|
||||
if (serializer != null)
|
||||
{
|
||||
return serializer;
|
||||
}
|
||||
|
||||
lock (ThisLock)
|
||||
{
|
||||
if (this.xmlSerializerTable.Count >= maxSerializerTableSize)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new CommunicationException(SR.GetString(SR.MsmqSerializationTableFull, maxSerializerTableSize)));
|
||||
// double-locking
|
||||
serializer = (XmlSerializer)this.xmlSerializerTable[serializedType];
|
||||
if (serializer != null)
|
||||
{
|
||||
return serializer;
|
||||
}
|
||||
|
||||
serializer = new XmlSerializer(serializedType);
|
||||
this.xmlSerializerTable[serializedType] = serializer;
|
||||
|
||||
return serializer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public MsmqMessageSerializationFormat SerializationFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
return this.serializationFormat;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IOutputChannel OnCreateChannel(EndpointAddress to, Uri via)
|
||||
{
|
||||
base.ValidateScheme(via);
|
||||
return new MsmqIntegrationOutputChannel(this, to, via, ManualAddressing);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns stream containing serialized body
|
||||
// In case of MsmqMessageSerializationFormat.Stream,
|
||||
// returns body as Stream, and throws exception if body is not a Stream
|
||||
//
|
||||
internal Stream Serialize(MsmqIntegrationMessageProperty property)
|
||||
{
|
||||
Stream stream;
|
||||
switch (this.SerializationFormat)
|
||||
{
|
||||
case MsmqMessageSerializationFormat.Xml:
|
||||
stream = new MemoryStream();
|
||||
XmlSerializer serializer = GetXmlSerializerForType(property.Body.GetType());
|
||||
serializer.Serialize(stream, property.Body);
|
||||
return stream;
|
||||
|
||||
case MsmqMessageSerializationFormat.Binary:
|
||||
stream = new MemoryStream();
|
||||
BinaryFormatter.Serialize(stream, property.Body);
|
||||
// need to set BodyType to a magic number used by System.Messaging
|
||||
property.BodyType = 0x300;
|
||||
return stream;
|
||||
|
||||
case MsmqMessageSerializationFormat.ActiveX:
|
||||
if (property.BodyType.HasValue)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqCannotUseBodyTypeWithActiveXSerialization)));
|
||||
}
|
||||
|
||||
stream = new MemoryStream();
|
||||
int bodyType = 0;
|
||||
ActiveXSerializer.Serialize(stream as MemoryStream, property.Body, ref bodyType);
|
||||
property.BodyType = bodyType;
|
||||
return stream;
|
||||
|
||||
case MsmqMessageSerializationFormat.ByteArray:
|
||||
// body MUST be byte array
|
||||
byte[] byteArray = property.Body as byte[];
|
||||
if (byteArray == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqByteArrayBodyExpected)));
|
||||
|
||||
stream = new MemoryStream();
|
||||
stream.Write(byteArray, 0, byteArray.Length);
|
||||
return stream;
|
||||
|
||||
case MsmqMessageSerializationFormat.Stream:
|
||||
// body MUST be a stream
|
||||
Stream bodyStream = property.Body as Stream;
|
||||
if (bodyStream == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqStreamBodyExpected)));
|
||||
|
||||
// NOTE: we don't copy here as a perf optimization, but this might be dangerous
|
||||
return bodyStream;
|
||||
|
||||
default:
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqUnsupportedSerializationFormat, this.SerializationFormat)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
sealed class MsmqIntegrationChannelListener
|
||||
: MsmqInputChannelListenerBase
|
||||
{
|
||||
XmlSerializer[] xmlSerializerList;
|
||||
|
||||
internal MsmqIntegrationChannelListener(MsmqBindingElementBase bindingElement, BindingContext context, MsmqReceiveParameters receiveParameters)
|
||||
: base(bindingElement, context, receiveParameters, null)
|
||||
{
|
||||
SetSecurityTokenAuthenticator(MsmqUri.FormatNameAddressTranslator.Scheme, context);
|
||||
MsmqIntegrationReceiveParameters parameters = receiveParameters as MsmqIntegrationReceiveParameters;
|
||||
xmlSerializerList = XmlSerializer.FromTypes(parameters.TargetSerializationTypes);
|
||||
}
|
||||
|
||||
public override string Scheme
|
||||
{
|
||||
get { return "msmq.formatname"; }
|
||||
}
|
||||
|
||||
internal XmlSerializer[] XmlSerializerList
|
||||
{
|
||||
get { return this.xmlSerializerList; }
|
||||
}
|
||||
|
||||
protected override IInputChannel CreateInputChannel(MsmqInputChannelListenerBase listener)
|
||||
{
|
||||
return new MsmqIntegrationInputChannel(this);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
sealed class MsmqIntegrationInputChannel
|
||||
: MsmqInputChannelBase
|
||||
{
|
||||
public MsmqIntegrationInputChannel(MsmqIntegrationChannelListener listener)
|
||||
: base(listener, new MsmqIntegrationMessagePool(MsmqDefaults.MaxPoolSize))
|
||||
{ }
|
||||
|
||||
protected override Message DecodeMsmqMessage(MsmqInputMessage msmqMessage, MsmqMessageProperty property)
|
||||
{
|
||||
MsmqIntegrationChannelListener listener = this.Manager as MsmqIntegrationChannelListener;
|
||||
return MsmqDecodeHelper.DecodeIntegrationDatagram(listener, this.MsmqReceiveHelper, msmqMessage as MsmqIntegrationInputMessage, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,123 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
class MsmqIntegrationInputMessage : MsmqInputMessage
|
||||
{
|
||||
ByteProperty acknowledge;
|
||||
StringProperty adminQueue;
|
||||
IntProperty adminQueueLength;
|
||||
IntProperty appSpecific;
|
||||
IntProperty arrivedTime;
|
||||
IntProperty senderIdType;
|
||||
ByteProperty authenticated;
|
||||
IntProperty bodyType;
|
||||
BufferProperty correlationId;
|
||||
StringProperty destinationQueue;
|
||||
IntProperty destinationQueueLength;
|
||||
BufferProperty extension;
|
||||
IntProperty extensionLength;
|
||||
StringProperty label;
|
||||
IntProperty labelLength;
|
||||
ByteProperty priority;
|
||||
StringProperty responseFormatName;
|
||||
IntProperty responseFormatNameLength;
|
||||
IntProperty sentTime;
|
||||
IntProperty timeToReachQueue;
|
||||
IntProperty privacyLevel;
|
||||
const int initialQueueNameLength = 256;
|
||||
const int initialExtensionLength = 0;
|
||||
const int initialLabelLength = 128;
|
||||
const int maxSize = 4 * 1024 * 1024;
|
||||
|
||||
public MsmqIntegrationInputMessage()
|
||||
: this(maxSize)
|
||||
{ }
|
||||
|
||||
public MsmqIntegrationInputMessage(int maxBufferSize)
|
||||
: this(new SizeQuota(maxBufferSize))
|
||||
{ }
|
||||
|
||||
protected MsmqIntegrationInputMessage(SizeQuota bufferSizeQuota)
|
||||
: base(22, bufferSizeQuota)
|
||||
{
|
||||
this.acknowledge = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_ACKNOWLEDGE);
|
||||
this.adminQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_ADMIN_QUEUE, initialQueueNameLength);
|
||||
this.adminQueueLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_ADMIN_QUEUE_LEN, initialQueueNameLength);
|
||||
this.appSpecific = new IntProperty(this, UnsafeNativeMethods.PROPID_M_APPSPECIFIC);
|
||||
this.arrivedTime = new IntProperty(this, UnsafeNativeMethods.PROPID_M_ARRIVEDTIME);
|
||||
this.senderIdType = new IntProperty(this, UnsafeNativeMethods.PROPID_M_SENDERID_TYPE);
|
||||
this.authenticated = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_AUTHENTICATED);
|
||||
this.bodyType = new IntProperty(this, UnsafeNativeMethods.PROPID_M_BODY_TYPE);
|
||||
this.correlationId = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_CORRELATIONID,
|
||||
UnsafeNativeMethods.PROPID_M_CORRELATIONID_SIZE);
|
||||
this.destinationQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_DEST_FORMAT_NAME, initialQueueNameLength);
|
||||
this.destinationQueueLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_DEST_FORMAT_NAME_LEN, initialQueueNameLength);
|
||||
this.extension = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_EXTENSION,
|
||||
bufferSizeQuota.AllocIfAvailable(initialExtensionLength));
|
||||
this.extensionLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_EXTENSION_LEN, initialExtensionLength);
|
||||
this.label = new StringProperty(this, UnsafeNativeMethods.PROPID_M_LABEL, initialLabelLength);
|
||||
this.labelLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_LABEL_LEN, initialLabelLength);
|
||||
this.priority = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_PRIORITY);
|
||||
this.responseFormatName = new StringProperty(this, UnsafeNativeMethods.PROPID_M_RESP_FORMAT_NAME, initialQueueNameLength);
|
||||
this.responseFormatNameLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_RESP_FORMAT_NAME_LEN, initialQueueNameLength);
|
||||
this.sentTime = new IntProperty(this, UnsafeNativeMethods.PROPID_M_SENTTIME);
|
||||
this.timeToReachQueue = new IntProperty(this, UnsafeNativeMethods.PROPID_M_TIME_TO_REACH_QUEUE);
|
||||
this.privacyLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_PRIV_LEVEL);
|
||||
}
|
||||
|
||||
protected override void OnGrowBuffers(SizeQuota bufferSizeQuota)
|
||||
{
|
||||
base.OnGrowBuffers(bufferSizeQuota);
|
||||
|
||||
this.adminQueue.EnsureValueLength(this.adminQueueLength.Value);
|
||||
this.responseFormatName.EnsureValueLength(this.responseFormatNameLength.Value);
|
||||
this.destinationQueue.EnsureValueLength(this.destinationQueueLength.Value);
|
||||
this.label.EnsureValueLength(this.labelLength.Value);
|
||||
|
||||
bufferSizeQuota.Alloc(this.extensionLength.Value);
|
||||
this.extension.EnsureBufferLength(this.extensionLength.Value);
|
||||
}
|
||||
|
||||
public void SetMessageProperties(MsmqIntegrationMessageProperty property)
|
||||
{
|
||||
property.AcknowledgeType = (System.Messaging.AcknowledgeTypes)this.acknowledge.Value;
|
||||
property.Acknowledgment = (System.Messaging.Acknowledgment)this.Class.Value;
|
||||
property.AdministrationQueue = GetQueueName(this.adminQueue.GetValue(this.adminQueueLength.Value));
|
||||
property.AppSpecific = this.appSpecific.Value;
|
||||
property.ArrivedTime = MsmqDateTime.ToDateTime(this.arrivedTime.Value).ToLocalTime();
|
||||
property.Authenticated = this.authenticated.Value != 0;
|
||||
property.BodyType = this.bodyType.Value;
|
||||
property.CorrelationId = MsmqMessageId.ToString(this.correlationId.Buffer);
|
||||
property.DestinationQueue = GetQueueName(this.destinationQueue.GetValue(this.destinationQueueLength.Value));
|
||||
property.Extension = this.extension.GetBufferCopy(this.extensionLength.Value);
|
||||
property.Id = MsmqMessageId.ToString(this.MessageId.Buffer);
|
||||
property.Label = this.label.GetValue(this.labelLength.Value);
|
||||
|
||||
if (this.Class.Value == UnsafeNativeMethods.MQMSG_CLASS_NORMAL)
|
||||
property.MessageType = System.Messaging.MessageType.Normal;
|
||||
else if (this.Class.Value == UnsafeNativeMethods.MQMSG_CLASS_REPORT)
|
||||
property.MessageType = System.Messaging.MessageType.Report;
|
||||
else
|
||||
property.MessageType = System.Messaging.MessageType.Acknowledgment;
|
||||
|
||||
property.Priority = (System.Messaging.MessagePriority)this.priority.Value;
|
||||
property.ResponseQueue = GetQueueName(this.responseFormatName.GetValue(this.responseFormatNameLength.Value));
|
||||
property.SenderId = this.SenderId.GetBufferCopy(this.SenderIdLength.Value);
|
||||
property.SentTime = MsmqDateTime.ToDateTime(this.sentTime.Value).ToLocalTime();
|
||||
property.InternalSetTimeToReachQueue(MsmqDuration.ToTimeSpan(this.timeToReachQueue.Value));
|
||||
}
|
||||
|
||||
static Uri GetQueueName(string formatName)
|
||||
{
|
||||
if (String.IsNullOrEmpty(formatName))
|
||||
return null;
|
||||
else
|
||||
return new Uri("msmq.formatname:" + formatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,36 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
sealed class MsmqIntegrationMessagePool
|
||||
: SynchronizedDisposablePool<MsmqIntegrationInputMessage>, IMsmqMessagePool
|
||||
{
|
||||
int maxPoolSize;
|
||||
|
||||
internal MsmqIntegrationMessagePool(int maxPoolSize)
|
||||
: base(maxPoolSize)
|
||||
{
|
||||
this.maxPoolSize = maxPoolSize;
|
||||
}
|
||||
|
||||
MsmqInputMessage IMsmqMessagePool.TakeMessage()
|
||||
{
|
||||
MsmqIntegrationInputMessage message = this.Take();
|
||||
if (null == message)
|
||||
message = new MsmqIntegrationInputMessage();
|
||||
return message;
|
||||
}
|
||||
|
||||
void IMsmqMessagePool.ReturnMessage(MsmqInputMessage message)
|
||||
{
|
||||
if (! this.Return(message as MsmqIntegrationInputMessage))
|
||||
{
|
||||
MsmqDiagnostics.PoolFull(this.maxPoolSize);
|
||||
message.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,192 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Messaging;
|
||||
using System.Runtime;
|
||||
|
||||
public sealed class MsmqIntegrationMessageProperty
|
||||
{
|
||||
public const string Name = "MsmqIntegrationMessageProperty";
|
||||
|
||||
public static MsmqIntegrationMessageProperty Get(System.ServiceModel.Channels.Message message)
|
||||
{
|
||||
if (null == message)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
|
||||
if (null == message.Properties)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message.Properties");
|
||||
|
||||
return message.Properties[Name] as MsmqIntegrationMessageProperty;
|
||||
}
|
||||
|
||||
object body;
|
||||
public object Body
|
||||
{
|
||||
get { return this.body; }
|
||||
set { this.body = value; }
|
||||
}
|
||||
|
||||
AcknowledgeTypes? acknowledgeType = null;
|
||||
public AcknowledgeTypes? AcknowledgeType
|
||||
{
|
||||
get { return this.acknowledgeType; }
|
||||
set { this.acknowledgeType = value; }
|
||||
}
|
||||
|
||||
Acknowledgment? acknowledgment = null;
|
||||
public Acknowledgment? Acknowledgment
|
||||
{
|
||||
get { return this.acknowledgment; }
|
||||
internal set { this.acknowledgment = value; }
|
||||
}
|
||||
|
||||
Uri administrationQueue = null;
|
||||
public Uri AdministrationQueue
|
||||
{
|
||||
get { return this.administrationQueue; }
|
||||
set { this.administrationQueue = value; }
|
||||
}
|
||||
|
||||
int? appSpecific = null;
|
||||
public int? AppSpecific
|
||||
{
|
||||
get { return this.appSpecific; }
|
||||
set { this.appSpecific = value; }
|
||||
}
|
||||
|
||||
DateTime? arrivedTime = null;
|
||||
public DateTime? ArrivedTime
|
||||
{
|
||||
get { return this.arrivedTime; }
|
||||
internal set { this.arrivedTime = value; }
|
||||
}
|
||||
|
||||
bool? authenticated = null;
|
||||
public bool? Authenticated
|
||||
{
|
||||
get { return this.authenticated; }
|
||||
internal set { this.authenticated = value; }
|
||||
}
|
||||
|
||||
int? bodyType = null;
|
||||
public int? BodyType
|
||||
{
|
||||
get { return this.bodyType; }
|
||||
set { this.bodyType = value; }
|
||||
}
|
||||
|
||||
string correlationId = null;
|
||||
public string CorrelationId
|
||||
{
|
||||
get { return this.correlationId; }
|
||||
set { this.correlationId = value; }
|
||||
}
|
||||
|
||||
Uri destinationQueue = null;
|
||||
public Uri DestinationQueue
|
||||
{
|
||||
get { return this.destinationQueue; }
|
||||
internal set { this.destinationQueue = value; }
|
||||
}
|
||||
|
||||
byte[] extension = null;
|
||||
public byte[] Extension
|
||||
{
|
||||
get { return this.extension; }
|
||||
set { this.extension = value; }
|
||||
}
|
||||
|
||||
string id = null;
|
||||
public string Id
|
||||
{
|
||||
get { return this.id; }
|
||||
internal set { this.id = value; }
|
||||
}
|
||||
|
||||
string label = null;
|
||||
public string Label
|
||||
{
|
||||
get { return this.label; }
|
||||
set { this.label = value; }
|
||||
}
|
||||
|
||||
MessageType? messageType = null;
|
||||
public MessageType? MessageType
|
||||
{
|
||||
get { return this.messageType; }
|
||||
internal set { this.messageType = value; }
|
||||
}
|
||||
|
||||
MessagePriority? priority = null;
|
||||
public MessagePriority? Priority
|
||||
{
|
||||
get { return this.priority; }
|
||||
set
|
||||
{
|
||||
ValidateMessagePriority(value);
|
||||
this.priority = value;
|
||||
}
|
||||
}
|
||||
|
||||
Uri responseQueue = null;
|
||||
public Uri ResponseQueue
|
||||
{
|
||||
get { return this.responseQueue; }
|
||||
set { this.responseQueue = value; }
|
||||
}
|
||||
|
||||
byte[] senderId = null;
|
||||
public byte[] SenderId
|
||||
{
|
||||
get { return this.senderId; }
|
||||
internal set { this.senderId = value; }
|
||||
}
|
||||
|
||||
DateTime? sentTime = null;
|
||||
public DateTime? SentTime
|
||||
{
|
||||
get { return this.sentTime; }
|
||||
internal set { this.sentTime = value; }
|
||||
}
|
||||
|
||||
TimeSpan? timeToReachQueue = null;
|
||||
public TimeSpan? TimeToReachQueue
|
||||
{
|
||||
get { return this.timeToReachQueue; }
|
||||
set
|
||||
{
|
||||
ValidateTimeToReachQueue(value);
|
||||
this.timeToReachQueue = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal void InternalSetTimeToReachQueue(TimeSpan timeout)
|
||||
{
|
||||
this.timeToReachQueue = timeout;
|
||||
}
|
||||
|
||||
static void ValidateMessagePriority(MessagePriority? priority)
|
||||
{
|
||||
if (priority.HasValue && (priority.Value < MessagePriority.Lowest || priority.Value > MessagePriority.Highest))
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("priority", (int)priority, typeof(MessagePriority)));
|
||||
}
|
||||
|
||||
static void ValidateTimeToReachQueue(TimeSpan? timeout)
|
||||
{
|
||||
if (timeout.HasValue && timeout.Value < TimeSpan.Zero)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", timeout,
|
||||
SR.GetString(SR.SFxTimeoutOutOfRange0)));
|
||||
}
|
||||
|
||||
if (timeout.HasValue && TimeoutHelper.IsTooLarge(timeout.Value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", timeout,
|
||||
SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,292 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.IO;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Diagnostics;
|
||||
using System.ServiceModel.Security.Tokens;
|
||||
|
||||
sealed class MsmqIntegrationOutputChannel : TransportOutputChannel
|
||||
{
|
||||
MsmqQueue msmqQueue;
|
||||
MsmqTransactionMode transactionMode;
|
||||
MsmqIntegrationChannelFactory factory;
|
||||
SecurityTokenProviderContainer certificateTokenProvider;
|
||||
|
||||
public MsmqIntegrationOutputChannel(MsmqIntegrationChannelFactory factory, EndpointAddress to, Uri via, bool manualAddressing)
|
||||
: base(factory, to, via, manualAddressing, factory.MessageVersion)
|
||||
{
|
||||
this.factory = factory;
|
||||
if (factory.IsMsmqX509SecurityConfigured)
|
||||
{
|
||||
this.certificateTokenProvider = factory.CreateX509TokenProvider(to, via);
|
||||
}
|
||||
}
|
||||
|
||||
void CloseQueue()
|
||||
{
|
||||
if (null != this.msmqQueue)
|
||||
this.msmqQueue.Dispose();
|
||||
this.msmqQueue = null;
|
||||
}
|
||||
|
||||
void OnCloseCore(bool isAborting, TimeSpan timeout)
|
||||
{
|
||||
this.CloseQueue();
|
||||
if (this.certificateTokenProvider != null)
|
||||
{
|
||||
if (isAborting)
|
||||
this.certificateTokenProvider.Abort();
|
||||
else
|
||||
this.certificateTokenProvider.Close(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAbort()
|
||||
{
|
||||
this.OnCloseCore(true, TimeSpan.Zero);
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
this.OnCloseCore(false, timeout);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected override void OnEndClose(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected override void OnClose(TimeSpan timeout)
|
||||
{
|
||||
this.OnCloseCore(false, timeout);
|
||||
}
|
||||
|
||||
void OpenQueue()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.msmqQueue = new MsmqQueue(this.factory.AddressTranslator.UriToFormatName(this.RemoteAddress.Uri), UnsafeNativeMethods.MQ_SEND_ACCESS);
|
||||
}
|
||||
catch (MsmqException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex.Normalized);
|
||||
}
|
||||
if (this.factory.ExactlyOnce)
|
||||
{
|
||||
this.transactionMode = MsmqTransactionMode.CurrentOrSingle;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.transactionMode = MsmqTransactionMode.None;
|
||||
}
|
||||
}
|
||||
|
||||
void OnOpenCore(TimeSpan timeout)
|
||||
{
|
||||
OpenQueue();
|
||||
if (this.certificateTokenProvider != null)
|
||||
{
|
||||
this.certificateTokenProvider.Open(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
OnOpenCore(timeout);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected override void OnEndOpen(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected override void OnOpen(TimeSpan timeout)
|
||||
{
|
||||
OnOpenCore(timeout);
|
||||
}
|
||||
|
||||
protected override IAsyncResult OnBeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
|
||||
{
|
||||
OnSend(message, timeout);
|
||||
return new CompletedAsyncResult(callback, state);
|
||||
}
|
||||
|
||||
protected override void OnEndSend(IAsyncResult result)
|
||||
{
|
||||
CompletedAsyncResult.End(result);
|
||||
}
|
||||
|
||||
protected override void OnSend(Message message, TimeSpan timeout)
|
||||
{
|
||||
MessageProperties properties = message.Properties;
|
||||
Stream stream = null;
|
||||
|
||||
MsmqIntegrationMessageProperty property = MsmqIntegrationMessageProperty.Get(message);
|
||||
if (null == property)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString(SR.MsmqMessageDoesntHaveIntegrationProperty)));
|
||||
if (null != property.Body)
|
||||
stream = this.factory.Serialize(property);
|
||||
|
||||
int size;
|
||||
if (stream == null)
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stream.Length > int.MaxValue)
|
||||
{
|
||||
throw TraceUtility.ThrowHelperError(new ProtocolException(SR.GetString(SR.MessageSizeMustBeInIntegerRange)), message);
|
||||
}
|
||||
|
||||
size = (int)stream.Length;
|
||||
}
|
||||
|
||||
using (MsmqIntegrationOutputMessage msmqMessage = new MsmqIntegrationOutputMessage(this.factory, size, this.RemoteAddress, property))
|
||||
{
|
||||
msmqMessage.ApplyCertificateIfNeeded(this.certificateTokenProvider, this.factory.MsmqTransportSecurity.MsmqAuthenticationMode, timeout);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
stream.Position = 0;
|
||||
for (int bytesRemaining = size; bytesRemaining > 0; )
|
||||
{
|
||||
int bytesRead = stream.Read(msmqMessage.Body.Buffer, 0, bytesRemaining);
|
||||
bytesRemaining -= bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
bool lockHeld = false;
|
||||
try
|
||||
{
|
||||
Msmq.EnterXPSendLock(out lockHeld, this.factory.MsmqTransportSecurity.MsmqProtectionLevel);
|
||||
this.msmqQueue.Send(msmqMessage, this.transactionMode);
|
||||
MsmqDiagnostics.DatagramSent(msmqMessage.MessageId, message);
|
||||
property.Id = MsmqMessageId.ToString(msmqMessage.MessageId.Buffer);
|
||||
}
|
||||
catch (MsmqException ex)
|
||||
{
|
||||
if (ex.FaultSender)
|
||||
this.Fault();
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex.Normalized);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockHeld)
|
||||
{
|
||||
Msmq.LeaveXPSendLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class MsmqIntegrationOutputMessage : MsmqOutputMessage<IOutputChannel>
|
||||
{
|
||||
ByteProperty acknowledge;
|
||||
StringProperty adminQueue;
|
||||
IntProperty appSpecific;
|
||||
BufferProperty correlationId;
|
||||
BufferProperty extension;
|
||||
StringProperty label;
|
||||
ByteProperty priority;
|
||||
StringProperty responseQueue;
|
||||
|
||||
|
||||
public MsmqIntegrationOutputMessage(
|
||||
MsmqChannelFactoryBase<IOutputChannel> factory,
|
||||
int bodySize,
|
||||
EndpointAddress remoteAddress,
|
||||
MsmqIntegrationMessageProperty property)
|
||||
: base(factory, bodySize, remoteAddress, 8)
|
||||
{
|
||||
if (null == property)
|
||||
{
|
||||
Fx.Assert("MsmqIntegrationMessageProperty expected");
|
||||
}
|
||||
|
||||
if (property.AcknowledgeType.HasValue)
|
||||
EnsureAcknowledgeProperty((byte)property.AcknowledgeType.Value);
|
||||
|
||||
if (null != property.AdministrationQueue)
|
||||
EnsureAdminQueueProperty(property.AdministrationQueue, false);
|
||||
|
||||
if (property.AppSpecific.HasValue)
|
||||
this.appSpecific = new IntProperty(this, UnsafeNativeMethods.PROPID_M_APPSPECIFIC, property.AppSpecific.Value);
|
||||
|
||||
if (property.BodyType.HasValue)
|
||||
EnsureBodyTypeProperty(property.BodyType.Value);
|
||||
|
||||
if (null != property.CorrelationId)
|
||||
this.correlationId = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_CORRELATIONID, MsmqMessageId.FromString(property.CorrelationId));
|
||||
|
||||
if (null != property.Extension)
|
||||
this.extension = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_EXTENSION, property.Extension);
|
||||
|
||||
if (null != property.Label)
|
||||
this.label = new StringProperty(this, UnsafeNativeMethods.PROPID_M_LABEL, property.Label);
|
||||
|
||||
if (property.Priority.HasValue)
|
||||
this.priority = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_PRIORITY, (byte)property.Priority.Value);
|
||||
|
||||
if (null != property.ResponseQueue)
|
||||
EnsureResponseQueueProperty(property.ResponseQueue);
|
||||
|
||||
if (property.TimeToReachQueue.HasValue)
|
||||
EnsureTimeToReachQueueProperty(MsmqDuration.FromTimeSpan(property.TimeToReachQueue.Value));
|
||||
}
|
||||
|
||||
void EnsureAcknowledgeProperty(byte value)
|
||||
{
|
||||
if (this.acknowledge == null)
|
||||
{
|
||||
this.acknowledge = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_ACKNOWLEDGE);
|
||||
}
|
||||
this.acknowledge.Value = value;
|
||||
}
|
||||
|
||||
void EnsureAdminQueueProperty(Uri value, bool useNetMsmqTranslator)
|
||||
{
|
||||
if (null != value)
|
||||
{
|
||||
string queueName = useNetMsmqTranslator ?
|
||||
MsmqUri.NetMsmqAddressTranslator.UriToFormatName(value) :
|
||||
MsmqUri.FormatNameAddressTranslator.UriToFormatName(value);
|
||||
|
||||
if (this.adminQueue == null)
|
||||
{
|
||||
this.adminQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_ADMIN_QUEUE, queueName);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.adminQueue.SetValue(queueName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnsureResponseQueueProperty(Uri value)
|
||||
{
|
||||
if (null != value)
|
||||
{
|
||||
string queueName = MsmqUri.FormatNameAddressTranslator.UriToFormatName(value);
|
||||
if (this.responseQueue == null)
|
||||
{
|
||||
this.responseQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_RESP_FORMAT_NAME, queueName);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.responseQueue.SetValue(queueName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,40 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
sealed class MsmqIntegrationReceiveParameters
|
||||
: MsmqReceiveParameters
|
||||
{
|
||||
MsmqMessageSerializationFormat serializationFormat;
|
||||
Type[] targetSerializationTypes;
|
||||
|
||||
internal MsmqIntegrationReceiveParameters(MsmqIntegrationBindingElement bindingElement)
|
||||
: base(bindingElement)
|
||||
{
|
||||
this.serializationFormat = bindingElement.SerializationFormat;
|
||||
|
||||
List<Type> knownTypes = new List<Type>();
|
||||
if (null != bindingElement.TargetSerializationTypes)
|
||||
{
|
||||
foreach (Type type in bindingElement.TargetSerializationTypes)
|
||||
if (! knownTypes.Contains(type))
|
||||
knownTypes.Add(type);
|
||||
}
|
||||
this.targetSerializationTypes = knownTypes.ToArray();
|
||||
}
|
||||
|
||||
internal MsmqMessageSerializationFormat SerializationFormat
|
||||
{
|
||||
get { return this.serializationFormat; }
|
||||
}
|
||||
|
||||
internal Type[] TargetSerializationTypes
|
||||
{
|
||||
get { return this.targetSerializationTypes; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Net.Security;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
public sealed class MsmqIntegrationSecurity
|
||||
{
|
||||
internal const MsmqIntegrationSecurityMode DefaultMode = MsmqIntegrationSecurityMode.Transport;
|
||||
|
||||
MsmqIntegrationSecurityMode mode;
|
||||
MsmqTransportSecurity transportSecurity;
|
||||
|
||||
public MsmqIntegrationSecurity()
|
||||
{
|
||||
this.mode = DefaultMode;
|
||||
this.transportSecurity = new MsmqTransportSecurity();
|
||||
}
|
||||
|
||||
[DefaultValue(MsmqIntegrationSecurity.DefaultMode)]
|
||||
public MsmqIntegrationSecurityMode Mode
|
||||
{
|
||||
get { return this.mode; }
|
||||
set
|
||||
{
|
||||
if (!MsmqIntegrationSecurityModeHelper.IsDefined(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
|
||||
}
|
||||
this.mode = value;
|
||||
}
|
||||
}
|
||||
|
||||
public MsmqTransportSecurity Transport
|
||||
{
|
||||
get { return this.transportSecurity; }
|
||||
set { this.transportSecurity = value; }
|
||||
}
|
||||
|
||||
internal void ConfigureTransportSecurity(MsmqBindingElementBase msmq)
|
||||
{
|
||||
if (this.mode == MsmqIntegrationSecurityMode.Transport)
|
||||
msmq.MsmqTransportSecurity = this.Transport;
|
||||
else
|
||||
msmq.MsmqTransportSecurity.Disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,22 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
public enum MsmqIntegrationSecurityMode
|
||||
{
|
||||
None,
|
||||
Transport
|
||||
}
|
||||
|
||||
static class MsmqIntegrationSecurityModeHelper
|
||||
{
|
||||
internal static bool IsDefined(MsmqIntegrationSecurityMode value)
|
||||
{
|
||||
return (value == MsmqIntegrationSecurityMode.Transport
|
||||
|| value == MsmqIntegrationSecurityMode.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,116 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
using System.ServiceModel.Description;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class MsmqIntegrationValidationBehavior : IEndpointBehavior, IServiceBehavior
|
||||
{
|
||||
static MsmqIntegrationValidationBehavior instance;
|
||||
|
||||
internal static MsmqIntegrationValidationBehavior Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
instance = new MsmqIntegrationValidationBehavior();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
MsmqIntegrationValidationBehavior() { }
|
||||
|
||||
void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint)
|
||||
{
|
||||
if (serviceEndpoint == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceEndpoint");
|
||||
|
||||
ContractDescription contract = serviceEndpoint.Contract;
|
||||
Binding binding = serviceEndpoint.Binding;
|
||||
if (NeedValidateBinding(binding))
|
||||
{
|
||||
ValidateHelper(contract, binding, null);
|
||||
}
|
||||
}
|
||||
|
||||
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters)
|
||||
{
|
||||
}
|
||||
|
||||
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
|
||||
{
|
||||
}
|
||||
|
||||
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
|
||||
{
|
||||
}
|
||||
|
||||
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
|
||||
{
|
||||
}
|
||||
|
||||
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
|
||||
{
|
||||
if (description == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description");
|
||||
|
||||
for (int i = 0; i < description.Endpoints.Count; i++)
|
||||
{
|
||||
ServiceEndpoint endpoint = description.Endpoints[i];
|
||||
if (NeedValidateBinding(endpoint.Binding))
|
||||
{
|
||||
ValidateHelper(endpoint.Contract, endpoint.Binding, description);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NeedValidateBinding(Binding binding)
|
||||
{
|
||||
if (binding is MsmqIntegrationBinding)
|
||||
return true;
|
||||
|
||||
if (binding is CustomBinding)
|
||||
{
|
||||
CustomBinding customBinding = new CustomBinding(binding);
|
||||
return (customBinding.Elements.Find<MsmqIntegrationBindingElement>() != null);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ValidateHelper(ContractDescription contract, Binding binding, ServiceDescription description)
|
||||
{
|
||||
foreach (OperationDescription operation in contract.Operations)
|
||||
{
|
||||
// since this is one-way, we can only have one message (one-way requirement is validated elsewhere)
|
||||
MessageDescription message = operation.Messages[0];
|
||||
|
||||
if ((message.Body.Parts.Count == 0) && (message.Headers.Count == 0))
|
||||
// all message parts are properties, great
|
||||
continue;
|
||||
|
||||
if (message.Body.Parts.Count == 1) // Single MsmqMessage<> argument is also legal
|
||||
{
|
||||
Type type = message.Body.Parts[0].Type;
|
||||
if (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(MsmqMessage<>)))
|
||||
continue;
|
||||
}
|
||||
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
|
||||
SR.GetString(SR.MsmqInvalidServiceOperationForMsmqIntegrationBinding, binding.Name, operation.Name, contract.Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,138 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
using System.Messaging;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Channels;
|
||||
|
||||
[MessageContract(IsWrapped = false)]
|
||||
public sealed class MsmqMessage<T>
|
||||
{
|
||||
[MessageProperty(Name = MsmqIntegrationMessageProperty.Name)]
|
||||
MsmqIntegrationMessageProperty property;
|
||||
|
||||
public MsmqMessage(T body)
|
||||
{
|
||||
if (body == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("body");
|
||||
this.property = new MsmqIntegrationMessageProperty();
|
||||
this.property.Body = body;
|
||||
}
|
||||
|
||||
internal MsmqMessage()
|
||||
{ }
|
||||
|
||||
public T Body
|
||||
{
|
||||
get { return (T)this.property.Body; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
|
||||
this.property.Body = value;
|
||||
}
|
||||
}
|
||||
|
||||
public AcknowledgeTypes? AcknowledgeType
|
||||
{
|
||||
get { return this.property.AcknowledgeType; }
|
||||
set { this.property.AcknowledgeType = value; }
|
||||
}
|
||||
|
||||
public Acknowledgment? Acknowledgment
|
||||
{
|
||||
get { return this.property.Acknowledgment; }
|
||||
}
|
||||
|
||||
public Uri AdministrationQueue
|
||||
{
|
||||
get { return this.property.AdministrationQueue; }
|
||||
set { this.property.AdministrationQueue = value; }
|
||||
}
|
||||
|
||||
public int? AppSpecific
|
||||
{
|
||||
get { return this.property.AppSpecific; }
|
||||
set { this.property.AppSpecific = value; }
|
||||
}
|
||||
|
||||
public DateTime? ArrivedTime
|
||||
{
|
||||
get { return this.property.ArrivedTime; }
|
||||
}
|
||||
|
||||
public bool? Authenticated
|
||||
{
|
||||
get { return this.property.Authenticated; }
|
||||
}
|
||||
|
||||
public int? BodyType
|
||||
{
|
||||
get { return this.property.BodyType; }
|
||||
set { this.property.BodyType = value; }
|
||||
}
|
||||
|
||||
public string CorrelationId
|
||||
{
|
||||
get { return this.property.CorrelationId; }
|
||||
set { this.property.CorrelationId = value; }
|
||||
}
|
||||
|
||||
public Uri DestinationQueue
|
||||
{
|
||||
get { return this.property.DestinationQueue; }
|
||||
}
|
||||
|
||||
public byte[] Extension
|
||||
{
|
||||
get { return this.property.Extension; }
|
||||
set { this.property.Extension = value; }
|
||||
}
|
||||
|
||||
public string Id
|
||||
{
|
||||
get { return this.property.Id; }
|
||||
}
|
||||
|
||||
public string Label
|
||||
{
|
||||
get { return this.property.Label; }
|
||||
set { this.property.Label = value; }
|
||||
}
|
||||
|
||||
public MessageType? MessageType
|
||||
{
|
||||
get { return this.property.MessageType; }
|
||||
}
|
||||
|
||||
public MessagePriority? Priority
|
||||
{
|
||||
get { return this.property.Priority; }
|
||||
set { this.property.Priority = value; }
|
||||
}
|
||||
|
||||
public Uri ResponseQueue
|
||||
{
|
||||
get { return this.property.ResponseQueue; }
|
||||
set { this.property.ResponseQueue = value; }
|
||||
}
|
||||
|
||||
public byte[] SenderId
|
||||
{
|
||||
get { return this.property.SenderId; }
|
||||
}
|
||||
|
||||
public DateTime? SentTime
|
||||
{
|
||||
get { return this.property.SentTime; }
|
||||
}
|
||||
|
||||
public TimeSpan? TimeToReachQueue
|
||||
{
|
||||
get { return this.property.TimeToReachQueue; }
|
||||
set { this.property.TimeToReachQueue = value; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.MsmqIntegration
|
||||
{
|
||||
public enum MsmqMessageSerializationFormat
|
||||
{
|
||||
Xml,
|
||||
Binary,
|
||||
ActiveX,
|
||||
ByteArray,
|
||||
Stream
|
||||
}
|
||||
|
||||
static class MsmqMessageSerializationFormatHelper
|
||||
{
|
||||
internal static bool IsDefined(MsmqMessageSerializationFormat value)
|
||||
{
|
||||
return
|
||||
value == MsmqMessageSerializationFormat.ActiveX ||
|
||||
value == MsmqMessageSerializationFormat.Binary ||
|
||||
value == MsmqMessageSerializationFormat.ByteArray ||
|
||||
value == MsmqMessageSerializationFormat.Stream ||
|
||||
value == MsmqMessageSerializationFormat.Xml;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user