ContractException when serialize my custom datatable - wcf

I got error when try execute this wcf code
An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
contract: http://tempuri.org/:IService1 ----> System.Runtime.Serialization.InvalidDataContractException: Method 'MyClassLibrary.MyDataTable.GetSchema()' must return a schema with a valid Id.
at System.Runtime.Serialization.SchemaExporter.InvokeGetSchemaMethod(Type clrType, XmlSchemaSet schemas, XmlQualifiedName stableName)
at System.Runtime.Serialization.SchemaExporter.ExportXmlDataContract(XmlDataContract dataContract)
at System.Runtime.Serialization.SchemaExporter.ExportDataContract(DataContract dataContract)
at System.Runtime.Serialization.SchemaExporter.Export()
at System.Runtime.Serialization.XsdDataContractExporter.Export()
at System.Runtime.Serialization.XsdDataContractExporter.Export(Type type)
at System.ServiceModel.Description.MessageContractExporter.ExportType(Type type, String partName, String operationName, XmlSchemaType& xsdType)
at System.ServiceModel.Description.DataContractSerializerMessageContractExporter.ExportBody(Int32 messageIndex, Object state)
at System.ServiceModel.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)
....
...
....
Custom datatable
Public Class MyDataTable
Inherits DataTable
Public Sub New()
End Sub
End Class
My WCF Interface
<ServiceContract()> _
Public Interface IService1
<OperationContract()> _
Function TestDatatable(ByVal MyDT As MyDataTable) As Boolean
End Interface
Implementation
Public Class Service1
Implements IService1
Public Function TestDatatable(ByVal MyDT As MyClassLibrary.MyDataTable) As Boolean Implements IService1.TestDatatable
Return MyDT.TableName = "MyTable"
End Function
End Class
Note: When just using datatable its ok but not my custom datatable.
What need to be added do I can serialize my custom datatable.
I able to serialize my other object but not this class.

Instead of manually deriving from DataTable I'd create a typed data set using Visual Studio's data set designer. They are much easier to work with.

Implementation of GetSchema method in DataTable looks like
protected virtual XmlSchema GetSchema()
{
if (this.GetType() == typeof (DataTable))
return (XmlSchema) null;
So that you may override this method in the following way
protected override XmlSchema GetSchema()
{
return null;
}
This will resolve serialization issue.

Related

Method 'set_Description' in type 'myAssembly.NetProduct' from assembly 'myAssembly' does not have an implementation

I have a DLL file created in VB6. It contains a class named Product and that contains the following simple code:
Option Explicit
Private sDescription As String
Public Property Get Description() As String
Description = sDescription
End Property
Public Property Let Description(Value As String)
sDescription = Value
End Property
I want to use this DLL in VB.NET, which is nothing more than registering the DLL on my system and including the DLL file in the references. Visual Studio automatically generates an interop DLL to consume the COM DLL. This interop DLL generates interfaces for all classes. In VB.NET I want to create a new class that implements the Product interface from the interop DLL. So I code:
Imports myAssembly
Public Class NetProduct
Implements myAssembly.Product
Public Property Description As String Implements _Product.Description
Get
Throw New NotImplementedException()
End Get
Set(value As String)
Throw New NotImplementedException()
End Set
End Property
End Class
The property is auto-generated because I implemented the Product interface. But here comes the problem because when I start using the NetProduct class I get an error telling me this:
Method 'set_Description' in type 'myProject.NetProduct' from
assembly 'myProject, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' does not have an implementation.
The problem is that there is no method set_Description in the interface. When I view the definition of the Product interface it shows me the following:
Imports System.Runtime.InteropServices
Namespace myAssembly
<CoClass(GetType(ProductClass))> <Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")>
Public Interface Product
Implements _Product
End Interface
End Namespace
The definition of the _Product interface is:
Imports System.Runtime.InteropServices
Namespace myAssembly
<Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")> <TypeLibTypeAttribute(4304)>
Public Interface _Product <DispId(1745027072)>
Property Description As String
End Interface
End Namespace
When I use the interface myAssembly.Product directly to create a new object then everything works as you would expect. The property does not pose a problem there. But when I implement the interface in a .NET class the problem arises.
How do I solve this?
[update 1] After creating a method Set_Description I see the following error appear:
property 'Description' implicitly defines 'set_Description', which
conflicts with a member of the same name in class 'NetProduct'.
This must have something to do with my problem, although I don't know what it is. I already tried completing the property to make sure the Throw New NotImplementedException() wouldn't be in the way but that didn't make the error go away. My code builds just fine by the way. The error I gave earlier is a runtime error. Not a build error.
Private myDescription As String
Public Property Description As String Implements Product.Description
Get
Return myDescription
End Get
Set(value As String)
myDescription = value
End Set
End Property
[update 2] I have used JetBrains DotPeek to disassemble the interop.dll that Visual Studio generates. Disassembly is coded in C#. It contains 2 interfaces and 1 class for the single Product class from VB6. Here are all details.
I'll start with the Product class itself.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace myAssembly
{
[ClassInterface(0)]
[Guid("C54B96A8-1499-4B76-8508-0B732E551326")]
[TypeLibType(2)]
[ComImport]
public class ProductClass : _Product, Product
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern ProductClass();
[DispId(1745027072)]
public virtual extern string Description { [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.BStr)] get; [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [param: MarshalAs(UnmanagedType.BStr), In, Out] set; }
}
}
The ProductClass uses 2 interfaces. I don't understand why because one of those is just an implementation of the other. This is the Product interface.
using System.Runtime.InteropServices;
namespace myAssembly
{
[CoClass(typeof (ProductClass))]
[Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")]
[ComImport]
public interface Product : _Product
{
}
}
And then we have the _Product interface. They even share the same Guid. It might have something to do with backwards compatibility.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace myAssembly
{
[Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")]
[TypeLibType(4304)]
[ComImport]
public interface _Product
{
[DispId(1745027072)]
string Description { [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.BStr)] get; [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [param: MarshalAs(UnmanagedType.BStr), In, Out] set; }
}
}
This is all I could find. Still no clue where the error for Set_Description comes from.
[Update 3] Example code
The code for the VB6 class is on top of this question. Nothing fancy there. The code for testing implementation in .NET is like this:
Imports myAssembly
Public Class NetProduct
Implements myAssembly.Product
Private myDescription As String
Public Property Description As String Implements Product.Description
Get
Return myDescription
End Get
Set(value As String)
myDescription = value
End Set
End Property
End Class
To test the NetProduct class I dropped a Button on a Form and create an instance of the class when the button is being clicked.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '<- Error happens here, so on loading the datatype!
Dim Product As New NetProduct 'Error does NOT happen here.
End Sub
The whole project compiles without errors. The project even runs without errors UNTIL you click the button. Probably because the NetProduct type is first loaded on that point.
I used a console app to do my test. Other than that, my VB.NET code is basically identical to yours in update 3. The VB.NET properties were auto-generated by VS with the stub Throw New NotImplementedException() after using the Implements statement :
Imports OurCOMDll
Class TestClass
Implements OurCOMDll.ClassInCOMDll
Dim msStringProperty As String = String.Empty
Public Property StringProperty As String Implements _ClassInCOMDll.StringProperty
Get
StringProperty= msStringProperty
End Get
Set(value As String)
msStringProperty = value
End Set
End Property
End Class
Module Module1
Sub Main()
Dim o As New OurCOMDll.ClassInCOMDll
o.StringProperty = "Hello World!"
Console.WriteLine(o.StringProperty) ' Outputs 'Hello World!' as expected
Console.ReadLine()
End Sub
End Module
Same is true for the VB6 code. The string property is implemented like yours.
Distinguishing factors so far:
VS 2019 vs. VS 2017
(Consuming) GUI vs. Console application
Different property names

Null reference exceptions on properties of a newly instantiated class? What's going on here?

I'm toying around with a 3rd party library and something has me absolutely puzzled.
When I instantiate this class, immediately all of the properties of the class throw exceptions before any more code even runs. Why is this happening? It's not just this TypedSegmentPWK class, it's all of the typedsegment classes.. of which there are many.
Simple instantiation fails
Imports OopFactory.X12.Parsing
Imports OopFactory.X12.Parsing.Model
Imports OopFactory.X12.Parsing.Model.Typed
....
Dim test As New TypedSegmentPWK
test.PWK04_EntityIdentifierCode = "blah"
Assigning a value to PWK04_EntityIdentifierCode or any other property of test fails with a null reference exception.
TypedSegmentPWK:
Namespace OopFactory.X12.Parsing.Model.Typed
Public Class TypedSegmentPWK
Inherits TypedSegment
Public Sub New()
Public Property PWK01_ReportTypeCode As String
Public Property PWK02_ReportTransmissionCode As String
Public Property PWK03_ReportCopiesNeeded As Integer?
Public Property PWK04_EntityIdentiferCodeEnum As EntityIdentifierCode
Public Property PWK04_EntityIdentifierCode As String
Public Property PWK05_IdentificationCodeQualifier As String
Public Property PWK05_IdentificationCodeQualifierEnum As IdentificationCodeQualifier
Public Property PWK06_IdentificationCode As String
Public Property PWK07_Description As String
Public Property PWK08_ActionsIndicated As String
Public Property PWK09_RequestCategoryCode As String
End Class
End Namespace
TypedSegment:
Namespace OopFactory.X12.Parsing.Model
Public MustInherit Class TypedSegment
Protected Sub New(segmentId As String)
Public Event Initialized As EventHandler
Public Event Initializing As EventHandler
Protected Overridable Sub OnInitialized(e As EventArgs)
Protected Overridable Sub OnInitializing(e As EventArgs)
End Class
End Namespace
Full source here: https://github.com/KeyMarkInc/OopFactory.X12
All the properties reference _segment defined in TypedSegment, e.g.
public string PWK04_EntityIdentifierCode
{
get { return _segment.GetElement(4); }
set { _segment.SetElement(4, value); }
}
However, the _segment variable is not initialized until TypedSegment.Initialize(Container parent, X12DelimiterSet delimiters) is called...
internal void Initialize(Container parent, X12DelimiterSet delimiters)
{
OnInitializing(new EventArgs());
_segment = new Segment(parent, delimiters, _segmentId);
OnInitialized(new EventArgs());
}
This is an internal method, so presumably something in this framework is supposed to call it, and not you as the user. So, I would guess the answer is that you are using the TypedSegmentPWK class incorrectly, although I don't know what the correct way is.

How can I make a "RequiredIf" custom valid attribute in vb.net

I am trying to create a customValidAttribute in VB.NET
Namespace EventRules
Public Class CustomRuleAttribute
Inherits ValidationAttribute
Protected Overrides Function IsValid(value As Object, validationContext as validationContext) As ValidationResult
If EventIsInOneWeek = True Then
'Property is required
End If
Return New ValidationResult(Me.FormatErrorMessage(validationContext.DisplayName))
End Function
And in my Interface
Imports System.ComponentModel.DataAnnotations
Imports EventRules
Namespace Contracts
Public Interface IEvent
Property EventIsInOneWeek As Boolean
<CustomRule()>
Property AdditionalProperty
So, the error I am getting is on EventIsInOneWeek and says "Reference to a non-shared member requires an object reference"
Edit: The object being passed in is a different property than 'EventIsInOneWeek', and I only want it to be required if EventIsInOneWeek is true.
Edit: Also updated the code more completely
As mentioned above -- the simple solution I was looking for was passing the entire business object in with validationContext. However, this exposes some security flaws in my system, so I created this work-around.
In my base business logic:
Public Overridable Function CheckRules() As Boolean
Me.Errors = New List(Of ValidationRules)()
Return Me.Validate(Me.Errors)
End Function
...
Public Overridable Function Validate(validationContext As ValidationContext) As IEnumerable(Of Validation Result) Implements IValidateObject.Validate
Return Nothing
End Function
And In my Business logic for the object itself
Protected Overrides Function Validate(validationContext As ValidationContext) As IEnumerable(Of Validation Result)
Dim results = New List(Of ValidationResult)()
'valiation conditionals here
Return results
End Function
I am passing my base logic into my Business Object, and it seems to be working well, unfortunately it does not auto generate front-end validation the way CustomValidationAttributes do.
This also allows me validationRules a little bit of re-usability that would not be afforded when passing a validationContext in.

How to send a managed Exception from WCF client to server (for logging)?

I'm trying to build an error logging mechanism for my WCF client applications, so they can report any exceptions that may occur outside of the WCF context back to the service.
I'm absolutely guaranteed in this situation that all clients will be .NET.
I'm finding a plethora of information, articles and examples on how to configure for going the other way (e.g. service to client), but nothing on client to service.
I wish to do something like this on the client:
Dim i As Integer
Try
i = String.Empty
Catch ex As Exception
Client.Create.Call(Sub(S As IService)
S.Log(LogLevels.Error, ex)
End Sub)
End Try
FaultException(Of T) doesn't work; I tried this:
Dim i As Integer
Try
i = String.Empty
Catch ex As Exception
Try
Throw New FaultException(Of Exception)(ex)
Catch fex As FaultException
Client.Create.Call(Sub(S As IService)
S.Log(LogLevels.Error, fex.Message, fex)
End Sub)
End Try
End Try
It returns a hideously obscure error message of its own:
"Type 'System.InvalidCastException' with data contract name 'InvalidCastException:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer."
Binary serialization of the exception doesn't work either; I get an error at deserialization:
"The input stream is not a valid binary format."
My code for that:
Class Test
Public Sub Test
Dim i As Integer
Dim aEx As Byte()
Dim oEx As Exception
Try
i = String.Empty
Catch ex As Exception
aEx = ex.ToBytes
oEx = aEx.ToObject(Of Exception)()
End Try
End Sub
End Class
Public Module Generic
<Extension>
Public Function ToBytes(Of T)([Object] As T) As Byte()
Using oStream As New MemoryStream
With New BinaryFormatter
.Serialize(oStream, [Object])
End With
Return oStream.ToArray
End Using
End Function
<Extension>
Public Function ToObject(Of T)(Data As Byte()) As T
Using oStream As New MemoryStream
oStream.Write(Data, 0, Data.Length)
oStream.Seek(0, SeekOrigin.Begin)
With New BinaryFormatter
Return .Deserialize(oStream)
End With
End Using
End Function
End Module
How does one send this non-WCF exception across the wire?
EDIT
Here's my service interface, edited for brevity:
<ServiceContract>
Public Interface IService
<OperationContract> Sub Log(Level As LogLevels, Message As String, Exception As Exception)
End Interface
I'm assuming that your contract just asks for a generic base exception - the System.Exception. If that's the case, then the DataContractSerializer will only deserialize that type. It will not deserialize anything that extends Exception; it will only deserialize exceptions of type Exception.
In other words, all the other exceptions that you catch - and you will really never catch a base System.Exception type - won't be handled by the contract.
So how can you handle this? Two options:
Add other types to your contract. Your contract will still only accept an Exception, but if you use the KnownTypeAttribute you can allow objects that sub-type the Exception class. This would be your FaultException, your NullReferenceException, or anything else you want. You can also check, inside the service, whether the Exception is one of these types, cast it and use those other properties that may be present. This is my preferred option, but you need to specify every single type you want to handle as a "Known Type". If a new type comes up, it will fail.
Clone your exception into a new System.Exception. i.e. create a new base System.Exception, put the message, the stack trace, and whatever other values you have from your subclass into it. The new object is of the correct type, so it will deserialize correctly.
Neither option is great, but when you think about it concretely you can't create a contract that accepts object and send whatever you want. This is the same thing. You can only deliver types that are known by the deserializer.
Well, that was a trip and a half. Wish I'd brought some TrailMix.
The solution turned out to be Microsoft's red-headed stepchild, NetDataContractSerializer, mentioned briefly here. You can read about why I call it that here.
There's an important link at the bottom of Ron Jacobs' post (to Aaron Skonnard's post) that's now expired. I found a copy of that here (the comments are important, have a look). It looks like Tim Scott used a slight variation of Aaron's code as well.
It was in Tim's more thorough explanation that I found my Holy Grail. (I've been wanting to do this for some time!)
Tim is using Attribute decorations, but those are applicable only when working with CLR objects at the server. In this case we're working at the client.
So in the end, the fix is beautiful in its simplicity. Just use NetDataContractSerializer to package up the System.Exception into a Byte(), send the data to the server, and then deserialize it there. No chanting, smoke-n-mirrors, eye-of-the-newt required.
There's a performance penalty, so keep your Exceptions to a minimum!
Here's what I ended up with, followed by Tim's code for anyone who may need it:
Send a System.Exception from client to server
Public Class Client
Private Sub ClientTest()
Dim i As Integer
Try
i = String.Empty
Catch ex As Exception
Client.Create.Call(Sub(S As IService)
S.Log(LogLevels.Error, ex.Message, ex.ToBytes)
End Sub)
End Try
End Sub
End Class
<ServiceContract>
Public Interface IService
<OperationContract> Sub Log(Level As LogLevels, Message As String, Data As Byte())
End Interface
Public Class Service
Implements IService
Public Sub Log(Level As LogLevels, Message As String, Data As Byte()) Implements IService.Log
' Log4Net logger created separately, out of scope of this question '
Select Case Level
Case LogLevels.Debug : Main.Logger.Debug(Message, Data.ToException)
Case LogLevels.Info : Main.Logger.Info(Message, Data.ToException)
Case LogLevels.Warn : Main.Logger.Warn(Message, Data.ToException)
Case LogLevels.Error : Main.Logger.Error(Message, Data.ToException)
Case LogLevels.Fatal : Main.Logger.Fatal(Message, Data.ToException)
End Select
End Sub
End Class
Public Module Extensions
<Extension>
Public Function ToBytes(Instance As Exception) As Byte()
Using oStream As New MemoryStream()
With New NetDataContractSerializer
.Serialize(oStream, Instance)
End With
Return oStream.ToArray
End Using
End Function
<Extension>
Public Function ToException(Data As Byte()) As Exception
Using oStream As New MemoryStream(Data)
With New NetDataContractSerializer
Return .Deserialize(oStream)
End With
End Using
End Function
End Module
Send CLR objects (including generics) to the client
public class NetDataContractOperationBehavior : DataContractSerializerOperationBehavior
{
public NetDataContractOperationBehavior(OperationDescription operation)
: base(operation)
{
}
public NetDataContractOperationBehavior(OperationDescription operation, DataContractFormatAttribute dataContractFormatAttribute)
: base(operation, dataContractFormatAttribute)
{
}
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns,
IList<Type> knownTypes)
{
return new NetDataContractSerializer(name, ns);
}
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name,
XmlDictionaryString ns, IList<Type> knownTypes)
{
return new NetDataContractSerializer(name, ns);
}
}
public class UseNetDataContractSerializerAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description,
System.ServiceModel.Dispatcher.ClientOperation proxy)
{
ReplaceDataContractSerializerOperationBehavior(description);
}
public void ApplyDispatchBehavior(OperationDescription description,
System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
ReplaceDataContractSerializerOperationBehavior(description);
}
public void Validate(OperationDescription description)
{
}
private static void ReplaceDataContractSerializerOperationBehavior( OperationDescription description)
{
DataContractSerializerOperationBehavior dcsOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
description.Behaviors.Remove(dcsOperationBehavior);
description.Behaviors.Add(new NetDataContractOperationBehavior(description));
}
}
}
// Then in the service contract, to every method we added the UseNetDataContractSerializer attribute, like so:
[UseNetDataContractSerializer]
[OperationContractAttribute]
Company SaveCompany(CompanyUpdater companyUpdater);

WCF/Entity Framework - How To Get a Nice DataContract?

Is there a clean way of using the auto-generated EF classes with WCF instead of having to hand-make classes for WCF DataContracts?
The classes are located in the LAIT.Entities.dll
ProductService.vb
Public Class ProductService
Implements IProductService
Public Function GetWorkOrder(ByVal WorkOrderID As Integer) As
WorkOrder Implements IProductService.GetWorkOrder
Using dc As New LAIT.Model.LAITEntities
Try
Dim _Order = (From o In dc.WorkOrder
Where o.WorkOrderID = WorkOrderID
Select o).SingleOrDefault
Return _Order
Catch ex As Exception
Return Nothing
End Try
End Using
End Function
End Class
IProductService.vb
Public Interface IProductService
<OperationContract()>
Function GetWorkOrder(ByVal WorkOrderID As Integer) As
LAIT.Entities.WorkOrder
End Interface
Yes. For that you need to edit the T4 file that VS uses to auto generate your entities. All you need to do is to make sure that all your classes are decorated with <DataContract> attribute and your properties are marked with <DataMember> attribute. I assume that you are using POCO entities because both Entity Objects and STEs are already marked as DataContract and you don't need to do anything in order to use them in your WCF services.
Having said that, I strongly discourage you from using Entity Objects across the wire with WCF. You should use either STEs or POCOs in this scenaio.
The POCO proxy type cannot be directly serialized or deserialized by the Windows Communication Foundation (WCF), because the DataContractSerializer serialization engine can only serialize and deserialize known types. The proxy type is not a known type.
If your POCO entities don't have any "Navigation Properties" you can have serialized objects of your entities through WCF Services by adding <DataContract> and <DataMember> properties in your class.
But for Entities with "Navigation Properties" In addition of adding <DataContract> and <DataMember> properties in your class you need to have some changes in your WCF Service as follows. Add the following calss in your WCF Service project.
1.
Imports System.Data.Objects
Imports System.ServiceModel.Description
Imports System.ServiceModel.Channels
Public Class ApplyDataContractResolverAttribute
Inherits Attribute
Implements IOperationBehavior
Public Sub New()
End Sub
Public Sub AddBindingParameters(ByVal operationDescription As OperationDescription, ByVal parameters As BindingParameterCollection) Implements IOperationBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(ByVal operationDescription As OperationDescription, ByVal proxy As System.ServiceModel.Dispatcher.ClientOperation) Implements IOperationBehavior.ApplyClientBehavior
Dim dataContractSerializerOperationBehavior As DataContractSerializerOperationBehavior = operationDescription.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
dataContractSerializerOperationBehavior.DataContractResolver = New ProxyDataContractResolver()
End Sub
Public Sub ApplyDispatchBehavior(ByVal operationDescription As OperationDescription, ByVal dispatch As System.ServiceModel.Dispatcher.DispatchOperation) Implements IOperationBehavior.ApplyDispatchBehavior
Dim dataContractSerializerOperationBehavior As DataContractSerializerOperationBehavior = operationDescription.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
dataContractSerializerOperationBehavior.DataContractResolver = New ProxyDataContractResolver()
End Sub
Public Sub Validate(ByVal operationDescription As OperationDescription) Implements IOperationBehavior.Validate
' Do validation.
End Sub
End Class
2.Open the service interface file. By default, it is called IService1.
3.Replace the code that defines the service interface file with the following code:
C#
[ServiceContract]
public interface IService1
{
[OperationContract]
[ApplyDataContractResolver]
void UpdateOrder(Order updated);
[OperationContract]
[ApplyDataContractResolver]
Order GetOrder(int OrderID);
}
VB
<ServiceContract> _
Public Interface IService1
<OperationContract> _
<ApplyDataContractResolver> _
Sub UpdateOrder(updated As Order)
<OperationContract> _
<ApplyDataContractResolver> _
Function GetOrder(OrderID As Integer) As Order
End Interface
And you are ready to go.