Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Monday, 9 December 2013

Using the DataContractSerializer to serialize and deserialize

 

To serialize a Business object marked with [DataContract] and properties marked with [DataMember] attributes…

public static string DataContractSerializeObject<T>(T objectToSerialize)

        {

using (var output = new StringWriter())

            {

using (var writer = new XmlTextWriter(output) { Formatting = Formatting.Indented })

                {

var dataContractSerializer = new DataContractSerializer(typeof(T), EntityUtilities.GetAllKnownTypes(), int.MaxValue, true, true, null);

                    dataContractSerializer.WriteObject(writer, objectToSerialize);

return output.GetStringBuilder().ToString();

                }

            }

        }

Then to deserialize back to your DataContract type, use this logic…

public static T Deserialize<T>(string xml)

        {

using (Stream stream = new MemoryStream())

            {

byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);

                stream.Write(data, 0, data.Length);

                stream.Position = 0;

var dataContractSerializer = new DataContractSerializer(typeof(T), EntityUtilities.GetAllKnownTypes(), int.MaxValue, true, true, null);

return (T)dataContractSerializer.ReadObject(stream);

            }

        }

Tuesday, 23 July 2013

Unit of work pattern in WCF

See here for an example of how to implement a unit of work pattern in WCF (using Unity).

http://blogs.5dlabs.it/post/2012/05/23/Implementing-Repository-and-UnitOfWork-patterns-in-a-WCF-service-using-Unity.aspx

public class CustomServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
  {
return new CustomServiceHost(serviceType, baseAddresses);
  }
}

public class CustomServiceHost : ServiceHost
{
static IUnityContainer _container;
static CustomServiceHost()
  {
    _container = new UnityContainer();
    _container.RegisterType<ICompanyRepository, CompanyRepository>();
    _container.RegisterType<IUnitOfWork, DbUnitOfWork>();
    _container.RegisterType<SVCContext>(new ServiceInstanceLifeTimeManager());
  }
public CustomServiceHost(Type serviceType, params Uri[] : base(serviceType, baseAddresses)
  {
  }
protected override void ApplyConfiguration()
  {
base.ApplyConfiguration();
    Description.Behaviors.Add(_container.Resolve<UnityServiceBehavior>());
  }
}

public class UnityServiceBehavior : BehaviorExtensionElement , IServiceBehavior
{
IUnityContainer _container;
public UnityServiceBehavior(IUnityContainer container) : base()
  {
    _container = container;
  }
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
  {
  }
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
  {
Type serviceType = serviceDescription.ServiceType;
IInstanceProvider instanceProvider = new UnityInstanceProvider(_container, serviceType);
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
    {
foreach (EndpointDispatcher endpointDispatcher in dispatcher.Endpoints)
      {
        endpointDispatcher.DispatchRuntime.InstanceProvider = instanceProvider;
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
new UnitOfWorkMessageInspector(_container)
        );
      }
    }
  }
public void Validate(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
  {
  }
public override Type BehaviorType
  {
get { return this.GetType(); }
  }
protected override object CreateBehavior()
  {
return this;
  }
}

public class UnityInstanceProvider : IInstanceProvider
{
IUnityContainer _container;
Type _serviceType;
public UnityInstanceProvider(IUnityContainer container, Type serviceType)
  {
    _container = container;
    _serviceType = serviceType;
  }
public object GetInstance(InstanceContext instanceContext, Message message)
  {
return _container.Resolve(_serviceType);
  }
public object GetInstance(InstanceContext instanceContext)
  {
return this.GetInstance(instanceContext, null);
  }
public void ReleaseInstance(InstanceContext instanceContext, object instance)
  {
  }
}

 

 

public interface IUnitOfWork
{
void Commit();
}

public class DbUnitOfWork : IUnitOfWork
{
SVCContext _context;
public DbUnitOfWork(SVCContext context)
  {
    _context = context;
  }
public void Commit()
  {
    _context.SaveChanges();
  }
}

 

public class UnitOfWorkMessageInspector : IDispatchMessageInspector
{
IUnityContainer _container;
public UnitOfWorkMessageInspector(IUnityContainer container)
  {
    _container = container;
  }
public object AfterReceiveRequest(ref Message request, IClientChannel channel,
InstanceContext instanceContext)
  {
return _container.Resolve<IUnitOfWork>();
  }
public void BeforeSendReply(ref Message reply, object correlationState)
  {
    ((IUnitOfWork)correlationState).Commit();
  }
}

Wednesday, 6 March 2013

WCF DataMember attribute issue

Got caught out by this issue today. Spent ages trying to find out why I was getting a WCF exception after adding the DataContract and DataMember attributes into my class, and it turned out I had a property that didn't have both a getter and a setter declared.

image

http://msdn.microsoft.com/en-gb/library/system.runtime.serialization.datamemberattribute.aspx

The error was simply reported as

System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue

Thursday, 15 November 2012

Deep clone of an object by rewinding the Serialization stream

/// <summary>
        /// Serializes this class to a json string.
        /// </summary>
        /// <returns>A JSON string reprsenting a SelectListItem.</returns>
        public string ToJson()
        {
            using (var memoryStream = new MemoryStream())
            {
                var dataContractJsonSerializer = new DataContractJsonSerializer(typeof(JsonSerializableSelectListItem));
                dataContractJsonSerializer.WriteObject(memoryStream, this);
                memoryStream.Position = 0;
                using (var streamReader = new StreamReader(memoryStream))
                {
                    return streamReader.ReadToEnd();
                }
            }
        }

Wednesday, 14 November 2012

WCF System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly

WCF System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly

If you get the above error when trying to return large numbers of items in a List<T> from a WCF service, then ensure you have set the following behaviour for the dataContractSerializer in both your client and service configuration files..

<dataContractSerializer maxItemsInObjectGraph="2147483646"/>

As in this blog, but with larger number (i.e. max of int)http://processmentor.com/community/blogs/scott_middleton/archive/2007/06/08/169.aspx

Need the settings in service layer and client, set to this.

Service has this

<behavior name="MyService.ServiceImplementation.MyService_Behavior">

                                  <serviceDebug includeExceptionDetailInFaults="true" />

                                  <serviceMetadata httpGetEnabled="true" />

                                  <dataContractSerializer maxItemsInObjectGraph="2147483646"/>

                           </behavior>

                     </serviceBehaviors>

<service behaviorConfiguration="MyService.ServiceImplementation.MyService_Behavior"

name="MyService.ServiceImplementation.MyService">

                           <endpoint binding="basicHttpBinding"bindingConfiguration="BasicHttpBinding_Leads"

bindingNamespace="http://MyService.ServiceContracts/2007/04"

contract="MyService.ServiceContracts.IMyService" />

                           <endpoint address="mex" binding="mexHttpBinding"contract="IMetadataExchange" />

                     </service>

              </services>

Client has this …

<behaviors>

<endpointBehaviors>

<behavior name="debuggingBehaviour">

<dataContractSerializer maxItemsInObjectGraph="2147483646" />

                           </behavior>

                     </endpointBehaviors>

              </behaviors>

<endpoint address="http://localhost/Host/Internal/myservice.svc" binding="basicHttpBinding"

bindingConfiguration="BasicHttpBinding_IMyService"contract="LeadsServiceInternal.IMyService" name="BasicHttpBinding_IMyService"

behaviorConfiguration="debuggingBehaviour"

                                    />

Note you must also set the following two settings on the client maxReceivedMessageSize and maxBufferSize

<binding name="BasicHttpBinding_IMyService" closeTimeout="00:01:00" openTimeout="00:01:00"receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false"

hostNameComparisonMode="StrongWildcard"maxBufferSize="500000000" maxBufferPoolSize="524288" maxReceivedMessageSize="500000000"messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">

                                  <readerQuotas maxDepth="32" maxStringContentLength="8192"maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>

                                  <security mode="None">

                                         <transport clientCredentialType="None"proxyCredentialType="None" realm=""/>

                                         <message clientCredentialType="UserName"algorithmSuite="Default"/>

                                  </security>

                           </binding>

Friday, 28 September 2012

How to create the DataContracts and Translators for Entity Framework generated objects

Think I've just come up with a fool proof method for creating datacontracts and associated translator logic from Entity Framework generated objects

Creating datacontracts

1. Grab the class definition from the xxxModel.cs file in xxxx.DataContracts.csproj project

2. Paste into a new file in the xxx.DataContracts namespace

3. Use Resharper to clean up the code (Ctrl +E , Ctrl + C), choose full format option

4. Suspend off Resharper (Tools, options ,Resharper)

5. Grab the primitives section and change privates to publics

6. Replace ; with { get; set; } and then replace _ with empty string

7. That's it, you now have your matching datacontract with no typos and property names matching the auto generated ones in the xxxModel.cs file.

Creating translators (little bit more involved) method

1. Use the following regex replace expression on the pasted properties from the class you created above.

Remember to paste them from the datatype definition onwards, and put them at the start of the line in the mapping class first! e.g.

String Author { get; set; }
String DMlibraryName { get; set; }
DateTime? DateCreated { get; set; }
String DocNAME { get; set; }
int? DocNumber { get; set; }
String DocPath { get; set; }
String DocTypeCode { get; set; }
String DocTypeDescription { get; set; }
Int32 IsDMType { get; set; }
Int32 IsRRAKMANType { get; set; }
int? PersonID { get; set; }
int? ProjectID { get; set; }
String ProjectLabel { get; set; }
String htmlLocation { get; set; }

Find: ^([a-zA-Z_$][a-zA-Z0-9_$?]*):b{(.*)}\{(.*)
Replace with: source.\1 = dest.\1;

Result is as follows...

source.Author  = document.Author;
source.DMlibraryName  = document.DMlibraryName;
source.DateCreated  = document.DateCreated;
source.DocNAME  = document.DocNAME;
source.DocNumber  = document.DocNumber;
source.DocPath  = document.DocPath;
source.DocTypeCode  = document.DocTypeCode;
source.DocTypeDescription  = document.DocTypeDescription;
source.IsDMType  = document.IsDMType;
source.IsRRAKMANType  = document.IsRRAKMANType;
source.PersonID  = document.PersonID;
source.ProjectID  = document.ProjectID;
source.ProjectLabel  = document.ProjectLabel;
source.htmlLocation  = document.htmlLocation;

(Old Creating translators (little bit more involved) method)

1. Turn resharper back on

2. Use the File Structure window

clip_image001

3. Stick this in Excel and do some manipulation (ask me if you're not sure how to do this)

clip_image002

4. Paste this back into your C# file, and do a regex replace of \t with nothing

5. That's it, translator code written

Friday, 14 September 2012

DataContract attribute gotcha

A little known fact that has caught out a few of our project team members this week, including myself. If you annotate a class with the DataContract attribute, then you must also ensure that the members you want to have serialized are also annotated with the DataMember / EnumMember attribute as well. The ones that aren't annotated will NOT get de-serialized when the data arrives at the consumer of your service method.

Note: If you apply no DataContract annotation at all to the class, then this has the same affect of attributing every member in your class with the DataMember / EnumMember attribute.

To be fair, this is somewhat eluded to in the following Microsoft article, although the part about it being implicit if you don't apply the attribute is not entirely obvious at first...

image

Silverlight 5 also supports a simplified opt-out model for serialization, where these attributes can be omitted from the type and the members of the type to be serialized. The data contract is implicit in the sense that the visibility modifiers (public, private) used by the type determines whether it and its members are included in the data contract. In this model, the name of a member is used to identify it in the serialized representation. A new IgnoreDataMemberAttribute attribute can be used to opt-out a member that is public when required.

Monday, 6 June 2011

Increasing WCF performance

Last week a colleague of mine discovered that for each WCF call, there are actually 2 round trips between client and the server going on using wireshark. This can especially be bad where the network latency on your site is also high, as for each request for data, there is the first call to authenticate the user, which then needs a reply back, then the actual call to get the data, which of course comes back as well, hence 4 x the network latency.

There are some solutions to this e.g. using a Secure Token Service, see http://msdn.microsoft.com/en-us/library/ee748498.aspx for more detail.

There is however an alternative to this which could provide better performance from http://www.noemax.com/

How to find the last interactive logons in Windows using PowerShell

Use the following powershell script to find the last users to login to a box since a given date, in this case the 21st April 2022 at 12pm un...