<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Anil Speaks</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/anilkumargupta/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 04:40:23 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Handling connection notification between a desktop machine and Windows CE based devices</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/handling-connection-notification-between-a-desktop-machine-and-windows-ce-based-devices</link>
      <pubDate>Sat, 16 May 2009 06:28:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/05/16/handling-connection-notification-between-a-desktop-machine-and-windows-ce-based-devices/</guid>
      <description><![CDATA[Introduction:
There are two ways that a desktop application can get notification when a Windows...]]></description>
      <content:encoded><![CDATA[<H2 style="COLOR: rgb(255,153,51)">Introduction:</H2>
<P>There are two ways that a desktop application can get notification when a Windows CE-based device gets connected with the desktop application.</P>
<OL>
<LI><STRONG>Registry based notification:</STRONG></LI></OL>
<P><STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </STRONG>Registry based notification has two predefined events, AutoStartOnConnect and AutoStartOnDisconnect, each of which has its own Registry key. We can register the command lines associated with the Registry key. Whenever the device gets connected with the desktop machine, the AutoStartOnConnect event will be triggered and all the command lines registered under this will be executed. Similarly, whenever a device gets disconnected from the desktop machine, the AutoStartOnDisconnect event will be triggered and all the command lines under the AutoStartOnDisconnect key will be executed.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For more details, refer to this MSDN link: <A title="Registry based notification" href="https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceactsy/html/ceconregistry-basednotification.asp" mce_href="https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceactsy/html/ceconregistry-basednotification.asp">Registry based notification.</A><BR></P>
<P><STRONG>&nbsp;&nbsp;&nbsp; 2.&nbsp;&nbsp; COM based notification</STRONG></P>
<P>It includes two interfaces, IDccMan provided by Rapi.dll, and IDccManSink implemented by the application which needs the notification. These interfaces handle connection and disconnection notification.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For more details, refer to the following link: <A title="COM based notification" href="https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceactsy/html/ceconcom-basednotification.asp" mce_href="https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceactsy/html/ceconcom-basednotification.asp">COM based notification.</A></P>
<P>The basic difference between these two methods is that when Registry based notification causes a program to run, we cannot get notifications in the application, whereas in COM based notification, you have control on the Connection Manager, registering and deregistering for connection notification, or any kind of operation that can be best handled by the application. In this article, our focus will be on COM based notification, which is better.</P>
<H2 style="COLOR: rgb(255,153,51)">Background:</H2>
<P>There exists very few articles on Smart Device connection notifications in .NET, especially in VB.NET. We wanted to get notifications when a desktop machine is connected with a Windows CE - based device. We could not find code in VB.NET, and finally decided to write it ourselves. We used COM based notifications for getting the Connection and Disconnection events.</P>
<H2 style="COLOR: rgb(255,153,51)">Using the Code:</H2>
<P mce_keep="true">Open the clsIDccMan.vb file in the code window. The file consists of the definitions of DccMan, DccManSink and the interfaces, IDccMan and IDccManSink. This file contains an import statement:</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">Imports System.Runtime.InteropServices</P>
<P mce_keep="true">This import statement is needed to define the COM attributes. The delegates mentioned below are used to register the events which will be raised on Connection and Disconnection. The ComVisible attribute is used so that these delegates may be visible in COM.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;Serializable()&gt; &lt;ComVisible(True)&gt; Public Delegate Sub ActiveHandler()</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;Serializable()&gt; &lt;ComVisible(True)&gt; Public Delegate Sub DisconnectHandler()</P>
<P mce_keep="true">This class is used to get the instance of IDccMan. The implementation of this class exists in the ActiveSync Connection Manager. We can see that a key exists corresponding to the "499C0C20-A766-11cf-8011-00A0C90A8F78" in Registry.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;ComImport(), Guid("499C0C20-A766-11cf-8011-00A0C90A8F78")&gt; _<BR>Public Class DccMan<BR>End Class</P>
<P mce_keep="true">This interface is used to get all the methods available in IDccMan. With the help of the IDccMan::Advise method, we can register IDccManSink.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;ComImport(), Guid("A7B88841-A812-11cf-8011-00A0C90A8F78"), _<BR>&nbsp; InterfaceType(ComInterfaceType.InterfaceIsIUnknown)&gt; _<BR>Public Interface IDccMan<BR>&nbsp;&nbsp;&nbsp; Function Advise(ByVal pDccSink As IDccManSink, _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ByRef dwContext As Int32) As Int32<BR>&nbsp;&nbsp;&nbsp; Function Unadvise(ByVal dwContext As Int32) As Int32<BR>&nbsp;&nbsp;&nbsp; Sub ShowCommSettings()<BR>&nbsp;&nbsp;&nbsp; Sub AutoconnectEnable()<BR>&nbsp;&nbsp;&nbsp; Sub AutoconnectDisable()<BR>&nbsp;&nbsp;&nbsp; Sub ConnectNow()<BR>&nbsp;&nbsp;&nbsp; Sub DisconnectNow()<BR>&nbsp;&nbsp;&nbsp; Sub SetIconDataTransferring()<BR>&nbsp;&nbsp;&nbsp; Sub SetIconNoDataTransferring()<BR>&nbsp;&nbsp;&nbsp; Sub SetIconError()<BR>End Interface</P>
<P mce_keep="true">This interface is used to get all the methods available in the IDccManSink.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;Guid("A7B88840-A812-11cf-8011-00A0C90A8F78"), _<BR>&nbsp;&nbsp; InterfaceType(ComInterfaceType.InterfaceIsIUnknown)&gt; _<BR>Public Interface IDccManSink<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogIpAddr(&lt;InAttribute()&gt; ByVal _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwIpAddr As Int32) As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogTerminated() As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogActive() As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogInactive() As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogAnswered() As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogListen() As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogDisconnection() As Int32<BR>&nbsp;&nbsp;&nbsp; &lt;PreserveSig()&gt; Function OnLogError() As Int32<BR>End Interface</P>
<P mce_keep="true">DccManSink is the main class. An object of this class is sent to the ActiveSync Connection Manager to get the notification on Connection / Disconnection. When the connection between the desktop computer and the device is established, the Connection Manager calls the IDccManSink::OnLogListen method. Once the remote connection services of both the desktop computer and the device respond, the Connection Manager calls the IDccManSink::OnLogAnswered method. When the Connection Manager has detected the communications interface, it calls the IDccManSink::OnLogActive method. Now, once the connection is established between the device and the Connection Manager, the Connection Manager calls the IDccManSink::OnLogIpAddr method. Finally, the IDccManSink::OnLogIpAddr method is invoked, and this completes the connection.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;Guid("C6659361-1625-4746-931C-36014B146679")&gt; _<BR>Public Class DccManSink<BR>&nbsp;&nbsp;&nbsp; Implements IDccManSink<BR>&nbsp;&nbsp;&nbsp; Public Event Active As ActiveHandler<BR>&nbsp;&nbsp;&nbsp; Public Event Disconnect As DisconnectHandler<BR>&nbsp;&nbsp;&nbsp; Public Function OnLogActive() As Int32 _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Implements IDccManSink.OnLogActive<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RaiseEvent Active()<BR>&nbsp;&nbsp;&nbsp; End Function &nbsp;&nbsp;&nbsp; <BR>Public Function OnLogAnswered() As Int32 _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Implements IDccManSink.OnLogAnswered<BR>&nbsp;&nbsp;&nbsp; End Function <BR>&nbsp;&nbsp;&nbsp; Public Function OnLogDisconnection() As Int32 _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Implements IDccManSink.OnLogDisconnection<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RaiseEvent Disconnect()<BR>&nbsp;&nbsp;&nbsp; End Function <BR>&nbsp;&nbsp;&nbsp; Public Function OnLogError() As Int32 Implements IDccManSink.OnLogError<BR>&nbsp;&nbsp;&nbsp; End Function <BR>&nbsp;&nbsp;&nbsp; Public Function OnLogInactive() As Int32 _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Implements IDccManSink.OnLogInactive<BR>&nbsp;&nbsp;&nbsp; End Function <BR>&nbsp;&nbsp;&nbsp; Public Function OnLogIpAddr(ByVal dwIpAddr As Int32) _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Int32 Implements IDccManSink.OnLogIpAddr<BR>&nbsp;&nbsp;&nbsp; End Function <BR>&nbsp;&nbsp;&nbsp; Public Function OnLogListen() As Int32 Implements IDccManSink.OnLogListen<BR>&nbsp;&nbsp;&nbsp; End Function <BR>&nbsp;&nbsp;&nbsp; Public Function OnLogTerminated() As Int32 _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Implements IDccManSink.OnLogTerminated<BR>&nbsp;&nbsp;&nbsp; End Function<BR>End Class 
<P mce_keep="true">Open the RegisterIDccManSink.vb file in the code window. The file consists of two button click events, which are used to register and unregister the IDccManSink in Connection Manager. In the btnRegister button Click event (btnRegister_Click), we initialize the objects of IDccMan, IDccManSink, DccMan, and DccManSink. The methods are then registered in the events that will be executed on Connection/Disconnection. With the help of the line, objIDccMan.Advise(objDccManSink, intAdvaiceReturn), we register the object of DccManSink which implements IDccManSink. Here, we are passing the object of DccManSink and an integer type variable. This variable will be used to unregister the events.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">Private Sub btnRegister_Click(ByVal sender As System.Object, _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ByVal e As System.EventArgs) Handles btnRegister.Click<BR>&nbsp;&nbsp;&nbsp; 'To create the object of DccMan class.<BR>&nbsp;&nbsp;&nbsp; 'It is used to get the object of IDccMan<BR>&nbsp;&nbsp;&nbsp; 'becuase we can not create the object of interface directly.<BR>&nbsp;&nbsp;&nbsp; Dim objDccMan As DccMan = New DccMan()<BR>&nbsp;&nbsp;&nbsp; 'To create the object of IDccMan class.<BR>&nbsp;&nbsp;&nbsp; objIDccMan = CType(objDccMan, IDccMan)<BR>&nbsp;&nbsp;&nbsp; 'To create the object of DccManSink class. <BR>&nbsp;&nbsp;&nbsp; 'It is used to get the object of IDccManSink<BR>&nbsp;&nbsp;&nbsp; Dim objDccManSink As DccManSink = New DccManSink()<BR>&nbsp;&nbsp;&nbsp; 'To create the object of IDccManSink<BR>&nbsp;&nbsp;&nbsp; 'Dim objIDccManSink As IDccManSink = _<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CType(objDccManSink, IDccManSink)<BR>&nbsp;&nbsp;&nbsp; 'To initialize the event handlers.<BR>&nbsp;&nbsp;&nbsp; AddHandler objDccManSink.Active, AddressOf OnConnection<BR>&nbsp;&nbsp;&nbsp; AddHandler objDccManSink.Disconnect, AddressOf OnDisConnection<BR>&nbsp;&nbsp;&nbsp; 'To register the IDccManSink<BR>&nbsp;&nbsp;&nbsp; objIDccMan.Advise(objDccManSink, intAdvaiceReturn)<BR>End Sub</P>
<P mce_keep="true">We can call the UnAdvice method of DccManSink to deregister DccManSink.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">'To unregister the IDccManSink<BR>objIDccMan.Unadvise(intAdvaiceReturn)<BR></P>
<P mce_keep="true">This example was intended to provide an example with the help of which we can get the notification on Connection and Disconnection, when any desktop machine is connected with Windows CE- based devices. I used it in my application for displaying the connection status between the desktop machine and the device.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/62/22/49/GetNotificationOnConnect_src.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-62-22-49/GetNotificationOnConnect_5F00_src.zip">GetNotificationOnConnect_src.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>WCF Intermediate Service between client and server</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/wcf-intermediate-service-between-client-and-server</link>
      <pubDate>Sat, 16 May 2009 05:51:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/05/16/wcf-intermediate-service-between-client-and-server/</guid>
      <description><![CDATA[Introduction:
The purpose of this article is to create a WCF service which can work as load...]]></description>
      <content:encoded><![CDATA[<H2 style="COLOR: rgb(255,153,51)">Introduction:</H2>
<P>The purpose of this article is to create a WCF service which can work as load balancer or router.Hosting a WCF service requires creating the service contract, Data contract and configure end points, host the service, generate the Web Service Description Language(WSDL), enable metadata exchange point so that client can create the proxy. Both the client and server channel should be agree on addressing, binding and message filtering. Sometimes the product requires some additional features like logging, routing, load balancing or introducing a security boundary. We can easily introduce intermediate service and achieve these kind of features by some tweaking in addressing and filtering behavior.</P>
<H2 style="COLOR: rgb(255,153,51)">Using the Code:</H2>
<P mce_keep="true">The attached source contain following projects.</P>
<OL>
<LI>
<DIV mce_keep="true"><STRONG>TargetServiceContract:</STRONG> contract for the target WCF service.</DIV></LI>
<LI>
<DIV mce_keep="true"><STRONG>TargetHost:</STRONG> Host console application for target WCF Service.</DIV></LI>
<LI>
<DIV mce_keep="true"><STRONG>IntermediateServiceContract:</STRONG> Service contract which can work as load balancer or router.</DIV></LI>
<LI>
<DIV mce_keep="true"><STRONG>IntermediateServiceHost:</STRONG> Host console application which host the IntermediateServiceContract.</DIV></LI>
<LI>
<DIV mce_keep="true"><STRONG>Client:</STRONG> it is the client project which consumes the WCF target service.</DIV></LI></OL>
<P mce_keep="true">Using the operation type in an operation signature doesn’t by definition mean that any message can be processed by the service. By default Action header is used to target the particular operation. The service model inspects incoming message and looks for an operation on the endpoint that has a matching action header. If it can’t find a match, the request is rejected.</P>
<P mce_keep="true">When would action headers not match the operation being invoked? One possibility is when an intermediary or routing service is placed between the client and the application service. In this scenario, the client application doesn’t know of the presence of the intermediate service and the action header targets the application service.</P>
<P mce_keep="true">Action header indicates the URI for the operation to be invoked. It is generated by concatenating the service contract namespace with the service contract friendly name and the operation name.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true"><A href="https://example/IntermediateService/TargetServiceContract/VerifyMessage" mce_href="https://example/IntermediateService/TargetServiceContract/VerifyMessage">https://Example/IntermediateService/TargetServiceContract/VerifyMessage</A></P>
<P mce_keep="true">The reply action appends “Response” to this.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true"><A href="https://example/IntermediateService/TargetServiceContract/VerifyMessageResponse" mce_href="https://example/IntermediateService/TargetServiceContract/VerifyMessageResponse">https://Example/IntermediateService/TargetServiceContract/VerifyMessageResponse</A> </P>
<P mce_keep="true">Client can generate the same Action, ReplyAction and proxy setting by generating the service proxy. Here is the code which is generated from the proxy.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">[System.ServiceModel.OperationContractAttribute(<BR>&nbsp;&nbsp;&nbsp; Action="<A href="https://example/IntermediateService/TargetServiceContract/VerifyMessage" mce_href="https://example/IntermediateService/TargetServiceContract/VerifyMessage">https://Example/IntermediateService/TargetServiceContract/VerifyMessage</A>",<BR>&nbsp;&nbsp;&nbsp; ReplyAction="<A href="https://example/IntermediateService/TargetServiceContract/VerifyMessageResponse" mce_href="https://example/IntermediateService/TargetServiceContract/VerifyMessageResponse">https://Example/IntermediateService/TargetServiceContract/VerifyMessageResponse</A>")]<BR>&nbsp;string VerifyMessage(string message);</P>
<P mce_keep="true">The client binding configuration will reflect physical address. Here is the client endpoint setting which have the physical address as the address of the target service. We can generate it by creating the service reference by using the metadata endpoint("<A href="https://localhost:8001/TargetService/Mex" mce_href="https://localhost:8001/TargetService/Mex">https://localhost:8001/TargetService/Mex</A>").</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&nbsp;&nbsp;&nbsp; &lt;endpoint address="<A href="https://localhost:8001/TargetService" mce_href="https://localhost:8001/TargetService">https://localhost:8001/TargetService</A>" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; binding="wsHttpBinding"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bindingConfiguration="wsHttpEndPoint"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contract="TargetServiceClient.TargetServiceContract"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="wsHttpEndPoint" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; behaviorConfiguration="clientBehavior" /&gt;<BR></P>
<P mce_keep="true">When client send any message to service, message is sent to physical address with action mentioned in the generated proxy file.</P>
<H3 mce_keep="true">Intermediate Service:</H3>
<P>Intermediate service is designed to receive messages that can target any service and it must be able to forward the original message to appropriate service without any change in the body of the message. The intermediate service may only look at only the message headers but the original message elements should be forwarded without any change.</P>
<P style="BACKGROUND: rgb(192,192,192)">&nbsp;&nbsp;&nbsp; [OperationContract(Name="ProcessMessage",Action="*",ReplyAction="*")]<BR>&nbsp;&nbsp;&nbsp; Message ProcessMessage(Message message);</P>
<P mce_keep="true">&nbsp;</P>
<P>In case if the Action and ReplyAction is * then the all the messages are dispatched to the same operation and only one operation can have Action and ReplyAction as * in the service contract. Since Channel dispatcher always gets the input argument as Message type(defined in System.ServiceModel.Channels) and return the value as Message type so the intermediate service should have operation which has Input argument and return type as Message. This operation can work as target of any request.<BR></P>
<H3>Forwarding Message to original service:</H3>
<P>Service proxy usually has strongly typed operation but in intermediate service we use a generic proxy operation which can send any type as input argument and receive any type as response. Since the contract has untyped message, the same message can be sent to the service and the response can be directly sent to the client. Intermediate service doesn't do any other change except changing the To address to send the message to the appropriate service.<BR></P>
<H3>Sending the request to Intermediate service:</H3>
<P>When and intermediate service is introduced, it is always best if the client can send messages using the correct To header for the service while still sending the message to the intermediate service. The first way to achieve this is to configure ClientViaBehavior as mentioned bellow. This tells the client to generate the message which would have the To header as the end point service address but it would go via the intermediate service.</P>
<P style="BACKGROUND: rgb(192,192,192)">&lt;client&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;endpoint address="<A href="https://localhost:8002/IntermediateServiceExample">https://localhost:8002/IntermediateServiceExample</A>" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; binding="wsHttpBinding"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bindingConfiguration="wsHttpEndPoint"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contract="TargetServiceClient.TargetServiceContract"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="wsHttpEndPoint" behaviorConfiguration="clientBehavior"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/endpoint&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/client&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;behaviors&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;endpointBehaviors&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;behavior name="clientBehavior"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;clientVia viaUri="<A href="https://localhost:8002/IntermediateServiceExample%22/">https://localhost:8002/IntermediateServiceExample%22/</A>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/behavior&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/endpointBehaviors&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/behaviors&gt;</P>
<P>The another way to achieve this to mention the listenuri in the target service so that the logical address of the target service can be the address of intermediate service and physical address can be the endpoint address. In this case when the client generates the proxy, it would have the address as the address of the intermediate service.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&lt;endpoint address="<A href="https://localhost:8002/IntermediateServiceExample">https://localhost:8002/IntermediateServiceExample</A>"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; binding="wsHttpBinding"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bindingConfiguration="wsHttpBinding" name="wsHttpEndPoint"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contract="IntermediateServiceExample.ITargetServiceContract"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listenUri="<A href="https://localhost:8001/TargetService">https://localhost:8001/TargetService</A>" /&gt;<BR></P>
<P mce_keep="true">In this scenario the service must be aware of the intermediate service which I think is wrong so it is better to tell the intermediate service address to the client and client can use the first way. The client sends the message to intermediate service with To header as the target service address. Thus, the To header will never match the router's logical address. By default, services use the EndpointAddressMessageFilter to determine whether a message's To header matches any of its configured endpoints. Since a router can't expect this to work, it should install the MatchAllMessageFilter. We can achieve this by using the following filter. It passes all the to header messages.</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">&nbsp;&nbsp;&nbsp; [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AddressFilterMode = AddressFilterMode.Any)]<BR>&nbsp;&nbsp;&nbsp; public class IntermediateServiceManager : IIntermediateServiceContract<BR></P>
<P mce_keep="true">Now when the client sends any message, it would go via the intermediate service. The intermediate service can load balance it or do the routing, send the request to appropiate service,get the response and return the same response to the client. Since all the requests from the client and all the response from the target service would go via the intermediate service, we can do logging, tracing for each and every message going through the channel.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/62/21/14/WCFIntermediateService_src.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-62-21-14/WCFIntermediateService_5F00_src.zip">WCFIntermediateService_src.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Serialization in Windows Communication Foundation</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/serialization-in-windows-communication-foundation</link>
      <pubDate>Fri, 08 May 2009 12:03:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/05/08/serialization-in-windows-communication-foundation/</guid>
      <description><![CDATA[Introduction:
In most scenarios, when we design a service, we create a service contract and data...]]></description>
      <content:encoded><![CDATA[<H2 style="COLOR: rgb(255,153,51)">Introduction:</H2>
<P>In most scenarios, when we design a service, we create a service contract and data contracts for the types used in the service. We let the service description be generated by the service contract, and we won’t ever have to look at the underlying XML, but sometimes, things don’t go that well in situations like preexisting types which implement SerializableAttribute and ISerializable, mapping an incoming message to types which are not serializable or which don’t match the predefined schema.</P>
<P>Internally, WCF represents all the messages with the Message class which is defined in the System.ServiceModel.Channels namespace. The Message class generate a SOAP envelop which consists of a message header and a message body. The message body contains the payload. The Message class provides an interface to interact with the message body or the message header.</P>
<P>The most common way of serialization in a WCF service is to mark the type with the DataContract attribute and mark each member which is to be serialized with the DataMember attribute.</P>
<H2 style="COLOR: rgb(255,153,51)">Types that support serialization:</H2>
<UL>
<LI>Types marked with DataContractAttribute or CollectionDataContractAttribute.</LI>
<LI>Types decorated with SerializableAttribute which can optionally implement the ISerializable or IXmlSerializable interface.</LI>
<LI>MessageContract decorated with MessageContractAttribute and containing the data contracts or the serializable types as header or body.</LI>
<LI>We can include any of these types, but the resulting message format will change based on the choice of the serializer.</LI></UL>
<P>There are two types of serializers: DataContractSerializer and XmlSerializer. By default, WCF uses DataContractSerializer for message serialization. Here are the differences between both the serializers.</P>
<UL>
<LI>In the case of DataContract, the DataContractSerializer serializes the fields marked with the DataMember attribute (irrespective of public or private), while XmlSerializer serializes only public properties and fields.</LI>
<LI>In the case of SerializableAttribute, the DataContractSerializer serializes all fields, while XmlSerializer serializes only the public fields.</LI>
<LI>In the case of the IXmlserializable interface, we provide the schema and control the serialization.</LI>
<LI>In the case of MessageContract, the DataContractSerializer serializes members marked with the header or body attribute, while XmlSerializer serializes only the public properties or fields.</LI>
<LI>In the case of DataContractSerializer, constructors are not called during deserialization. However, if you need to perform initialization, DataContractSerializer supports the [OnDeserializing], [OnDeserialized], [OnSerializing], and [OnSerialized] callbacks that were also supported on the Binary/SoapFormatter classes.</LI></UL>
<H2 style="COLOR: rgb(255,153,51)">Message encoding:</H2>
<P mce_keep="true">There exists two types of encoding, Document/literal and RPC. Actually, they are two programming models, one is the RPC programming model and the other is the Message Passing programming model. One programming model says that if you are talking to a service, you should always explicitly form a message and use explicit message-passing infrastructure to send the message to the service and, optionally, to receive the response. The following is an example of a potential implementation of such a mechanism (from the caller's perspective):<BR></P>
<P style="BACKGROUND: rgb(192,192,192)">Channel chan = new ChannelFactory.CreateChannel(endpointAddress);<BR>ActionInvocationMessage msg = new ActionInvocationMessage();<BR>msg.Action = "SayHello";<BR>msg.Parameters.Add(new StringParameter("Forename", "Rich"));<BR>msg.Parameters.Add(new StringParameter("Surname", "Turner"));<BR>Console.WriteLine(chan.SendMessageSync(msg, new SayHelloCallback(HandleResponse)));<BR></P>
<P mce_keep="true">The other camp aims to simplify the developer experience by reusing development constructs in wide use today, that results in code such as the following:</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">HelloWorldProxy proxy = new HelloWorldProxy(endpointAddress);<BR>Console.WriteLine(proxy.SayHello("Rich", "Turner"));<BR></P>
<P mce_keep="true">In both the DataContractSerializer and the XmlSerializer, default the value of style is document/literal format, but we can use RPC encoding using the OperationFormatStyle enumeration in the event you need it. Each serializer has a style property based on the enumeration, and can be set to one of its two elements, Document and RPC.<BR></P>
<H3>DataContractFormatAttribute:</H3>
<P>We can use the RPC style like this:</P>
<P style="BACKGROUND: rgb(192,192,192)">[ServiceContract(Name="ServiceContract",<BR>&nbsp;&nbsp;&nbsp;&nbsp; Namespace="<A href="https://www.servicecontract.com/Samples/RPCExample" mce_href="https://www.ServiceContract.com/Samples/RPCExample">https://www.ServiceContract.com/Samples/RPCExample</A>")]<BR>&nbsp;&nbsp;&nbsp;&nbsp; [DataContractFormat(Style=OperationFormatStyle.Rpc)]<BR>&nbsp;&nbsp;&nbsp;&nbsp; public interface IRPCStyleTest</P>
<H3>XmlSerializerFormatAttribute:</H3>
<P>We can support the RPC style in the case of XmlSerializer like this:</P>
<P style="BACKGROUND: rgb(192,192,192)">[ServiceContract(Name="ServiceContract",<BR>&nbsp;&nbsp;&nbsp;&nbsp; Namespace="<A href="https://www.servicecontract.com/Samples/RPCExample">https://www.ServiceContract.com/Samples/RPCExample</A>")]<BR>&nbsp;&nbsp;&nbsp;&nbsp; [XmlSerializerFormat(Style=OperationFormatStyle.Rpc,<BR>&nbsp;&nbsp;&nbsp;&nbsp; Use=OperationFormatUse.Encoded)]<BR>&nbsp;&nbsp;&nbsp;&nbsp; public interface IRPCStyleTest<BR></P>
<H2 style="COLOR: rgb(255,153,51)">Serialization/Encoding:</H2>
<P>Actually, there exists two contracts when discussing .NET types in the context of serialization. First is the .NET contract which has properties, methods, and constructors, and the other is the contract which has the serializable properties and which would be exposed to the word. Each serializer comes with some algorithms which define the mapping details, and includes attributes that let us customize the mapping. This mapping is stored with the metadata which serializers can access at runtime and decide which property to serialize.</P>
<P>There exists an inbuilt tool (svc.exe) for moving between these contract representations. We can use xsd.exe while working with XmlSerializer. Svc.exe can generate the .NET data type with all the attributes from the XML schema definition. If we pass a .NET assembly to svc.exe, it will automatically generate all the types which support serialization. So, we can write the data contracts in either XML schema or in .NET code.</P>
<P>Windows Communication Foundation lets us specify the encoding to be used. Serialization defines how the .NET object maps to XML, while Encoding defines how the XML is written out to a stream of bytes. WCF supports three types of encoding: text, binary, and message transmission optimization mechanism (MTOM). We can also add custom encoding.</P>
<P>If you represent the same logical data by the three encodings, the stream will be totally different, but they all represent the same logical data. Encoding isn’t considered to be part of the service contract, but it is the configuration entry. We can change it dynamically, and we can control it by endpoint binding. Different kinds of encoding are used in different types of word scenarios. If interoperability is a concern, then text type encoding is used, while if performance is the concern, then binary encoding can be used.</P>
<P>When WCF creates a message at runtime, it chooses the serializer based on the service contract, and selects the encoding based on the binding configuration. Let’s see how this is accomplished. We can take the following type for understanding the serializers:</P>
<P style="BACKGROUND: rgb(192,192,192)">[DataContract]<BR>public class Name<BR>{<BR>&nbsp;&nbsp;&nbsp; [DataMember]<BR>&nbsp;&nbsp;&nbsp; public string firstName;<BR>&nbsp;&nbsp;&nbsp; public string middlename;<BR>&nbsp;&nbsp;&nbsp; [DataMember]<BR>&nbsp;&nbsp;&nbsp; public string lastName;<BR>}</P>
<H3>DataContractSerializer:</H3>
<P>We can use the following method to generate the serialized stream from DataContractSerializer:</P>
<P style="BACKGROUND: rgb(192,192,192)">public static void SerializeClass()<BR>{<BR>&nbsp;&nbsp;&nbsp; Name name = new Name { firstName = "John", <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; middlename = "Fuma", lastName = "last" };<BR>&nbsp;&nbsp;&nbsp; using (Message message = Message.CreateMessage(MessageVersion.Soap11WSAddressing10,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "<A href="https://www.servicecontract.com/Samples/RPCExample/Name">https://www.ServiceContract.com/Samples/RPCExample/Name</A>", name,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new DataContractSerializer(typeof(Name))))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (FileStream fs = new FileStream("binary.bin", FileMode.Create))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (XmlDictionaryWriter writer = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDictionaryWriter.CreateBinaryWriter(fs))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message.WriteMessage(writer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR>}</P>
<P>The CreateMessage method’s last parameter specifies the serializer. The serializer controls how the message body has the Name object as XML. The writer determines which encoding will be used to write the message out to the byte stream. XmlDictionaryWriter and XmlDictionaryReader can be used to read and write the type in any encoding (text, binary, MTOM).</P>
<P>The following method can be used to generate the Name type again from the bin file. We can use XmlDictionaryReader and the corresponding decoder to do the reverse engineering, and get the original message.</P>
<P style="BACKGROUND: rgb(192,192,192)">public static void ReadSerializeClass()<BR>{<BR>&nbsp;&nbsp;&nbsp; using (FileStream fs = File.OpenRead("binary.bin"))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (XmlDictionaryReader reader = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDictionaryReader.CreateBinaryReader(fs, XmlDictionaryReaderQuotas.Max))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (Message message = Message.CreateMessage(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reader, 1024, MessageVersion.Soap11WSAddressing10))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // deserialize Person object from XML<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name name = message.GetBody(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new DataContractSerializer(typeof(Name)));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>In case we don’t want to read the XML infoset directly, we can call GetReaderAtBodyContents instead of GetBody, which returns the XmlReader and reads the specific elements.</P>
<H3>XmlSerializer:</H3>
<P>XmlSerializer is quite an old technology which is used in web services. Windows Communication Foundation supports it for backwards compatibility. I am not going to discuss a lot about it as there are a lot of articles about it available already. Here is the sample code which serializes the same Name object. We can see that it includes the middle name too as middle name is the public property.</P>
<P>Serialization method:</P>
<P style="BACKGROUND: rgb(192,192,192)">public static void WriteNameXmlSerializer()<BR>{<BR>&nbsp;&nbsp;&nbsp; Name name = new Name { firstName = "John", <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; middlename = "Fuma", lastName = "last" };<BR>&nbsp;&nbsp;&nbsp; using (FileStream fs = new FileStream("Name.xml", FileMode.Create))<BR>&nbsp;&nbsp;&nbsp; using (XmlDictionaryWriter writer =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDictionaryWriter.CreateTextWriter(fs))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlSerializer serializer = new XmlSerializer(typeof(Name));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serializer.Serialize(writer, name);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>Serialized stream:</P>
<P style="BACKGROUND: rgb(192,192,192)">&lt;Name xmlns:xsi="<A href="https://www.w3.org/2001/XMLSchema-instance">https://www.w3.org/2001/XMLSchema-instance</A>" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:xsd="<A href="https://www.w3.org/2001/XMLSchema">https://www.w3.org/2001/XMLSchema</A>"&gt;<BR>&nbsp; &lt;firstName&gt;John&lt;/firstName&gt;<BR>&nbsp; &lt;middlename&gt;Fuma&lt;/middlename&gt;<BR>&nbsp; &lt;lastName&gt;last&lt;/lastName&gt;<BR>&lt;/Name&gt;</P>Deserialization method: 
<P style="BACKGROUND: rgb(192,192,192)">public static void ReadNameXmlSerializer()<BR>{<BR>&nbsp;&nbsp;&nbsp; using (FileStream fs = new FileStream("Name.xml", FileMode.Open))<BR>&nbsp;&nbsp;&nbsp; using (XmlDictionaryReader reader =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDictionaryReader.CreateTextReader(fs, XmlDictionaryReaderQuotas.Max))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlSerializer serializer = new XmlSerializer(typeof(Name));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name person = (Name)serializer.Deserialize(reader);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<H3>NetDataContractSerializer:</H3>
<P mce_keep="true">DataContractSerializer has two modes: SharedContract and SharedType. The modes reflect whether you want to share the schema contract across the wire or the .NET type information.</P>
<P mce_keep="true">In general, sharing schema contract is the preferred and recommended approach, as it loosens the coupling across the wire, but WCF still wants to support .NET Remoting style applications where maintaining type across the wire is important. WCF spilts both the modes into separate classes, so now, WCF has DataContractSerializer (SharedContract) and NetDataContractSerializer (SharedType). Since WCF wants to encourage DataContractSerializer, it is the default serializer.</P>
<P mce_keep="true">NetDataContractSerializer supports the same mapping algorithm and the same customization attributes, but in the case of NetDataContractSerializer, type information is not required ahead of time as in DataContractSerializer. We can see it from the following code:</P>
<P style="BACKGROUND: rgb(192,192,192)" mce_keep="true">// no type specified<BR>NetDataContractSerializer serializer = new NetDataContractSerializer();<BR>serializer.WriteObject(writer, p);<BR></P>
<P mce_keep="true">We can use the following method to serialize the Name class:</P>
<P style="BACKGROUND: rgb(192,192,192)">public static void SerializeClass()<BR>{<BR>&nbsp;&nbsp;&nbsp; Name name = new Name { firstName = "John", middlename = "Fuma", lastName = "last" };<BR>&nbsp;&nbsp;&nbsp; NetDataContractSerializer netData = new NetDataContractSerializer();<BR>&nbsp;&nbsp;&nbsp; using (FileStream fs = new FileStream("NetData.xml", FileMode.Create))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; netData.Serialize(fs, name);<BR>&nbsp;&nbsp;&nbsp; }<BR>} </P>
<P mce_keep="true">Here is the serialized stream. It contains the type information, so there is no need for specifying the type while doing the deserialization.</P>
<P style="BACKGROUND: rgb(192,192,192)">&lt;Name z:Id="1" z:Type="HelloIndigo.Name" z:Assembly="HelloIndigo,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns="<A href="https://schemas.datacontract.org/2004/07/HelloIndigo">https://schemas.datacontract.org/2004/07/HelloIndigo</A>" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:i="<A href="https://www.w3.org/2001/XMLSchema-instance">https://www.w3.org/2001/XMLSchema-instance</A>" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:z="<A href="https://schemas.microsoft.com/2003/10/Serialization/">https://schemas.microsoft.com/2003/10/Serialization/</A>"&gt;<BR>&nbsp; &lt;firstName z:Id="2"&gt;John&lt;/firstName&gt;<BR>&nbsp; &lt;lastName z:Id="3"&gt;last&lt;/lastName&gt;<BR>&lt;/Name&gt;</P>
<P>Following are some precautions that we have to take while doing the serilalization:</P>
<UL>
<LI>When serializing types that use inheritance, all the types in the hierarchy should be serializable either via the DataContract or the Serializable attribute.</LI>
<LI>WCF also provide a KnowType attribute which can be used to substitute the type which serializers will recognize at runtime. This lets us specify the Serializable attribute to some base type and send some derived type.</LI>
<LI>We can use IDataContractSurrogate in case we find that there is some property which is not serializable. We can implement this interface, and the serializer will call it while doing the serialization.</LI></UL>
<H2 style="COLOR: rgb(255,153,51)">Conclusion:</H2>
<P>Windows Communication Foundation takes care of everything, but it is important to understand how each serializer works and which one is the best on a particular scenario. You should use DataContractSerializer whenever possible in WCF. It provides interoperability. NetDataContractSerializer should be used when you need type fidelity across the wire. You should user XmlSerializer when you need backwards compatibility with ASMX pages, or you are starting with the existing types which don’t follow the DataContract rules.</P>
<P mce_keep="true">&nbsp;</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/59/73/14/Host.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-59-73-14/Host.zip">Host.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Playing Subtitles with Videos in Silverlight</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/playing-subtitles-with-videos-in-silverlight</link>
      <pubDate>Fri, 01 May 2009 05:27:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/05/01/playing-subtitles-with-videos-in-silverlight/</guid>
      <description><![CDATA[Introduction:
This article is about playing subtitles in a video in Silverlight. It is really very...]]></description>
      <content:encoded><![CDATA[<H2 style="COLOR: rgb(255,153,51)">Introduction:</H2>
<P>This article is about playing subtitles in a video in Silverlight. It is really very easy to implement this functionality. 
<H2 style="COLOR: rgb(255,153,51)">Background:</H2>
<P>I had a requirement for playing titles with videos in Silverlight.</P>
<P>I started implementing this feature by using a timer. We can set the timer interval to 500 ms and the timer will trigger the event every 500 ms. We can put our logic to show/hide the title bar and achieve our goal, but this approach has an issue. There will be buffering in the video and that will make the timer out of sync with the position of the video, so this approach can't handle the media buffering scenario.</P>
<P>I found another way to implement the same. MediaElement has a collection of timeline markers associated with the currently loaded media element. The collection is cleared and repopulated each time the MediaElement opens a new media file, and is only considered valid after the MediaOpened event has occurred. For more information on markers, follow this link: </P>
<P><A href="https://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.markers(VS.95).aspx" mce_href="https://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.markers(VS.95).aspx">https://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.markers(VS.95).aspx</A>.</P>
<P>The reader should be aware of Silverlight basics and the MediaElement control to follow this article.</P>
<H2 style="COLOR: rgb(255,153,51)">Using the Code:</H2>
<P>I didn't add the media file with the Zip file, so before running the solution, you have to add a WMV file with the name "SUP015.wmv" in the ClientBin folder of the web project.</P>
<P>Define the title class which should have the start time of the title, the end time of the title, and the message of the title.<BR></P>
<P style="BACKGROUND: rgb(192,192,192)">public class Title<BR>{<BR>&nbsp;&nbsp;&nbsp; public string Id { get; set; }<BR>&nbsp;&nbsp;&nbsp; public double InTime { get; set; }<BR>&nbsp;&nbsp;&nbsp; public double OutTime { get; set; }<BR>&nbsp;&nbsp;&nbsp; public string Message { get; set; }<BR>}</P>
<P>We can use the MarkerReached event to get a notification whenever the video reaches the title start or end time. The MarkerReached event is not raised when the MediaElement seeks past a timeline marker. This event is raised whenever a marker associated with the media is reached. The marker might come from one of three locations: stored in the metadata of the currently opened media, associated with the currently opened media, or coming from a separate stream, explicitly added to the Markers collection for the currently opened media, using script. We can subscribe to the above event in the MediaElement loaded event.</P>
<P style="BACKGROUND: rgb(192,192,192)">this.MediaEl.MarkerReached += <BR>&nbsp; new TimelineMarkerRoutedEventHandler(MediaEl_MarkerReached);</P>
<P>Before playing the media, we have to add markers for all the titles. We can use the two properties of the markers for this: Time and Type. Time is the time span at which the MediaElement will raise the MarkerReached event, and Type is a string which can be used to identify the title when the MarkerReached event occurs. We can use the following code to add all the titles to the Markers collection:</P>
<P style="BACKGROUND: rgb(192,192,192)">private void AddMarker()<BR>{<BR>&nbsp;&nbsp;&nbsp; foreach(Title comment in list)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.MediaEl.Markers.Add(new TimelineMarker(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Time = TimeSpan.FromSeconds(comment.InTime),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Type = comment.Id.ToString() + ":Start", Text = "Test"});<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.MediaEl.Markers.Add(new TimelineMarker() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Time = TimeSpan.FromSeconds(comment.OutTime),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Type = comment.Id.ToString() + ":End", Text = "Test" });<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>Here, we are using Type to identify the title as well as if it's the start or the end of the title. We are adding every title twice to the Markers collection, once for the start of the title and once for the end of the title.</P>
<P>Following is the code for the MarkerReached event:</P>
<P style="BACKGROUND: rgb(192,192,192)">private void MediaEl_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)<BR>{<BR>&nbsp;&nbsp;&nbsp; string[] array = e.Marker.Type.Split(':');<BR>&nbsp;&nbsp;&nbsp; if(array != null &amp;&amp; array.Length == 2)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(array[1] == "Start")<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title comment = list.SingleOrDefault(x =&gt; x.Id == array[0]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(comment != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.CommentCanas.Visibility = System.Windows.Visibility.Visible;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CommentText.Text = comment.Message + " TimeSpan:" +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.MediaEl.Position.ToString();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(array[1] == "End")<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.CommentCanas.Visibility = System.Windows.Visibility.Collapsed;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CommentText.Text = string.Empty;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>We can get the Type value of the marker from the event arguments. The Type contains the unique ID of the title to identify the title, and Start or End to identify the start or end of the title. If it is Start, then we can set the Visibility of the Canvas to Visible and set the text. If it is End, then we can set the Visibility of the Canvas to Collapsed.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/58/21/56/TitlesInVideoPlayer_src.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-58-21-56/TitlesInVideoPlayer_5F00_src.zip">TitlesInVideoPlayer_src.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>DownloadProgress, DownloadProgressOffset, and BufferProgress of the MediaElement</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/downloadprogress-downloadprogressoffset-and-bufferprogress-of-the-mediaelement</link>
      <pubDate>Wed, 29 Apr 2009 05:24:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/04/29/downloadprogress-downloadprogressoffset-and-bufferprogress-of-the-mediaelement/</guid>
      <description><![CDATA[Introduction:
This article is about the DownloadProgress, DownloadProgressOffset, and...]]></description>
      <content:encoded><![CDATA[<h2 style="color: rgb(255, 153, 51);">Introduction:</h2>
<p>This article is about the DownloadProgress, DownloadProgressOffset, and BufferProgress properties of MediaElement.</p>
<h2 style="color: rgb(255, 153, 51);">Background:</h2>
<p>I was working with MediaElement as I had a requirement to play a video from an HTTP URL. I encountered a strange issue. In a normal scenario, MediaElement’s DownloadProgress property updates a UI progress bar. It works correctly while downloading and the DownloadProgress increases. But, when the user clicks another position in the file, the DownloadProgress value becomes 1.0 (100%) and the same with DownloadProgressOffset. After some time, it corrects itself. You can find this same issue at the following link: https://silverlight.net/forums/p/69162/167219.aspx.<br>Before explaining the issue, let me explain some definitions that I would use to explain the issue in showing the DownloadProgress and the DownloadProgressOffset.<br>Byte Range Request: </p>
<h3>Byte Range Request:</h3>
<p>HTTP requests have an option to do a partial content range request. To explain it, let’s take a scenario. Say, we want to request a very large file from a service, but before we do so, we want to find out exactly how large it is and whether the service supports “range requests”. To do this, we make a HEAD request to the large resource we want to retrieve. The HEAD method is a standard HTTP method that acts as if we have made a GET request, but it returns only the headers and not the body. This allows us to find out information about the resource without actually taking the time or using the bandwidth to download it. For example, we can read the Content-Length header and determine the size of the resource.<br>Another header of great importance is the Accept-Ranges header. If it’s present, it may contain a value “bytes”. If so, we know that we can make a GET request and request a byte range to retrieve only those bytes. This is the first important key component.<br>So, now, we know we can make a range request to the service, which we do by sending a standard GET request including a Range header that specifies the range of bytes we can&nbsp; request it like like so: Range: bytes=0-999. The service should then respond with a 206 Partial Content status code, a Content-Range header, and the requested range of bytes. This is the second key component.<br>we should note that the service cannot force the client to make a range request. It is entirely up to the client to make such requests, so the service should honor all standard GET requests that do not contain a Range header by sending back the full representation of the requested resource. If your service allows range requests, it is to your benefit to tell the client with an Accept-Ranges header. If you want to explicitly tell the client that you do not allow range requests, send a value of “none” back with the Accept-Ranges header.<br>I got this definition from the following article, so in case it is not clear to you, you can refer to the following article: </p><p><a href="https://benramsey.com/archives/206-partial-content-and-range-requests/." title="https://benramsey.com/archives/206-partial-content-and-range-requests/." target="_blank" mce_href="https://benramsey.com/archives/206-partial-content-and-range-requests/.">https://benramsey.com/archives/206-partial-content-and-range-requests/.</a></p>
<h3>DownloadProgress:</h3>
<p>The DownloadProgress property of MediaElement is a percentage indicating the amount of download completed for content located on a remote server. The value ranges from 0 to 1. Multiply it by 100 to get the percentage. The default value is 0. When this property is set, the DownloadProgressChanged event occurs. The reference point for this value would be the start of the video so even if you set the position of the video to some middle position, it’s value would be relative to 0.<br>Let’s take an example. If I am playing a video and the video is 100 minute long. Now If I set the position of the video to 50th minute. After some time if it’s value is 0.6&nbsp; then it doesn’t mean that it have been downloaded 60%, it means that it have been downloaded from 50th minute to 60th minute in crude term.</p>
<h3>DownloadProgressOffset:</h3>
<p>It gets the offset of the download progress of the MediaElement. When the user seeks to a point in the download progress (for example, 30 seconds into the video), that becomes the offset for the download progress.<br></p>
<h3>&nbsp;BufferingProgress:</h3>
<p>Gets a value that indicates the current buffering progress. It is the amount of buffering that is completed for the media content. The value ranges from 0 to 1. Multiply by 100 to obtain a percentage. The default value is 0. The BufferingProgressChanged event occurs whenever the BufferingProgress property is updated by 0.05 or more, or reaches 1.0. In some cases, the BufferingProgress value does not remain at 1 as the media plays.<br></p>
<h2 style="color: rgb(255, 153, 51);">Explanation of the Issue: </h2>
<p>When the user plays an HTTP URL, it downloads the file, and DowloadProgress and DownloadProgressOffest works fine, but when the user changes the position of the play or when the first time “seek” operation happens, the player actually fires a BRR, and the index of the WMV file (which is at the end of the file) will be downloaded. At this point, the DownloadProgress and the DownloadProgressOffset both would be very near to the end point, so after some time, the DownloadProgress and the DownloadProgressOffset both reach 100%, which actually means the index file downloaded completely. After this, DownloadProgress will go back to the seek point.</p>
<h2 style="color: rgb(255, 153, 51);">Using the Code:</h2>
<p>There is nothing much to explain in the code. It is self-explanatory. I am using the DownloadProgressChanged and BufferingProgressChanged events to set the DownloadProgress, DownloadProgressOffset and BufferOffset progressbars.</p>

<p style="background: rgb(192, 192, 192) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">&nbsp;private void VideoMediaElement_MediaOpened(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; //VideoMediaElement.Position = TimeSpan.FromDays(1);<br>&nbsp;&nbsp;&nbsp; //VideoMediaElement.Position = TimeSpan.FromSeconds(0);<br>}<br><br>private void Video_BufferingProgressChanged(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; BufferProgress.Value = VideoMediaElement.BufferingProgress * 100;<br>&nbsp;&nbsp;&nbsp; DownloadProgress.Value = VideoMediaElement.DownloadProgress * 100;<br>&nbsp;&nbsp;&nbsp; OffsetValue.Value = VideoMediaElement.DownloadProgressOffset * 100;<br>}<br><br>private void Video_DownloadProgressChanged(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; DownloadProgress.Value = VideoMediaElement.DownloadProgress * 100;<br>&nbsp;&nbsp;&nbsp; OffsetValue.Value = VideoMediaElement.DownloadProgressOffset * 100;<br>}<br><br>private void Pause_Click(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; VideoMediaElement.Pause();<br>}<br>private void Play_Click(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; if (!Uri.IsWellFormedUriString(URI.Text, UriKind.Absolute))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("Invalid URI");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; VideoMediaElement.Source = new Uri(URI.Text);<br>&nbsp;&nbsp;&nbsp; VideoMediaElement.Play();<br>}<br>private void Stop_Click(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; VideoMediaElement.Stop();<br>}<br>private void Farward_Click(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; //if (VideoMediaElement.CurrentState != MediaElementState.Buffering) <br>&nbsp;&nbsp;&nbsp; VideoMediaElement.Position = VideoMediaElement.Position + <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TimeSpan.FromSeconds(Int16.Parse(Amount.Text));<br>}<br>private void Backward_Click(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; //if (VideoMediaElement.CurrentState != MediaElementState.Buffering) <br>&nbsp;&nbsp;&nbsp; VideoMediaElement.Position = VideoMediaElement.Position - <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TimeSpan.FromSeconds(Int16.Parse(Amount.Text));<br>}</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/57/54/29/MediaElementDownloadProgress.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-57-54-29/MediaElementDownloadProgress.zip">MediaElementDownloadProgress.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Silverlight ListBox Part II (Drag and drop in the same listbox and scroll)</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/silverlight-listbox-part-ii-drag-and-drop-in-the-same-listbox-and-scroll</link>
      <pubDate>Tue, 21 Apr 2009 14:12:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/04/21/silverlight-listbox-part-ii-drag-and-drop-in-the-same-listbox-and-scroll/</guid>
      <description><![CDATA[Introduction
In this article, I am going to discuss some of the issues that I faced with ListBox. I...]]></description>
      <content:encoded><![CDATA[<H2 style="COLOR: #ff9933">Introduction</H2>
<P>In this article, I am going to discuss some of the issues that I faced with ListBox. I spent a lot of time Googling to find out a solution to the problems, but couldn’t find much. Here is the list of problems that I will talk about in this article:</P>
<OL>
<LI>Drag and drop in the same listbox.</LI>
<LI>Scrolling (bring the selected item in the visible region).</LI></OL>
<H2 style="COLOR: #ff9933">Background</H2>
<P>This article is a continuation to my previous article, so if you haven’t gone through it, please go through it as I am using the same sample to discuss the issue. Here is the link for the article:</P>
<UL>
<LI><A href="https://blogs.msdn.com/controlpanel/blogs/UsingMultipleTemInListBox.aspx" mce_href="UsingMultipleTemInListBox.aspx">UsingMultipleTemInListBox.aspx</A></LI></UL>
<P>There are three types of items in the listbox (software developer, team leader, manager). The requirement is to provide a drag and drop feature in the listbox so that the user can drag a developer item and drop it a on team leader item, which would include the developer in the team leader’s reporters list, and the same would apply for team leaders and managers. I found many articles on drag and drop on listbox, but most of them were implementing drag and drop from one listbox to another listbox. I had one more issue: to get the controls within a listbox. There is no direct way to get this because of abstraction. We can only get the listboxitems.</P>
<P>After running the attached sample, if you drag a developer item to a team leader item, you would see that the developer gets added into the team leader's list.</P>
<H2 style="COLOR: #ff9933">Using the code</H2>
<P>The first thing that we do for drag and drop functionality is to add a popup control in the form to show the visual effect. Here is the code for the mouse down event where we set the data template and the content of the popup control which would move as we drag the listbox item:</P><PRE style="BACKGROUND: #c0c0c0" lang=html>&lt;Popup x:Name="DragPopupControl" IsOpen="True"&gt;
    &lt;ContentControl x:Name="DragPopupControlContent" Opacity="0.5"/&gt;

&lt;/Popup&gt;</PRE>
<P>The code-behind:</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Employee employee = (sender as UserControl).DataContext as Employee;
    
    if(employee is Developer || employee is TeamLeader)
    {
        this.DragPopupControlContent.Content = employee;
        DataTemplate dataTemplate = 
          this.EmployeeList.ItemTemplateSelector.SelectTemplate(employee, null);
        dataTemplate.LoadContent();
        this.DragPopupControlContent.ContentTemplate = dataTemplate;
        this.DragPopupControl.CaptureMouse();
        this.IsDragging = true;
        this.DragPopupControl.IsOpen = true;
        this.DragPopupControl.HorizontalOffset = e.GetPosition(LayoutRoot).X;
        this.DragPopupControl.VerticalOffset = e.GetPosition(LayoutRoot).Y;
    }
}</PRE>
<P>Here is the code for the mouse move where we change the coordinates of the popup control to move:</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
    if (this.IsDragging)
    {
        double currentVerticalPosition = e.GetPosition(LayoutRoot).Y;
        double currentHorizontalPosition = e.GetPosition(LayoutRoot).X;

        this.DragPopupControl.VerticalOffset = currentVerticalPosition;
        this.DragPopupControl.HorizontalOffset = currentHorizontalPosition;
    }
}</PRE>
<P>Everything was going very smooth up till here, but here comes the main issue. How to get the control in the listbox where we are dropping any other item? There is no direct way to do it. Thanks to one of my colleagues who gave me the code for an extension method which solved my problem. Here is the code for the extension method which returns the list of all the controls in a given control. You can pass the control whose children you want to find out and the mouse position:</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>public static class VisualTreeHelperExtensions
{
    public static IList&lt;T&gt; GetChildControls&lt;T&gt;(
           this DependencyObject obj) where T : DependencyObject
    {
        var childControls = new List&lt;T&gt;();
        DependencyObject child;

        for (int i = 0; i &lt; VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            child = VisualTreeHelper.GetChild(obj, i);

            if (child != null &amp;&amp; (child.GetType() == typeof(T) || 
                child.GetType().IsSubclassOf(typeof(T))))
            {
                childControls.Add(child as T);
            }
            else if (child != null)
            {
                IList&lt;T&gt; subChilds = child.GetChildControls&lt;T&gt;();
                if (subChilds.Count &gt; 0)
                {
                    childControls.AddRange(subChilds);
                }
            }
        }

        return childControls;
    }
}</PRE>
<P>We can use the extension method to get all the controls in the listbox at the given coordinates, and then we can iterate thorough all the items and find out if there is any team leader view if the user is dragging a developer item, or if there is a manager view if the user is dragging a team leader item. Here is the code which actually accepts the mouse up position and adds the dragged item to the dropped item if the drag and drop is a valid one.</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>private void EmployeeDropOnFolder(object sender, Employee employee, MouseEventArgs e)
{
    if (this.IsDragging &amp;&amp; this.DragPopupControlContent.Content != null &amp;&amp; employee != null)
    {
        Point currentMousePosition = e.GetPosition(this);
        List&lt;UIElement&gt; controlList = 
           VisualTreeHelper.FindElementsInHostCoordinates(currentMousePosition, 
           EmployeeList) as List&lt;UIElement&gt;;
        if (controlList != null &amp;&amp; controlList.Count &gt; 0)
        {
            // Remove the sender as it can't be target.
            controlList.Remove(sender as UIElement);

            // Find out if there is FolderView in the list.
            foreach (UIElement uiElement in controlList)
            {
                if(uiElement is TeamLeaderView &amp;&amp; employee is Developer)
                {
                    TeamLeader teamLeader = 
                      (uiElement as TeamLeaderView).DataContext as TeamLeader;
                    if(!teamLeader.DirectReports.Contains(employee))
                    {
                        teamLeader.DirectReports.Add(employee);
                    }
                }
                else if (uiElement is ManagerView &amp;&amp; employee is TeamLeader)
                {
                    Manager manager = (uiElement as ManagerView).DataContext as Manager;
                    if (!manager.DirectReports.Contains(employee))
                    {
                        manager.DirectReports.Add(employee);
                    }
                }
            }
        }
    }
}

private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    EmployeeDropOnFolder(sender, this.DragPopupControlContent.Content as Employee, e);
    this.IsDragging = true;
    this.DragPopupControl.IsOpen = false;
    this.DragPopupControlContent.Content = null;
    this.DragPopupControlContent.ContentTemplate = null;
    this.DragPopupControlContent.ReleaseMouseCapture();
}</PRE>
<P>There exists a direct method <CODE>ScrollIntoView</CODE> in the listbox to bring the selected control in the visible region, but it was not working for me probably because I was using a <CODE>WrapPanel</CODE>. I added code to maintain the row index and the height of the items in the <CODE>WrapPanel</CODE>. When the user clicks on the button in the UI, it gets the currently selected item in the listbox, passes it to the <CODE>WrapPanel</CODE> public method, and gets the position from the top of the wrap panel for the item. Now, we can set the position of the scrollbar. You can look at the code of the <CODE>WrapPanel</CODE> in the attached source code.</P></SPAN>
<DIV></DIV>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/55/99/47/ListBox_Drag_and_drop.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-55-99-47/ListBox_5F00_Drag_5F00_and_5F00_drop.zip">ListBox_Drag_and_drop.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Silverlight ListBox: Part I - Using multiple templates in a ListBox</title>
      <link>https://docs.microsoft.com/archive/blogs/anilkumargupta/silverlight-listbox-part-i-using-multiple-templates-in-a-listbox</link>
      <pubDate>Tue, 21 Apr 2009 13:23:00 GMT</pubDate>
      <dc:creator><![CDATA[anil_gupta29]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/anilkumargupta/2009/04/21/silverlight-listbox-part-i-using-multiple-templates-in-a-listbox/</guid>
      <description><![CDATA[Introduction
The listbox is a very important control in any technology like ASP.NET or Sliverlight....]]></description>
      <content:encoded><![CDATA[<H2 style="COLOR: #ff9933">Introduction</H2>
<P>The listbox is a very important control in any technology like ASP.NET or Sliverlight. Normally, we use it to show single line records where the user has the option to choose one of them. I am not going to discuss about how to use listbox in Silverlight as there are many articles available on the topic in the Internet. In this article, I will discuss about how we can use a template to show the items in a listbox. Although there are many articles available on using a single template in a listbox, there are very few which discuss about using multiple templates in a listbox. Sometimes we might have a requirement where we want to show items which have a few common properties and a few specific properties, and we might want to show a different UI for each type of item and in the same listbox.</P>
<P>Let’s take an example to get a better understanding.</P>
<P>It is a very common scenario. There is an organization which has software developers, team leaders, and managers. All of them have a common properties like EmployeeName and ManagerName, but team leaders and managers will have direct reporters to them.</P>
<P>I am going to create a list box which will have software developers, team leaders, and mangers in a list box. Each will have common properties like Employee Name and Manager Name. Team leader and manager items will have listbox which will have a list of reporters. Following is the list of background colors that I used for each type of item to distinguish them.</P>
<TABLE class=ArticleTable width="100%" class="ArticleTable">
<THEAD>
<TR>
<TD>Item Type</TD>
<TD>Background Color</TD></TR></THEAD>
<TBODY>
<TR>
<TD>Software Developer</TD>
<TD>Yellow</TD></TR>
<TR>
<TD>Team Leader</TD>
<TD>Cyan</TD></TR>
<TR>
<TD>Manager</TD>
<TD>Green</TD></TR></TBODY></TABLE>
<H2 style="COLOR: #ff9933">Background</H2>
<P>There is a very good sample on listbox which uses a <CODE>Panel</CODE> as a container of the listbox. Normally, we use a listbox with the listbox items arranged vertically even if there is enough horizontal space. This sample implements a wrap panel for the listbox; if you are using a wrap panel, then you need not worry about the list box item positions. If there is enough horizontal space, then multiple items can rendered in the same line, and if there is not enough space for the next item, then the next item would be rendered in the next line. Apart from it, its also takes care of resizing the listbox so if the end user is resizing the listbox, then the items would be rendered again and will take new positions corresponding to the space available. This sample also describes about an animation but I am not going to use that in my sample. Following is the link for the article:</P>
<UL>
<LI><A href="https://blogs.msdn.com/devdave/archive/2008/07/17/layout-transitions-an-animatable-wrappanel.aspx" target=_blank mce_href="https://blogs.msdn.com/devdave/archive/2008/07/17/layout-transitions-an-animatable-wrappanel.aspx">DevDave - Dave Relyea's Silverlight Blog</A></LI></UL>
<P>You can directly follow up my example even without reading the above article, but I would highly recommend reading it.</P>
<H2 style="COLOR: #ff9933">What is the Idea?</H2>
<P>Following are the steps that we will follow to achieve our goal. The steps would be more clear in the code section.</P>
<OL>
<LI>Create a template class which will have properties for all the possible templates in the listbox.</LI>
<LI>Create a new class which will derive from <CODE>ListBox</CODE>. It will have a new dependency property to select the template for a given <CODE>ListBoxItem</CODE>. Override the <CODE>PrepareContainerForItemOverride</CODE> method as it actually prepares the specified element to display the given <CODE>ListBoxItem</CODE>. It should call the base class (<CODE>ListBox</CODE>) <CODE>PrepareContainerForItemOverride</CODE> method and set the template of the item from the <CODE>TemplateSelecter</CODE> property.</LI>
<LI>Define the templates for each type of item in the XAML resource.</LI>
<LI>Define a <CODE>TemplateSelecter</CODE> in the XAML resource which will refer to the data template for the item types in the <CODE>ListBox</CODE>.</LI>
<LI>Refer this <CODE>TemplateSelector</CODE> in the list box declaration in the User Control XAML.</LI></OL>
<H2 style="COLOR: #ff9933">Using the Code</H2>
<H4>Step1</H4>
<P>Define the classes for each type of item. All the classes should have a common base class. Here, <CODE>Employee</CODE> is the common base class.</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>public class Employee
{
    public string Name { get; set; }
    public string ImageSource { get; set; }
}

public class Developer : Employee
{
    public string ManagerName { get; set; }
}

public class TeamLeader : Employee
{
    public List&lt;Employee&gt; DirectReports { get; set; }
    public string ManagerName { get; set; }
}

public class Manager : Employee
{
    public List&lt;Employee&gt; DirectReports { get; set; }
}</PRE>
<H4>Step 2</H4>
<P>Create a <CODE>EmployeeTemplateSelecter</CODE> class which should have all the used templates in the <CODE>ListBox</CODE> and should have a <CODE>SelectTemplate</CODE> method which would return the template.</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>public class EmployeeTemplateSelector : DataTemplateSelector
{
    public DataTemplate EmployeeTemplate { get; set; }
    public DataTemplate DeveloperTemplate { get; set; }
    public DataTemplate TeamLeaderTemplate { get; set; }
    public DataTemplate ManagerTemplate { get; set; }
    public override DataTemplate SelectTemplate(object item,
        DependencyObject container)
    {
        if (item != null)
        {
            if (item is Manager)
            {
                return this.ManagerTemplate;
            }

            if (item is TeamLeader)
            {
                return this.TeamLeaderTemplate;
            }

            if (item is Developer)
            {
                return this.DeveloperTemplate;
            }

            if (item is Employee)
            {
                return this.EmployeeTemplate;
            }
        }

        return null;
    }
}</PRE>
<H4>Step 3</H4>
<P>Create a class <CODE>MultiTemplateListBox</CODE> which will be derived from <CODE>ListBox</CODE>. It will have a dependency property which will refer to <CODE>TemplateSelector</CODE> to get the template for the given <CODE>ListBoxItem</CODE>. We have to override the virtual method <CODE>PrepareContainerForItemOverride</CODE> so that we can apply the template corresponding to the given <CODE>ListBoxItem</CODE>. Here is the code for <CODE>MultiTemplateListBox</CODE>.</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>public class MultiTemplateListBox : ListBox
{
    public static readonly DependencyProperty TemplateSelectorProperty = 
        DependencyProperty.Register("TemplateSelector",
        typeof(DataTemplateSelector), typeof(MultiTemplateListBox),
        new PropertyMetadata(new PropertyChangedCallback(OnTemplateChanged)));

    public DataTemplateSelector ItemTemplateSelector
    {
        get { return (DataTemplateSelector)this.GetValue(TemplateSelectorProperty); }
        set { this.SetValue(TemplateSelectorProperty, value); }
    }

    protected override void PrepareContainerForItemOverride(
        DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);

        ListBoxItem listBoxItem = element as ListBoxItem;

        if (listBoxItem != null)
        {
            listBoxItem.ContentTemplate = this.ItemTemplateSelector.SelectTemplate(
                item, this);
        }
    }

    private static void OnTemplateChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
    }
}

public class DataTemplateSelector
{
    public virtual DataTemplate SelectTemplate(object item,
        DependencyObject container)
    {
        return null;
    }
}</PRE>
<H4>Step 4</H4>
<P>I created three different controls for three types of items. You can see the controls in the attached solution. Now, we can create the templates for each type of item, which will have different views for different types of items. Here is the code which defines the templates:</P><PRE style="BACKGROUND: #c0c0c0" lang=xml>&lt;DataTemplate x:Key="DeveloperTemplate"&gt;
&lt;CustomControls:DeveloperView /&gt;

    &lt;/DataTemplate&gt;
    &lt;DataTemplate x:Key="LeaderTemplate"&gt;
&lt;CustomControls:TeamLeaderView /&gt;
&lt;/DataTemplate&gt;
&lt;DataTemplate x:Key="ManagerTemplate"&gt;
    &lt;CustomControls:ManagerView /&gt;

&lt;/DataTemplate&gt;</PRE>
<H4>Step 5</H4>
<P>Define an <CODE>EmployeeTemplateSelector</CODE> in the User Control resource which will refer each template defined in the resources.</P><PRE style="BACKGROUND: #c0c0c0" lang=xml>&lt;CustomControls:EmployeeTemplateSelector x:Key="EmployeeTemplateSelector"
                                DeveloperTemplate=
                                "{StaticResource DeveloperTemplate}" 
                                TeamLeaderTemplate=
                                "{StaticResource LeaderTemplate}"

                                ManagerTemplate=
                                "{StaticResource ManagerTemplate}"/&gt;</PRE>
<H4>Step 6</H4>
<P>Include an object of <CODE>MultiTemplateListBox</CODE> which will have a <CODE>ItemTemplateSelector</CODE> property as a static resource and refers to the <CODE>EmployeeTemplateSelector</CODE> key. Bind the <CODE>ListBox</CODE> to the <CODE>Employees</CODE> collection property.</P><PRE style="BACKGROUND: #c0c0c0" lang=xml>&lt;CustomControls:MultiTemplateListBox x:Name="EmployeeList"
                                         ItemsSource="{Binding Employees}"       
                                         ItemTemplateSelector=
                                         "{StaticResource EmployeeTemplateSelector}" 
                                         Width="800" Height="600" 
                                         Canvas.Top="20"&gt; 
    &lt;ListBox.Template&gt;

        &lt;ControlTemplate&gt;
            &lt;Grid&gt;D:\Personal\Submit Article\MultipleDataTemplateInListBox\
                  MultipleDataTemplateInListBox\EmployeeContainer.xaml
                &lt;ScrollViewer&gt;
                    &lt;ItemsPresenter /&gt;
                &lt;/ScrollViewer&gt;
            &lt;/Grid&gt;

        &lt;/ControlTemplate&gt;
    &lt;/ListBox.Template&gt;
    &lt;ListBox.ItemsPanel&gt;
        &lt;ItemsPanelTemplate&gt;
            &lt;CustomControls:WrapPanel Width="Auto"/&gt;

        &lt;/ItemsPanelTemplate&gt;
    &lt;/ListBox.ItemsPanel&gt;
&lt;/CustomControls:MultiTemplateListBox&gt;</PRE>
<P>The only thing remaining is to populate the data and set the context. Here is the code for it:</P><PRE style="BACKGROUND: #c0c0c0" lang=cs>public class EmployeeContext
{
    public List&lt;employee&gt; Employees { get; set; }
    public EmployeeContext()
    {
        Employees = GetEmployeeList();
    }
    private List&lt;employee&gt; GetEmployeeList()
    {
        Developer dev1 = new Developer() { Name = "Mike", ManagerName = "Peterson" ,
            ImageSource = @"/Images/image1.jpg"};
        Developer dev2 = new Developer() { Name = "John", ManagerName = "Peterson" };
        TeamLeader leader1 = new TeamLeader() { Name = "Peterson",
            ManagerName = "Anderson", DirectReports = new List&lt;employee&gt; { dev1,
            dev2 } };
        Developer dev3 = new Developer() { Name = "Steave Mollenkopf",
            ManagerName = "Tomi Swartz" };
        Developer dev4 = new Developer() { Name = "Han Tran",
            ManagerName = "Tomi Swartz" };
        Developer dev5 = new Developer() { Name = "Parth Sarthi",
            ManagerName = "Tomi Swartz" };
        Developer dev6 = new Developer() { Name = "Shivank Nayak",
            ManagerName = "Tomi Swartz" }; 
        TeamLeader leader2 = new TeamLeader() { Name = "Allona Cholnika",
            ManagerName = "Tomi Swartz", DirectReports = new List&lt;employee&gt; { dev3,
            dev4, dev5, dev6 } };
        Manager manager1 = new Manager() { Name = "Tomi Swartz",
            DirectReports = new List&lt;employee&gt;() { leader1, leader2 } };
        return new List&lt;employee&gt;()
           {
               dev1, dev2, dev3, dev4, dev5, dev6, leader1, leader2, manager1
           };
    }
}
   
EmployeeContext context = new EmployeeContext();
        this.DataContext = context;</PRE>
<P>Now, if you run the code, you will find the items in three different colors (yellow, cyan, and green). I am not very good at UI designing, so the UI might not look very good. The <CODE>ListBox</CODE> contains three different types of items, and different types of items have different UI. We can deal with them separately. Here, the team leader <CODE>ListBoxItem</CODE> has a list of developers and the manager <CODE>ListBoxItem</CODE> has a list of team leaders.</P></SPAN>
<DIV></DIV>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/55/98/58/MultipleDataTemplateInListBox.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-55-98-58/MultipleDataTemplateInListBox.zip">MultipleDataTemplateInListBox.zip</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>