WebHttpBehaviorTest.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. using System;
  2. using System.IO;
  3. using System.Runtime.Serialization;
  4. using System.ServiceModel;
  5. using System.ServiceModel.Channels;
  6. using System.ServiceModel.Description;
  7. using System.ServiceModel.Dispatcher;
  8. using System.ServiceModel.Web;
  9. using System.Text;
  10. using NUnit.Framework;
  11. namespace MonoTests.System.ServiceModel.Description
  12. {
  13. public class WebHttpBehaviorExt : WebHttpBehavior
  14. {
  15. public IClientMessageFormatter DoGetReplyClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
  16. {
  17. return GetReplyClientFormatter (operationDescription, endpoint);
  18. }
  19. public IClientMessageFormatter DoGetRequestClientFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
  20. {
  21. return GetRequestClientFormatter (operationDescription, endpoint);
  22. }
  23. #if !MOBILE
  24. public IDispatchMessageFormatter DoGetReplyDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
  25. {
  26. return GetReplyDispatchFormatter (operationDescription, endpoint);
  27. }
  28. public IDispatchMessageFormatter DoGetRequestDispatchFormatter (OperationDescription operationDescription, ServiceEndpoint endpoint)
  29. {
  30. return GetRequestDispatchFormatter (operationDescription, endpoint);
  31. }
  32. #endif
  33. public event Action<ServiceEndpoint, ClientRuntime> ApplyClientBehaviorInvoked;
  34. public override void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime client)
  35. {
  36. base.ApplyClientBehavior (endpoint, client);
  37. if (ApplyClientBehaviorInvoked != null)
  38. ApplyClientBehaviorInvoked (endpoint, client);
  39. }
  40. }
  41. [TestFixture]
  42. public class WebHttpBehaviorTest
  43. {
  44. ServiceEndpoint CreateEndpoint ()
  45. {
  46. return new ServiceEndpoint (ContractDescription.GetContract (typeof (IMyService)), new WebHttpBinding (),
  47. new EndpointAddress ("http://localhost:37564"));
  48. }
  49. [Test]
  50. public void DefaultValues ()
  51. {
  52. var b = new WebHttpBehavior ();
  53. Assert.AreEqual (WebMessageBodyStyle.Bare, b.DefaultBodyStyle, "#1");
  54. Assert.AreEqual (WebMessageFormat.Xml, b.DefaultOutgoingRequestFormat, "#2");
  55. Assert.AreEqual (WebMessageFormat.Xml, b.DefaultOutgoingResponseFormat, "#3");
  56. #if NET_4_0
  57. Assert.IsFalse (b.AutomaticFormatSelectionEnabled, "#11");
  58. Assert.IsFalse (b.FaultExceptionEnabled, "#12");
  59. Assert.IsFalse (b.HelpEnabled, "#13");
  60. #endif
  61. }
  62. [Test]
  63. public void AddBiningParameters ()
  64. {
  65. var se = CreateEndpoint ();
  66. var b = new WebHttpBehavior ();
  67. var pl = new BindingParameterCollection ();
  68. b.AddBindingParameters (se, pl);
  69. Assert.AreEqual (0, pl.Count, "#1");
  70. }
  71. #if !MOBILE
  72. [Test]
  73. public void ApplyDispatchBehavior ()
  74. {
  75. var se = CreateEndpoint ();
  76. var od = se.Contract.Operations [0];
  77. // in .NET 3.5 it adds "OperationSelectorBehavior"
  78. int initCB = ContractDescription.GetContract (typeof (IMyService)).Behaviors.Count;
  79. // in .NET 3.5 it adds
  80. // - OperationInvokeBehavior,
  81. // - OperationBehaviorAttribute,
  82. // - DataContractSerializerOperationBehavior and
  83. // - DataContractSerializerOperationGenerator
  84. int initOB = od.Behaviors.Count;
  85. // Assert.AreEqual (1, initCB, "#0-1");
  86. // Assert.AreEqual (4, initOB, "#0-2");
  87. var b = new WebHttpBehavior ();
  88. se.Behaviors.Add (b);
  89. var ed = new EndpointDispatcher (se.Address, se.Contract.Name, se.Contract.Namespace);
  90. IChannelListener l = new WebHttpBinding ().BuildChannelListener<IReplyChannel> (new BindingParameterCollection ());
  91. var cd = new ChannelDispatcher (l);
  92. cd.Endpoints.Add (ed); // without it this test results in NRE (it blindly adds IErrorHandler).
  93. Assert.AreEqual (0, cd.ErrorHandlers.Count, "#1-1");
  94. Assert.IsNull (ed.DispatchRuntime.OperationSelector, "#1-2");
  95. Assert.AreEqual (1, se.Behaviors.Count, "#1-3-1");
  96. Assert.AreEqual (initCB, se.Contract.Behaviors.Count, "#1-3-2");
  97. Assert.AreEqual (initOB, od.Behaviors.Count, "#1-3-3");
  98. Assert.IsTrue (ed.AddressFilter is EndpointAddressMessageFilter, "#1-4");
  99. b.ApplyDispatchBehavior (se, ed);
  100. // FIXME: implement and enable it later
  101. //Assert.AreEqual (1, cd.ErrorHandlers.Count, "#2-1");
  102. Assert.AreEqual (typeof (WebHttpDispatchOperationSelector),
  103. ed.DispatchRuntime.OperationSelector.GetType (), "#2-2");
  104. Assert.AreEqual (1, se.Behaviors.Count, "#3-1");
  105. Assert.AreEqual (initCB, se.Contract.Behaviors.Count, "#3-2");
  106. Assert.AreEqual (initOB, od.Behaviors.Count, "#3-3");
  107. // ... i.e. nothing is added.
  108. Assert.IsTrue (ed.AddressFilter is PrefixEndpointAddressMessageFilter, "#3-4");
  109. Assert.AreEqual (0, ed.DispatchRuntime.Operations.Count, "#4-0"); // hmm... really?
  110. }
  111. #endif
  112. [Test]
  113. public void GetMessageFormatters ()
  114. {
  115. var se = CreateEndpoint ();
  116. var od = se.Contract.Operations [0];
  117. var b = new WebHttpBehaviorExt ();
  118. Assert.IsNotNull (b.DoGetRequestClientFormatter (od, se), "#1");
  119. Assert.IsNotNull (b.DoGetReplyClientFormatter (od, se), "#2");
  120. #if !MOBILE
  121. Assert.IsNotNull (b.DoGetRequestDispatchFormatter (od, se), "#3");
  122. Assert.IsNotNull (b.DoGetReplyDispatchFormatter (od, se), "#4");
  123. #endif
  124. }
  125. [Test]
  126. public void RequestClientFormatter ()
  127. {
  128. var se = CreateEndpoint ();
  129. var od = se.Contract.Operations [0];
  130. var b = new WebHttpBehaviorExt ();
  131. var rcf = b.DoGetRequestClientFormatter (od, se);
  132. var msg = rcf.SerializeRequest (MessageVersion.None, new object [] {"foo"});
  133. var hp = msg.Properties [HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
  134. Assert.IsNotNull (hp, "#1");
  135. Assert.IsTrue (msg.IsEmpty, "#2");
  136. Assert.AreEqual (String.Empty, hp.QueryString, "#3");
  137. var mb = msg.CreateBufferedCopy (1000);
  138. try {
  139. rcf.DeserializeReply (mb.CreateMessage (), new object [0]);
  140. Assert.Fail ("It should not support reply deserialization");
  141. } catch (NotSupportedException) {
  142. }
  143. }
  144. #if !MOBILE
  145. [Test]
  146. public void RequestClientFormatter2 ()
  147. {
  148. var se = CreateEndpoint ();
  149. var od = se.Contract.Operations [0];
  150. var b = new WebHttpBehaviorExt ();
  151. IClientMessageFormatter rcf = null;
  152. b.ApplyClientBehaviorInvoked += delegate (ServiceEndpoint e, ClientRuntime cr) {
  153. rcf = cr.Operations [0].Formatter;
  154. };
  155. se.Behaviors.Add (b);
  156. var ch = new WebChannelFactory<IMyServiceClient> (se).CreateChannel ();
  157. var msg = rcf.SerializeRequest (MessageVersion.None, new object [] {"foo"});
  158. var hp = msg.Properties [HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
  159. Assert.IsNotNull (hp, "#1");
  160. Assert.IsTrue (msg.IsEmpty, "#2");
  161. Assert.AreEqual (String.Empty, hp.QueryString, "#3");
  162. //var mb = msg.CreateBufferedCopy (1000);
  163. // TODO: test DeserializeReply too (it is supported unlike above).
  164. }
  165. #endif
  166. [ServiceContract]
  167. public interface IMyService
  168. {
  169. [OperationContract]
  170. [WebGet]
  171. string Echo (string input);
  172. }
  173. public interface IMyServiceClient : IMyService, IClientChannel
  174. {
  175. }
  176. public class MyService: IMyService
  177. {
  178. #if !MOBILE
  179. [OperationBehavior]
  180. #endif
  181. public string Echo (string input)
  182. {
  183. return input;
  184. }
  185. }
  186. [Test]
  187. public void TestWebGetExists()
  188. {
  189. ContractDescription cd = ContractDescription.GetContract (typeof(IMyService), typeof (MyService));
  190. OperationDescription od = cd.Operations[0];
  191. Assert.IsTrue (od.Behaviors.Contains (typeof (WebGetAttribute)), "Operation is recognized as WebGet");
  192. }
  193. #if !MOBILE
  194. [Test]
  195. public void MessageFormatterSupportsRaw ()
  196. {
  197. // serializing reply
  198. var ms = new MemoryStream ();
  199. var bytes = new byte [] {0, 1, 2, 0xFF};
  200. ms.Write (bytes, 0, bytes.Length);
  201. ms.Position = 0;
  202. var cd = ContractDescription.GetContract (typeof (ITestService));
  203. var od = cd.Operations [0];
  204. var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:37564/"));
  205. var formatter = new WebHttpBehaviorExt ().DoGetReplyDispatchFormatter (od, se);
  206. var msg = formatter.SerializeReply (MessageVersion.None, null, ms);
  207. var wp = msg.Properties ["WebBodyFormatMessageProperty"] as WebBodyFormatMessageProperty;
  208. Assert.IsNotNull (wp, "#1");
  209. Assert.AreEqual (WebContentFormat.Raw, wp.Format, "#2");
  210. var wmebe = new WebMessageEncodingBindingElement ();
  211. var wme = wmebe.CreateMessageEncoderFactory ().Encoder;
  212. var ms2 = new MemoryStream ();
  213. wme.WriteMessage (msg, ms2);
  214. Assert.AreEqual (bytes, ms2.ToArray (), "#3");
  215. }
  216. [Test]
  217. public void MessageFormatterSupportsRaw2 ()
  218. {
  219. // deserializing request
  220. var ms = new MemoryStream ();
  221. ms.Write (new byte [] {0, 1, 2, 0xFF}, 0, 4);
  222. ms.Position = 0;
  223. var cd = ContractDescription.GetContract (typeof (ITestService));
  224. var od = cd.Operations [0];
  225. var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
  226. var wmebe = new WebMessageEncodingBindingElement ();
  227. var wme = wmebe.CreateMessageEncoderFactory ().Encoder;
  228. var msg = wme.ReadMessage (ms, 100, null); // "application/xml" causes error.
  229. var formatter = new WebHttpBehaviorExt ().DoGetRequestDispatchFormatter (od, se);
  230. object [] pars = new object [1];
  231. formatter.DeserializeRequest (msg, pars);
  232. Assert.IsTrue (pars [0] is Stream, "ret");
  233. }
  234. #endif
  235. [ServiceContract]
  236. public interface IMultipleParametersGet
  237. {
  238. [OperationContract]
  239. [WebGet (UriTemplate = "get")]
  240. void Get (string p1, string p2);
  241. }
  242. [ServiceContract]
  243. public interface IMultipleParameters
  244. {
  245. [OperationContract]
  246. [WebInvoke (UriTemplate = "posturi?p1={p1}&p2={p2}")]
  247. string PostUri (string p1, string p2);
  248. [OperationContract]
  249. [WebInvoke (UriTemplate = "postone?p1={p1}")]
  250. string PostOne (string p1, string p2);
  251. [OperationContract]
  252. [WebInvoke (UriTemplate = "postwrapped", BodyStyle=WebMessageBodyStyle.WrappedRequest)]
  253. string PostWrapped (string p1, string p2);
  254. [OperationContract]
  255. [WebInvoke (UriTemplate = "out?p1={p1}&p2={p2}", BodyStyle=WebMessageBodyStyle.WrappedResponse)]
  256. void PostOut (string p1, string p2, out string ret);
  257. }
  258. [Test]
  259. public void MultipleParameters ()
  260. {
  261. var behavior = new WebHttpBehaviorExt ();
  262. var cd = ContractDescription.GetContract (typeof (IMultipleParameters));
  263. var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
  264. behavior.Validate (se);
  265. foreach (var od in cd.Operations)
  266. behavior.DoGetRequestClientFormatter (od, se);
  267. }
  268. [Test]
  269. [Category ("NotWorking")]
  270. public void MultipleParameters2 ()
  271. {
  272. var behavior = new WebHttpBehaviorExt ();
  273. var cd = ContractDescription.GetContract (typeof (IMultipleParametersGet));
  274. var se = new ServiceEndpoint (cd, new WebHttpBinding (), new EndpointAddress ("http://localhost:8080/"));
  275. behavior.Validate (se);
  276. try {
  277. foreach (var od in cd.Operations)
  278. behavior.DoGetRequestClientFormatter (od, se);
  279. Assert.Fail ("Should result in invalid operation");
  280. } catch (InvalidOperationException) {
  281. }
  282. }
  283. }
  284. [ServiceContract]
  285. public interface ITestService
  286. {
  287. [OperationContract]
  288. Stream Receive (Stream input);
  289. }
  290. }