e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
277 lines
11 KiB
C#
277 lines
11 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="SoapMessage.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.Web.Services.Protocols {
|
|
using System.Web.Services;
|
|
using System.Xml.Serialization;
|
|
using System;
|
|
using System.Reflection;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.ComponentModel;
|
|
using System.Security.Permissions;
|
|
using System.Runtime.InteropServices;
|
|
using System.Diagnostics;
|
|
using System.Web.Services.Diagnostics;
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
|
|
public abstract class SoapMessage {
|
|
SoapMessageStage stage;
|
|
SoapHeaderCollection headers = new SoapHeaderCollection();
|
|
Stream stream;
|
|
SoapExtensionStream extensionStream;
|
|
string contentType;
|
|
string contentEncoding;
|
|
object[] parameterValues;
|
|
SoapException exception;
|
|
|
|
internal SoapMessage() { }
|
|
|
|
internal void SetParameterValues(object[] parameterValues) {
|
|
this.parameterValues = parameterValues;
|
|
}
|
|
|
|
internal object[] GetParameterValues() {
|
|
return parameterValues;
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.OneWay"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public abstract bool OneWay {
|
|
get;
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.GetInParameterValue"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public object GetInParameterValue(int index) {
|
|
EnsureInStage();
|
|
EnsureNoException();
|
|
if (index < 0 || index >= parameterValues.Length) throw new IndexOutOfRangeException(Res.GetString(Res.indexMustBeBetweenAnd0Inclusive, parameterValues.Length));
|
|
return parameterValues[index];
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.GetOutParameterValue"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public object GetOutParameterValue(int index) {
|
|
EnsureOutStage();
|
|
EnsureNoException();
|
|
if (!MethodInfo.IsVoid) {
|
|
if (index == int.MaxValue)
|
|
throw new IndexOutOfRangeException(Res.GetString(Res.indexMustBeBetweenAnd0Inclusive, parameterValues.Length));
|
|
index++;
|
|
}
|
|
if (index < 0 || index >= parameterValues.Length) throw new IndexOutOfRangeException(Res.GetString(Res.indexMustBeBetweenAnd0Inclusive, parameterValues.Length));
|
|
return parameterValues[index];
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.GetReturnValue"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public object GetReturnValue() {
|
|
EnsureOutStage();
|
|
EnsureNoException();
|
|
if (MethodInfo.IsVoid) throw new InvalidOperationException(Res.GetString(Res.WebNoReturnValue));
|
|
return parameterValues[0];
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.EnsureOutStage"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
protected abstract void EnsureOutStage();
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.EnsureInStage"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
protected abstract void EnsureInStage();
|
|
|
|
void EnsureNoException() {
|
|
if (exception != null) throw new InvalidOperationException(Res.GetString(Res.WebCannotAccessValue), exception);
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.Exception"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapException Exception {
|
|
get { return exception; }
|
|
set { exception = value; }
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.MethodInfo"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public abstract LogicalMethodInfo MethodInfo {
|
|
get;
|
|
}
|
|
|
|
/*
|
|
internal abstract SoapReflectedExtension[] Extensions {
|
|
get;
|
|
}
|
|
|
|
internal abstract object[] ExtensionInitializers {
|
|
get;
|
|
}
|
|
*/
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.EnsureStage"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
protected void EnsureStage(SoapMessageStage stage) {
|
|
if ((this.stage & stage) == 0) throw new InvalidOperationException(Res.GetString(Res.WebCannotAccessValueStage, this.stage.ToString()));
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.Headers"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapHeaderCollection Headers {
|
|
get { return headers; }
|
|
}
|
|
|
|
internal void SetStream(Stream stream) {
|
|
if (extensionStream != null) {
|
|
extensionStream.SetInnerStream(stream);
|
|
extensionStream.SetStreamReady();
|
|
// The extension stream should now be referenced by either this.stream
|
|
// or an extension that has chained it to another stream.
|
|
extensionStream = null;
|
|
}
|
|
else
|
|
this.stream = stream;
|
|
}
|
|
|
|
internal void SetExtensionStream(SoapExtensionStream extensionStream) {
|
|
this.extensionStream = extensionStream;
|
|
this.stream = extensionStream;
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.Stream"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public Stream Stream {
|
|
get { return stream; }
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.ContentType"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public string ContentType {
|
|
get { EnsureStage(SoapMessageStage.BeforeSerialize | SoapMessageStage.BeforeDeserialize); return contentType; }
|
|
set { EnsureStage(SoapMessageStage.BeforeSerialize | SoapMessageStage.BeforeDeserialize); contentType = value; }
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.ContentEncoding"]/*' />
|
|
public string ContentEncoding {
|
|
get { EnsureStage(SoapMessageStage.BeforeSerialize | SoapMessageStage.BeforeDeserialize); return contentEncoding; }
|
|
set { EnsureStage(SoapMessageStage.BeforeSerialize | SoapMessageStage.BeforeDeserialize); contentEncoding = value; }
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.Stage"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public SoapMessageStage Stage {
|
|
get { return stage; }
|
|
}
|
|
|
|
internal void SetStage(SoapMessageStage stage) {
|
|
this.stage = stage;
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.Url"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public abstract string Url {
|
|
get;
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.Action"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public abstract string Action {
|
|
get;
|
|
}
|
|
|
|
/// <include file='doc\SoapMessage.uex' path='docs/doc[@for="SoapMessage.SoapVersion"]/*' />
|
|
[ComVisible(false)]
|
|
[DefaultValue(SoapProtocolVersion.Default)]
|
|
public virtual SoapProtocolVersion SoapVersion {
|
|
get { return SoapProtocolVersion.Default; }
|
|
}
|
|
|
|
internal static SoapExtension[] InitializeExtensions(SoapReflectedExtension[] reflectedExtensions, object[] extensionInitializers) {
|
|
if (reflectedExtensions == null)
|
|
return null;
|
|
SoapExtension[] extensions = new SoapExtension[reflectedExtensions.Length];
|
|
for (int i = 0; i < extensions.Length; i++) {
|
|
extensions[i] = reflectedExtensions[i].CreateInstance(extensionInitializers[i]);
|
|
}
|
|
return extensions;
|
|
}
|
|
|
|
internal void InitExtensionStreamChain(SoapExtension[] extensions) {
|
|
if (extensions == null)
|
|
return;
|
|
for (int i = 0; i < extensions.Length; i++) {
|
|
stream = extensions[i].ChainStream(stream);
|
|
}
|
|
}
|
|
|
|
internal void RunExtensions(SoapExtension[] extensions, bool throwOnException) {
|
|
if (extensions == null)
|
|
return;
|
|
|
|
TraceMethod caller = Tracing.On ? new TraceMethod(this, "RunExtensions", extensions, throwOnException) : null;
|
|
|
|
// Higher priority extensions (earlier in the list) run earlier for deserialization stages,
|
|
// and later for serialization stages
|
|
if ((stage & (SoapMessageStage.BeforeDeserialize | SoapMessageStage.AfterDeserialize)) != 0) {
|
|
for (int i = 0; i < extensions.Length; i++) {
|
|
if (Tracing.On) Tracing.Enter("SoapExtension", caller, new TraceMethod(extensions[i], "ProcessMessage", stage));
|
|
extensions[i].ProcessMessage(this);
|
|
if (Tracing.On) Tracing.Exit("SoapExtension", caller);
|
|
if (Exception != null) {
|
|
if (throwOnException)
|
|
throw Exception;
|
|
if (Tracing.On) Tracing.ExceptionIgnore(TraceEventType.Warning, caller, Exception);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (int i = extensions.Length - 1; i >= 0; i--) {
|
|
if (Tracing.On) Tracing.Enter("SoapExtension", caller, new TraceMethod(extensions[i], "ProcessMessage", stage));
|
|
extensions[i].ProcessMessage(this);
|
|
if (Tracing.On) Tracing.Exit("SoapExtension", caller);
|
|
if (Exception != null) {
|
|
if (throwOnException)
|
|
throw Exception;
|
|
if (Tracing.On) Tracing.ExceptionIgnore(TraceEventType.Warning, caller, Exception);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|