Skip to content

Commit 8b92f39

Browse files
committed
Add source code for Custom TextMessageEncoding
1 parent 2078717 commit 8b92f39

23 files changed

+1198
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<Using Include="System.ServiceModel" />
12+
<Using Include="System.ServiceModel.Channels" />
13+
<Using Include="CoreWcf.Samples.TextMessageEncoder" />
14+
<Using Include="CoreWcf.Samples.CustomTextMessageEncoder" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="System.ServiceModel.Http" Version="4.*" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<ProjectReference Include="..\Library\CustomTextMessageEncoder.csproj" />
23+
</ItemGroup>
24+
25+
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"ExtendedData": {
3+
"inputs": [
4+
"https://localhost:5001/CalculatorService?wsdl"
5+
],
6+
"collectionTypes": [
7+
"System.Array",
8+
"System.Collections.Generic.Dictionary`2"
9+
],
10+
"namespaceMappings": [
11+
"*, CoreWcf.Samples.TextMessageEncoder"
12+
],
13+
"sync": true,
14+
"targetFramework": "net6.0",
15+
"typeReuseMode": "All"
16+
}
17+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by a tool.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
namespace CoreWcf.Samples.TextMessageEncoder
11+
{
12+
13+
14+
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
15+
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="CoreWcf.Samples.TextMessageEncoder.ICalculatorService")]
16+
public interface ICalculatorService
17+
{
18+
19+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Add", ReplyAction="http://tempuri.org/ICalculatorService/AddResponse")]
20+
double Add(double n1, double n2);
21+
22+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Add", ReplyAction="http://tempuri.org/ICalculatorService/AddResponse")]
23+
System.Threading.Tasks.Task<double> AddAsync(double n1, double n2);
24+
25+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Subtract", ReplyAction="http://tempuri.org/ICalculatorService/SubtractResponse")]
26+
double Subtract(double n1, double n2);
27+
28+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Subtract", ReplyAction="http://tempuri.org/ICalculatorService/SubtractResponse")]
29+
System.Threading.Tasks.Task<double> SubtractAsync(double n1, double n2);
30+
31+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Multiply", ReplyAction="http://tempuri.org/ICalculatorService/MultiplyResponse")]
32+
double Multiply(double n1, double n2);
33+
34+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Multiply", ReplyAction="http://tempuri.org/ICalculatorService/MultiplyResponse")]
35+
System.Threading.Tasks.Task<double> MultiplyAsync(double n1, double n2);
36+
37+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Divide", ReplyAction="http://tempuri.org/ICalculatorService/DivideResponse")]
38+
double Divide(double n1, double n2);
39+
40+
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculatorService/Divide", ReplyAction="http://tempuri.org/ICalculatorService/DivideResponse")]
41+
System.Threading.Tasks.Task<double> DivideAsync(double n1, double n2);
42+
}
43+
44+
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
45+
public interface ICalculatorServiceChannel : CoreWcf.Samples.TextMessageEncoder.ICalculatorService, System.ServiceModel.IClientChannel
46+
{
47+
}
48+
49+
[System.Diagnostics.DebuggerStepThroughAttribute()]
50+
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.1.0")]
51+
public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<CoreWcf.Samples.TextMessageEncoder.ICalculatorService>, CoreWcf.Samples.TextMessageEncoder.ICalculatorService
52+
{
53+
54+
/// <summary>
55+
/// Implement this partial method to configure the service endpoint.
56+
/// </summary>
57+
/// <param name="serviceEndpoint">The endpoint to configure</param>
58+
/// <param name="clientCredentials">The client credentials</param>
59+
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);
60+
61+
public CalculatorServiceClient() :
62+
base(CalculatorServiceClient.GetDefaultBinding(), CalculatorServiceClient.GetDefaultEndpointAddress())
63+
{
64+
this.Endpoint.Name = EndpointConfiguration.CustomBinding_ICalculatorService.ToString();
65+
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
66+
}
67+
68+
public CalculatorServiceClient(EndpointConfiguration endpointConfiguration) :
69+
base(CalculatorServiceClient.GetBindingForEndpoint(endpointConfiguration), CalculatorServiceClient.GetEndpointAddress(endpointConfiguration))
70+
{
71+
this.Endpoint.Name = endpointConfiguration.ToString();
72+
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
73+
}
74+
75+
public CalculatorServiceClient(EndpointConfiguration endpointConfiguration, string remoteAddress) :
76+
base(CalculatorServiceClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
77+
{
78+
this.Endpoint.Name = endpointConfiguration.ToString();
79+
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
80+
}
81+
82+
public CalculatorServiceClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) :
83+
base(CalculatorServiceClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
84+
{
85+
this.Endpoint.Name = endpointConfiguration.ToString();
86+
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
87+
}
88+
89+
public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
90+
base(binding, remoteAddress)
91+
{
92+
}
93+
94+
public double Add(double n1, double n2)
95+
{
96+
return base.Channel.Add(n1, n2);
97+
}
98+
99+
public System.Threading.Tasks.Task<double> AddAsync(double n1, double n2)
100+
{
101+
return base.Channel.AddAsync(n1, n2);
102+
}
103+
104+
public double Subtract(double n1, double n2)
105+
{
106+
return base.Channel.Subtract(n1, n2);
107+
}
108+
109+
public System.Threading.Tasks.Task<double> SubtractAsync(double n1, double n2)
110+
{
111+
return base.Channel.SubtractAsync(n1, n2);
112+
}
113+
114+
public double Multiply(double n1, double n2)
115+
{
116+
return base.Channel.Multiply(n1, n2);
117+
}
118+
119+
public System.Threading.Tasks.Task<double> MultiplyAsync(double n1, double n2)
120+
{
121+
return base.Channel.MultiplyAsync(n1, n2);
122+
}
123+
124+
public double Divide(double n1, double n2)
125+
{
126+
return base.Channel.Divide(n1, n2);
127+
}
128+
129+
public System.Threading.Tasks.Task<double> DivideAsync(double n1, double n2)
130+
{
131+
return base.Channel.DivideAsync(n1, n2);
132+
}
133+
134+
public virtual System.Threading.Tasks.Task OpenAsync()
135+
{
136+
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
137+
}
138+
139+
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
140+
{
141+
if ((endpointConfiguration == EndpointConfiguration.CustomBinding_ICalculatorService))
142+
{
143+
System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
144+
System.ServiceModel.Channels.TextMessageEncodingBindingElement textBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
145+
textBindingElement.MessageVersion = System.ServiceModel.Channels.MessageVersion.CreateVersion(System.ServiceModel.EnvelopeVersion.Soap11, System.ServiceModel.Channels.AddressingVersion.WSAddressing10);
146+
result.Elements.Add(textBindingElement);
147+
System.ServiceModel.Channels.HttpsTransportBindingElement httpsBindingElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
148+
httpsBindingElement.AllowCookies = true;
149+
httpsBindingElement.MaxBufferSize = int.MaxValue;
150+
httpsBindingElement.MaxReceivedMessageSize = int.MaxValue;
151+
result.Elements.Add(httpsBindingElement);
152+
return result;
153+
}
154+
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
155+
}
156+
157+
private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
158+
{
159+
if ((endpointConfiguration == EndpointConfiguration.CustomBinding_ICalculatorService))
160+
{
161+
return new System.ServiceModel.EndpointAddress("https://localhost:5001/CalculatorService");
162+
}
163+
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
164+
}
165+
166+
private static System.ServiceModel.Channels.Binding GetDefaultBinding()
167+
{
168+
return CalculatorServiceClient.GetBindingForEndpoint(EndpointConfiguration.CustomBinding_ICalculatorService);
169+
}
170+
171+
private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
172+
{
173+
return CalculatorServiceClient.GetEndpointAddress(EndpointConfiguration.CustomBinding_ICalculatorService);
174+
}
175+
176+
public enum EndpointConfiguration
177+
{
178+
179+
CustomBinding_ICalculatorService,
180+
}
181+
}
182+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
//The service contract is defined using Connected Service "WCF Web Service", generated from the service by the dotnet svcutil tool.
5+
6+
BasicHttpBinding basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
7+
HttpTransportBindingElement httpTransportBindingElement = basicHttpBinding.CreateBindingElements().Find<HttpTransportBindingElement>();
8+
MessageEncodingBindingElement encodingBindingElement = new CustomTextMessageBindingElement("UTF-8", "application/soap+xml", MessageVersion.Soap12WSAddressing10);
9+
httpTransportBindingElement.TransferMode = TransferMode.Streamed;
10+
CustomBinding binding = new CustomBinding(new BindingElement[]
11+
{
12+
encodingBindingElement,
13+
httpTransportBindingElement
14+
});
15+
16+
var endpointAddress = new EndpointAddress("https://localhost:5001/CalculatorService");
17+
18+
// Create a client with given client endpoint configuration
19+
CalculatorServiceClient client = new CalculatorServiceClient(binding, endpointAddress);
20+
21+
// Call the Add service operation.
22+
double value1 = 100.00D;
23+
double value2 = 15.99D;
24+
double result = client.Add(value1, value2);
25+
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
26+
27+
// Call the Subtract service operation.
28+
value1 = 145.00D;
29+
value2 = 76.54D;
30+
result = client.Subtract(value1, value2);
31+
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
32+
33+
// Call the Multiply service operation.
34+
value1 = 9.00D;
35+
value2 = 81.25D;
36+
result = client.Multiply(value1, value2);
37+
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
38+
39+
// Call the Divide service operation.
40+
value1 = 22.00D;
41+
value2 = 7.00D;
42+
result = client.Divide(value1, value2);
43+
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
44+
45+
//Closing the client gracefully closes the connection and cleans up resources
46+
client.CloseAsync();
47+
48+
Console.WriteLine();
49+
Console.WriteLine("Press <ENTER> to terminate client.");
50+
Console.ReadLine();
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.2.32422.2
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service", "Service\Service.csproj", "{BF126326-3393-407C-B24A-8FCCC388BE27}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{B533CADA-93BB-40E1-8FBA-FE37100062C3}"
9+
EndProject
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomTextMessageEncoder_CoreWCF", "LibraryCoreWCF\CustomTextMessageEncoder_CoreWCF.csproj", "{D1EAF072-0F66-4BD0-BC53-D4ABC45163C5}"
11+
EndProject
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomTextMessageEncoder", "Library\CustomTextMessageEncoder.csproj", "{B1EAF072-4F66-FBD0-BC53-D4ABC45963C5}"
13+
EndProject
14+
Global
15+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
16+
Debug|Any CPU = Debug|Any CPU
17+
Release|Any CPU = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20+
{BF126326-3393-407C-B24A-8FCCC388BE27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{BF126326-3393-407C-B24A-8FCCC388BE27}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{BF126326-3393-407C-B24A-8FCCC388BE27}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{BF126326-3393-407C-B24A-8FCCC388BE27}.Release|Any CPU.Build.0 = Release|Any CPU
24+
{B533CADA-93BB-40E1-8FBA-FE37100062C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25+
{B533CADA-93BB-40E1-8FBA-FE37100062C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{B533CADA-93BB-40E1-8FBA-FE37100062C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
27+
{B533CADA-93BB-40E1-8FBA-FE37100062C3}.Release|Any CPU.Build.0 = Release|Any CPU
28+
{D1EAF072-0F66-4BD0-BC53-D4ABC45163C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29+
{D1EAF072-0F66-4BD0-BC53-D4ABC45163C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
30+
{D1EAF072-0F66-4BD0-BC53-D4ABC45163C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
31+
{D1EAF072-0F66-4BD0-BC53-D4ABC45163C5}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{B1EAF072-4F66-FBD0-BC53-D4ABC45963C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33+
{B1EAF072-4F66-FBD0-BC53-D4ABC45963C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
34+
{B1EAF072-4F66-FBD0-BC53-D4ABC45963C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
35+
{B1EAF072-4F66-FBD0-BC53-D4ABC45963C5}.Release|Any CPU.Build.0 = Release|Any CPU
36+
EndGlobalSection
37+
GlobalSection(SolutionProperties) = preSolution
38+
HideSolutionNode = FALSE
39+
EndGlobalSection
40+
GlobalSection(ExtensibilityGlobals) = postSolution
41+
SolutionGuid = {AD996EFD-70DC-4431-B411-5A2771DD02D3}
42+
EndGlobalSection
43+
EndGlobal
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text;
5+
using System.Xml;
6+
7+
namespace CoreWcf.Samples.CustomTextMessageEncoder
8+
{
9+
public class CustomTextMessageEncoder : MessageEncoder
10+
{
11+
private readonly CustomTextMessageEncoderFactory _factory;
12+
private readonly XmlWriterSettings _writerSettings;
13+
private readonly string _contentType;
14+
15+
public CustomTextMessageEncoder(CustomTextMessageEncoderFactory factory)
16+
{
17+
_factory = factory;
18+
_writerSettings = new XmlWriterSettings();
19+
_writerSettings.Encoding = Encoding.GetEncoding(factory.CharSet);
20+
_contentType = string.Format("{0}; charset={1}", _factory.MediaType, _writerSettings.Encoding.HeaderName);
21+
}
22+
23+
public override string ContentType => _contentType;
24+
25+
public override string MediaType => _factory.MediaType;
26+
27+
public override MessageVersion MessageVersion => _factory.MessageVersion;
28+
29+
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
30+
{
31+
byte[] msgContents = new byte[buffer.Count];
32+
Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);
33+
bufferManager.ReturnBuffer(buffer.Array);
34+
35+
return ReadMessage(msgContents, bufferManager);
36+
}
37+
38+
public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
39+
{
40+
XmlReader reader = XmlReader.Create(stream);
41+
Message message = Message.CreateMessage(reader, maxSizeOfHeaders, MessageVersion);
42+
return message;
43+
}
44+
45+
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
46+
{
47+
MemoryStream stream = new MemoryStream();
48+
XmlWriter writer = XmlWriter.Create(stream, _writerSettings);
49+
message.WriteMessage(writer);
50+
writer.Close();
51+
52+
byte[] messageBytes = stream.GetBuffer();
53+
int messageLength = (int)stream.Position;
54+
stream.Close();
55+
56+
int totalLength = messageLength + messageOffset;
57+
byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
58+
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
59+
60+
ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
61+
return byteArray;
62+
}
63+
64+
public override void WriteMessage(Message message, Stream stream)
65+
{
66+
XmlWriter writer = XmlWriter.Create(stream, _writerSettings);
67+
message.WriteMessage(writer);
68+
writer.Close();
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)