a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
325 lines
11 KiB
C#
325 lines
11 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Runtime.Serialization;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Description;
|
|
using System.ServiceModel.Dispatcher;
|
|
using System.ServiceModel.Web;
|
|
using System.Text;
|
|
using NUnit.Framework;
|
|
|
|
namespace MonoTests.System.ServiceModel.Description
|
|
{
|
|
public class WebHttpBehaviorExt : WebHttpBehavior
|
|
{
|
|
public IClientMessageFormatter DoGetReplyClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
|
|
{
|
|
return GetReplyClientFormatter (operationDescription, endpoint);
|
|
}
|
|
|
|
public IClientMessageFormatter DoGetRequestClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
|
|
{
|
|
return GetRequestClientFormatter (operationDescription, endpoint);
|
|
}
|
|
#if !MOBILE
|
|
public IDispatchMessageFormatter DoGetReplyDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
|
|
{
|
|
return GetReplyDispatchFormatter (operationDescription, endpoint);
|
|
}
|
|
|
|
public IDispatchMessageFormatter DoGetRequestDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
|
|
{
|
|
return GetRequestDispatchFormatter (operationDescription, endpoint);
|
|
}
|
|
#endif
|
|
public event Action<ServiceEndpoint, ClientRuntime> ApplyClientBehaviorInvoked;
|
|
|
|
public override void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime client)
|
|
{
|
|
base.ApplyClientBehavior (endpoint, client);
|
|
if (ApplyClientBehaviorInvoked != null)
|
|
ApplyClientBehaviorInvoked (endpoint, client);
|
|
}
|
|
}
|
|
|
|
[TestFixture]
|
|
public class WebHttpBehaviorTest
|
|
{
|
|
ServiceEndpoint CreateEndpoint ()
|
|
{
|
|
return new ServiceEndpoint (ContractDescription.GetContract (typeof (IMyService)), new WebHttpBinding (),
|
|
new EndpointAddress ("http://localhost:37564"));
|
|
}
|
|
|
|
[Test]
|
|
public void DefaultValues ()
|
|
{
|
|
var b = new WebHttpBehavior ();
|
|
Assert.AreEqual (WebMessageBodyStyle.Bare, b.DefaultBodyStyle, "#1");
|
|
Assert.AreEqual (WebMessageFormat.Xml, b.DefaultOutgoingRequestFormat, "#2");
|
|
Assert.AreEqual (WebMessageFormat.Xml, b.DefaultOutgoingResponseFormat, "#3");
|
|
#if NET_4_0
|
|
Assert.IsFalse (b.AutomaticFormatSelectionEnabled, "#11");
|
|
Assert.IsFalse (b.FaultExceptionEnabled, "#12");
|
|
Assert.IsFalse (b.HelpEnabled, "#13");
|
|
#endif
|
|
}
|
|
|
|
[Test]
|
|
public void AddBiningParameters ()
|
|
{
|
|
var se = CreateEndpoint ();
|
|
var b = new WebHttpBehavior ();
|
|
var pl = new BindingParameterCollection ();
|
|
b.AddBindingParameters (se, pl);
|
|
Assert.AreEqual (0, pl.Count, "#1");
|
|
}
|
|
|
|
#if !MOBILE
|
|
[Test]
|
|
public void ApplyDispatchBehavior ()
|
|
{
|
|
var se = CreateEndpoint ();
|
|
var od = se.Contract.Operations [0];
|
|
// in .NET 3.5 it adds "OperationSelectorBehavior"
|
|
int initCB = ContractDescription.GetContract (typeof (IMyService)).Behaviors.Count;
|
|
// in .NET 3.5 it adds
|
|
// - OperationInvokeBehavior,
|
|
// - OperationBehaviorAttribute,
|
|
// - DataContractSerializerOperationBehavior and
|
|
// - DataContractSerializerOperationGenerator
|
|
int initOB = od.Behaviors.Count;
|
|
// Assert.AreEqual (1, initCB, "#0-1");
|
|
// Assert.AreEqual (4, initOB, "#0-2");
|
|
|
|
var b = new WebHttpBehavior ();
|
|
se.Behaviors.Add (b);
|
|
var ed = new EndpointDispatcher (se.Address, se.Contract.Name, se.Contract.Namespace);
|
|
IChannelListener l = new WebHttpBinding ().BuildChannelListener<IReplyChannel> (new BindingParameterCollection ());
|
|
var cd = new ChannelDispatcher (l);
|
|
cd.Endpoints.Add (ed); // without it this test results in NRE (it blindly adds IErrorHandler).
|
|
Assert.AreEqual (0, cd.ErrorHandlers.Count, "#1-1");
|
|
Assert.IsNull (ed.DispatchRuntime.OperationSelector, "#1-2");
|
|
Assert.AreEqual (1, se.Behaviors.Count, "#1-3-1");
|
|
Assert.AreEqual (initCB, se.Contract.Behaviors.Count, "#1-3-2");
|
|
Assert.AreEqual (initOB, od.Behaviors.Count, "#1-3-3");
|
|
|
|
Assert.IsTrue (ed.AddressFilter is EndpointAddressMessageFilter, "#1-4");
|
|
|
|
b.ApplyDispatchBehavior (se, ed);
|
|
// FIXME: implement and enable it later
|
|
//Assert.AreEqual (1, cd.ErrorHandlers.Count, "#2-1");
|
|
Assert.AreEqual (typeof (WebHttpDispatchOperationSelector),
|
|
ed.DispatchRuntime.OperationSelector.GetType (), "#2-2");
|
|
Assert.AreEqual (1, se.Behaviors.Count, "#3-1");
|
|
Assert.AreEqual (initCB, se.Contract.Behaviors.Count, "#3-2");
|
|
Assert.AreEqual (initOB, od.Behaviors.Count, "#3-3");
|
|
// ... i.e. nothing is added.
|
|
|
|
Assert.IsTrue (ed.AddressFilter is PrefixEndpointAddressMessageFilter, "#3-4");
|
|
|
|
Assert.AreEqual (0, ed.DispatchRuntime.Operations.Count, "#4-0"); // hmm... really?
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void GetMessageFormatters ()
|
|
{
|
|
var se = CreateEndpoint ();
|
|
var od = se.Contract.Operations [0];
|
|
var b = new WebHttpBehaviorExt ();
|
|
Assert.IsNotNull (b.DoGetRequestClientFormatter (od, se), "#1");
|
|
Assert.IsNotNull (b.DoGetReplyClientFormatter (od, se), "#2");
|
|
#if !MOBILE
|
|
Assert.IsNotNull (b.DoGetRequestDispatchFormatter (od, se), "#3");
|
|
Assert.IsNotNull (b.DoGetReplyDispatchFormatter (od, se), "#4");
|
|
#endif
|
|
}
|
|
|
|
[Test]
|
|
public void RequestClientFormatter ()
|
|
{
|
|
var se = CreateEndpoint ();
|
|
var od = se.Contract.Operations [0];
|
|
var b = new WebHttpBehaviorExt ();
|
|
var rcf = b.DoGetRequestClientFormatter (od, se);
|
|
var msg = rcf.SerializeRequest (MessageVersion.None, new object [] {"foo"});
|
|
var hp = msg.Properties [HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
|
|
Assert.IsNotNull (hp, "#1");
|
|
Assert.IsTrue (msg.IsEmpty, "#2");
|
|
Assert.AreEqual (String.Empty, hp.QueryString, "#3");
|
|
var mb = msg.CreateBufferedCopy (1000);
|
|
try {
|
|
rcf.DeserializeReply (mb.CreateMessage (), new object [0]);
|
|
Assert.Fail ("It should not support reply deserialization");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
}
|
|
|
|
#if !MOBILE
|
|
[Test]
|
|
public void RequestClientFormatter2 ()
|
|
{
|
|
var se = CreateEndpoint ();
|
|
var od = se.Contract.Operations [0];
|
|
var b = new WebHttpBehaviorExt ();
|
|
IClientMessageFormatter rcf = null;
|
|
b.ApplyClientBehaviorInvoked += delegate (ServiceEndpoint e, ClientRuntime cr) {
|
|
rcf = cr.Operations [0].Formatter;
|
|
};
|
|
se.Behaviors.Add (b);
|
|
var ch = new WebChannelFactory<IMyServiceClient> (se).CreateChannel ();
|
|
var msg = rcf.SerializeRequest (MessageVersion.None, new object [] {"foo"});
|
|
var hp = msg.Properties [HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
|
|
Assert.IsNotNull (hp, "#1");
|
|
Assert.IsTrue (msg.IsEmpty, "#2");
|
|
Assert.AreEqual (String.Empty, hp.QueryString, "#3");
|
|
//var mb = msg.CreateBufferedCopy (1000);
|
|
|
|
// TODO: test DeserializeReply too (it is supported unlike above).
|
|
}
|
|
#endif
|
|
|
|
[ServiceContract]
|
|
public interface IMyService
|
|
{
|
|
[OperationContract]
|
|
[WebGet]
|
|
string Echo (string input);
|
|
}
|
|
|
|
public interface IMyServiceClient : IMyService, IClientChannel
|
|
{
|
|
}
|
|
|
|
public class MyService: IMyService
|
|
{
|
|
#if !MOBILE
|
|
[OperationBehavior]
|
|
#endif
|
|
public string Echo (string input)
|
|
{
|
|
return input;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestWebGetExists()
|
|
{
|
|
ContractDescription cd = ContractDescription.GetContract (typeof(IMyService), typeof (MyService));
|
|
OperationDescription od = cd.Operations[0];
|
|
Assert.IsTrue (od.Behaviors.Contains (typeof (WebGetAttribute)), "Operation is recognized as WebGet");
|
|
}
|
|
|
|
#if !MOBILE
|
|
[Test]
|
|
public void MessageFormatterSupportsRaw ()
|
|
{
|
|
// serializing reply
|
|
var ms = new MemoryStream ();
|
|
var bytes = new byte [] {0, 1, 2, 0xFF};
|
|
ms.Write (bytes, 0, bytes.Length);
|
|
ms.Position = 0;
|
|
var cd = ContractDescription.GetContract (typeof (ITestService));
|
|
var od = cd.Operations [0];
|
|
var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:37564/"));
|
|
var formatter = new WebHttpBehaviorExt ().DoGetReplyDispatchFormatter (od, se);
|
|
|
|
var msg = formatter.SerializeReply (MessageVersion.None, null, ms);
|
|
var wp = msg.Properties ["WebBodyFormatMessageProperty"] as WebBodyFormatMessageProperty;
|
|
Assert.IsNotNull (wp, "#1");
|
|
Assert.AreEqual (WebContentFormat.Raw, wp.Format, "#2");
|
|
|
|
var wmebe = new WebMessageEncodingBindingElement ();
|
|
var wme = wmebe.CreateMessageEncoderFactory ().Encoder;
|
|
var ms2 = new MemoryStream ();
|
|
wme.WriteMessage (msg, ms2);
|
|
Assert.AreEqual (bytes, ms2.ToArray (), "#3");
|
|
}
|
|
|
|
[Test]
|
|
public void MessageFormatterSupportsRaw2 ()
|
|
{
|
|
// deserializing request
|
|
var ms = new MemoryStream ();
|
|
ms.Write (new byte [] {0, 1, 2, 0xFF}, 0, 4);
|
|
ms.Position = 0;
|
|
var cd = ContractDescription.GetContract (typeof (ITestService));
|
|
var od = cd.Operations [0];
|
|
var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
|
|
var wmebe = new WebMessageEncodingBindingElement ();
|
|
var wme = wmebe.CreateMessageEncoderFactory ().Encoder;
|
|
var msg = wme.ReadMessage (ms, 100, null); // "application/xml" causes error.
|
|
var formatter = new WebHttpBehaviorExt ().DoGetRequestDispatchFormatter (od, se);
|
|
object [] pars = new object [1];
|
|
formatter.DeserializeRequest (msg, pars);
|
|
Assert.IsTrue (pars [0] is Stream, "ret");
|
|
}
|
|
#endif
|
|
[ServiceContract]
|
|
public interface IMultipleParametersGet
|
|
{
|
|
[OperationContract]
|
|
[WebGet (UriTemplate = "get")]
|
|
void Get (string p1, string p2);
|
|
}
|
|
|
|
[ServiceContract]
|
|
public interface IMultipleParameters
|
|
{
|
|
[OperationContract]
|
|
[WebInvoke (UriTemplate = "posturi?p1={p1}&p2={p2}")]
|
|
string PostUri (string p1, string p2);
|
|
|
|
[OperationContract]
|
|
[WebInvoke (UriTemplate = "postone?p1={p1}")]
|
|
string PostOne (string p1, string p2);
|
|
|
|
[OperationContract]
|
|
[WebInvoke (UriTemplate = "postwrapped", BodyStyle=WebMessageBodyStyle.WrappedRequest)]
|
|
string PostWrapped (string p1, string p2);
|
|
|
|
[OperationContract]
|
|
[WebInvoke (UriTemplate = "out?p1={p1}&p2={p2}", BodyStyle=WebMessageBodyStyle.WrappedResponse)]
|
|
void PostOut (string p1, string p2, out string ret);
|
|
}
|
|
|
|
[Test]
|
|
public void MultipleParameters ()
|
|
{
|
|
var behavior = new WebHttpBehaviorExt ();
|
|
var cd = ContractDescription.GetContract (typeof (IMultipleParameters));
|
|
var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
|
|
behavior.Validate (se);
|
|
|
|
foreach (var od in cd.Operations)
|
|
behavior.DoGetRequestClientFormatter (od, se);
|
|
}
|
|
|
|
[Test]
|
|
[Category ("NotWorking")]
|
|
public void MultipleParameters2 ()
|
|
{
|
|
var behavior = new WebHttpBehaviorExt ();
|
|
var cd = ContractDescription.GetContract (typeof (IMultipleParametersGet));
|
|
var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
|
|
behavior.Validate (se);
|
|
|
|
try {
|
|
foreach (var od in cd.Operations)
|
|
behavior.DoGetRequestClientFormatter (od, se);
|
|
Assert.Fail ("Should result in invalid operation");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
}
|
|
}
|
|
|
|
[ServiceContract]
|
|
public interface ITestService
|
|
{
|
|
[OperationContract]
|
|
Stream Receive (Stream input);
|
|
}
|
|
}
|