namrata's profileNashaPhotosBlogListsMore Tools Help

Blog


    February 17

    Interview Questions & Answers

     If you have any questions in mind please mail them to me at namratha1@gmail.com in the below format.

    E.g.
    Usergroup : Mumbaisuergroup.
    Nick Name : Nasha
    Question : Explain ur Q in brief


    What is a diff between an abstract class and an interface ? What would govern your decision for its usage in .NET?
    -- A an abstract class is a class which cannot be instantiated and an interface is a set of functions. Thier usage would goverened by  the follwoing reasons :-
    a. If I have some common functions to be implemeted in the base class then one should  use abstract class as Interface cannot have  funcation implementations.
    b. Languages like C# and VB.NET only allow single inheritance of classes hence you have only one base class and rest will have to  be created as interfaces.
    e.g. If I did my class A to inherit from Class B and Class C .. then inheritance can only be done from one of these classes the one will  have to created as an interface.

    What are the different types of polymorphism ?
    -- There are two types of polymorphism inheritance based and interface based. In Inheritance based you have a common base class  and in interface based you have a common interface between classes.

    How can you view the procedure text from Query Analyser ?
    -- Use sp_helptext <procedure name>

    Can you have two applications on the same machine one which is using .NET Framework 1.0  and the other using  1.1 ?
    -- Yes

    You have an application which yoour client is going to view from his end. If you dont want the cleint to view details of the error  message then what will you do?
    -- Set the custom errors property of to Remoteonly. The other two options are On which will not display the error details on both  remote as well as local machine and the other one is Off which is always display the complete error message on both remote as well  as local machine.

    If you are using a web service and you want its path to be picked up from the config file what will you do ?
    -- Set its behaviour property to dynamic this will add a new appSetting entry in the config file for the webservice path.

     Can I view Intermediate Language of a .NET assembly?
    -- Yes. MS supply a tool called Ildasm, which can be used to view the metadata and IL for an assembly.

    What is the maximum number of classes a .NET DLL can contain?
    -- Unlimited

    Can you call the garbage collector explicitly?
    -- System.GC class exposes a Collect method - this forces the garbage collector to collect all unreferenced objects immediately.

    Can I serialize Hash table with XmlSerializer?
    -- XmlSerializer will refuse to serialize instances of any class that implements IDictionary, e.g. Hash table. Soap Formatter and Binary  Formatter do not have this restriction.

    What is difference between "tlbexp" and "Regasm" tools?
    -- Both these tools are used to create CCW from a .NET Assembly, the only difference being that Tlbexp will not register the type  library unlike regasm.

    February 09

    .NET Remoting ( Part - 5 -> Configuration File )

    Configuration files have always been a part of our applications. They generally hold data which is configurable, so instead of hard  coding the parameters in the code we can read them form a config file. In .NET Remtoing we have some xml elements to configure our channel and remote objects.

    All the elements are placed under the main xml element <configuration>. For .Net Remoting there is a tag named  <system.runtime.remoting>. Let us look at the various elements provided for .NET Remoting which will be placed under  <system.runtime.remoting> .

    a. The first tag to come under <system.runtime.remoting> is <application> application. This tag is used to specify the application  name. On the server side for specifying  the server name and on the client side its the name of the client application.
    E.g. If we have a remote server name "MyRemoteServer" then the server configuration will specify it in the application tag as follows
            <application name ="MyRemoteServer" >
                    |
                    |
            <application/>

    b.On the server side we have <service> element. This element is used to specify a collection of remote objects we host. This element  can hold <wellknown> and <activated> elements under it , which are used to specify the type of remote object.
            <service>
               |
               |
            </service>
    c.On the client side instead of service we have a <client> element. <client> has an attribute url to hold the path of the remote server.  Like <service> it can have <wellknown> and <activated> sub-elements under it. They are used to specify the type of remote object  and hold the url of the remote server.
    E.g.
            <client url ="tcp://MyMacName:6789/MyRemoteServer>
                    |
                    |
            </client>
           
    d. <wellknown> is used on the server and client to specify the type of remote object On the server side it is used to specify the mode  of the remote object using the mode attribute, type of remote is specified as Namespace.Classname  followed by the name of  assembly. ObjectURI mentions the server object's URI. Its a subelement under <service>.
    On the client side it is used to mention the type again as Namespace.Classname and url holds the complete url of the server object  mentioning the protocol, port, application name and the object URI. Its a subelement under <client>
    E.g.
            Client : - <wellknown type = "MyNamspace,MyRemoteServer" url = "protocol://MyMacName:6789/MyRemoteServer/URI" />
            Server :- <wellknown mode = "Singleton" type "MyNameSpace.MyRemoteServer, RemoteServer" objectURI="URI" />

    e. The activated element is used for  client activated objects [CAO]. It specifies type containing the complete name of the object i.e.  Namespace.ServerName along with the name of the assembly. This should be specified for CAO's on both server side and client side.
    Its a subelement of <clilent> on client side  and <service> on server side.

    E.g.
            <activated type = "MyNamespace.MyRemoteServer, RemoteServer" />

    f. Generally it is observed that the config file are used to configure channels. To specify channel we have the channel element. Under  channel we have channeltype. It is used on both the client and server side. The channeltype element holds the type of channel with its  assembly name and the port number. Its a subelement under <appplication> generally mentioned below <service> or <client>.

    E.g.
    <channels>
            <channel type = "System.Runtime.Remoting.Channels.Http.HttpChannel,System.Runtime.Remoting" port=6789 />
            <channel type = "System.Runtime.Remoting.Channels.Tcp.TcpChannel,System.Runtime.Remoting" port=6789 />
    </channels>

    February 07

    .NET Remoting ( Part - 4 --> LifeTime Management )

    Continuing our discussion with LifeTime Management :-

    Lifetime Management has been one of the biggest challenges in distributed applications. It is difficult to detect for client and server  that whether the other is available or not.

    To check whether the server is available or not, the least that the client can do is to ping the server . But this mechanism is fine if we  are on LAN but is not suitable for Internet based applications. If the client is unable to check the presence of the server, the last thing  it can do is call a method on the server object. If the server object is not present than an exception will be raised.

    .NET Remoting has some up with a solution for lifetime management called as the Leasing Distributed Garbge Collector i.e.LDGC. Lifetime managment becomes very important for client -activated objects as they can have state and need to be aware of resources  that they use. So lease becomes very important for these objects when the lease time is reached the lease expires and the object is  marked for garbage collection.

    All objects inherited from MarshalByRef generally do their own lifetime managment and do not reside in memeory for a long time.  Inorder to implement custom lifetime managment we need to override InitializeLifetimeService(). The life time of the object is controlled  by setting the lease time , lease manager and Number of sponsors. When we say number of sponsors we mean that if no sponsors  are available within the SponsorshipTimeOut then the lease expires and te object is garbage collected. Lease Manager keeps a watch  on the object and marks it for garbage collection when the lease expires. All the sponsors who want the object have to first register themselves with the lease manager and than renew the lease time for the remote object periodically.

    Inorder to handle lease of an object we need to override InitializeLifetimeService(). When we override this method the call to the base  class InitializeLifetimeService() returns ILease object. We need to set properties of this object inorder to renew the object lifetime.

    ILease defines the following properties to control lease time of an object :-

    Lease Time :- Time until the object will be marked for garbage collection. The default current lease time is 5 minutes .. setting it to 0  will be setting it to infinite
    RenewOnCallTime :- Its the lease time set on each method call on the remote object. Default 2 minutes
    SponorshipTimeout :- The amount of time by which the lease manager should be able to find a sponsor for the object. If not than the  lease expires and the object is marked for deletion. Default 2 mintues
    LeaseManagerPollTime :- Its the time interal after which the lease manager checks for object lease expiration. Default is 10 seconds.

    There are lot of ways for renewing object lease or liftime.

    a. As we saw above the object life time will be automatically renewed if the CurrentLeaseTime is less than the RenewOnCallTime  once there is a method call made on that object.

    b. One can control the object renewal by calling Renew method. InitializeLifetimeService() which returns us an ILease object exposes  a method called ILease:Renew().

    c. Object renewal can be left at Sponors discretion. The sponors need to implement ISponsor interface. This mechanism need the  sponsor to register by calling the Register() method of the ILease interface. When the lease  is about to expire the sponsor will be  asked if the lease needs to be renewed. This mechanism is best for Client-activated objects and when you want remote objects to live  for a long time.

    .NET's approach towards lifetime management is better than other older aproaches like pinging for an object and reference counting.

     

    February 04

    .NET Remoting ( Part - 3 Formatters,ObjectActivation,Proxy & Msg Sinks)

    Continuing our yesterdays discussion letz start with formatters.

    Formatters :- .NET framework provides us with two formatters classes namely SoapFormatter and BinaryFormatter. You can find  them under namespace System..Runtime.Serialization.Formatters.Binary and System.Runtime.Serialization.Formatters.Soap .  Formatters are used to transfer data to and fro from a channel. They are associated with a channel through formatter sink objects and  providers.Both these formatters implement a common interface know as IRemotingFormatter. IRemoting is available under  System.Runtime.Remoting.Messaging Namespace. This interface has two methods Serialize and Deserialize which help to serialize  data to be transfered across.

    Both these formatters are primarily used for serialization and deseralization of method calls and reponses.When a method call is  made , the method call information has to be serialized inorder to be sent to the remote object. To execute the request it has to be  deserialized. After the request is executed on the remote object the response has to be serialized and sent. The response is further  deserialised by the client.

    You can also create your custom formatter and associate it to a channel.

    Object Activation :-  Remote objects can be either client activiated or server activated. You can get reference to the remote objects  using the Activator class. Activator.GetObject method returns you a reference to the proxy of a server activated object.  Activator.CreateInstance returns you a refernce to a proxy of client Activated object.

    Server or WellKnown Objects :-
    Activator.GetObject and RemotingServices.Connect both return a reference to a proxy of a server or wellknown object. There are two types of the wellknown service type. SingleCall and Singleton.

    SingleCall :- SingleCall objects dont hold any state that means for every call you make to the remote object a new object is created.  So there is no object to persist data in between calls. This can be efficient as the server does not need to hold any resources for the  client.

    Singleton :- As the word singleton says the same object is used across client. This object can be used to share data across clients.  As with any other singleton object one has to be careful of locking of resources and concurrency.

    When we create a server activated remote object we can register the wellknownservicetype as either of them.

    Client-Activated Objects :-Activator.CreateInstance creates a client activated object. Life-time of the client activated object is in the  hands of the client unlike the server activated objects i.e. the object lives till the time the cleint wants it to live. On creating a client  activated object yuo can specifiy the lease time of the object. Since the the client has reference to the object, object state can be  maintained easily.

    Proxy :-  We just saw above that both the static methods Activator.GetObject and Activator.CreateInstance return us reference to a  proxy object. In Remoting there are two types of proxies Transparent and Real Proxy. Transparent proxy is an object that looks like  the remote object but all the method calls are further redirected to real proxy. Transparent proxy calls the Invoke method of the real  proxy object.

    To check whether the proxy received by you is a real proxy or a transparent proxy .NET provides us with a method called  IsTransparentProxy exposed by RemotingServices class. This method takes the refrence to the proxy object as a parameter and  returns a boolean value.

    MessageSinks :-  Message sinks are interceptors that can change the messages and perform some additional actions. Whenever we  create an object we get a reterence to its proxy. This proxy uses a chain of envoy sinks to pass messages to the channel. All  message sinks implement IMessageSink Interface which has one property NextSink and two methods SyncProcessMessage and  AsyncProcessMessage.

    NextSink returns a refernce to the next sink in the hierarchy to pass the message. SycnProcessMessage method processes a  message request in a synchronous manner and returns a response message [ a an IMessage object ]. AsyncProcessMessage  method process the message request asynchronously and returns a reference to the passed async message [ an IMessageCtrl  object].

    There are mainly three types of message sinks i.e. Envoy,Server Context and Object.

    Envoy Sink :- They are created from the server context so the server can pass messages to the client. Envoy sinks are generally  used to collect client info and pass it to the server.

    Server Context Sink :- When a message is received on the server side it is passed to the server context sink.

    Object Sink :- An object sink is created for a particular object if its class defines context sinks and attributes.

    February 03

    .NET Remoting ( Part - 2 Channels )

    Channels :
    Channels are used for communication. In .Net Remoting Channels are used to transport messages from client to server to and fro.  When a message is sent from client to server, client is the sender and server is the receiver and vice-versa. Since channel is used to  transport messages before starting any type of communication with the remote object it is important to setup a channel for  communication.

    To create a channel one needs to implement IChannel interface ( the primary interface for any channel). The two main operations of  channels are to send and receive messages. For any channel to receive messages it needs to implement IChannelReceiver interface and to send messages it needs to implement IChannelSender Interface.

    .NET Framework provides us with two in built channels TCP and HTTP. Both TCP and HTTP implement IChannelReceiver and  IChannelSender interfaces.

    Since all the channels implement IChannel interface let us check it out first. IChannel has two main properties ChannelName and  ChannelPriority. ChannelName enables us to give a a reference name to the channel. ChannelPriority enables us set the priority.Channels with higher priority value are given higher priority.

    TCP and HTTP channels, each are further classified into Client and Server channels. Client channels implement IChannelSender  interface and Server channels implement IChannelReceiver interfaces respectively.

    IChannelSender :- This interface is implemented by any channel to send messages. This interface has an important fuction called as  CreateMessageSink. This method takes 3 parameters  URL,remotechanneldata and objectURI and returns a reference to the newly  created message sink. URL is the address to which the messages are to be delivered.Remotechanneldata holds the data about the  target channel [ server channel ].ObjectURI is parameter is unintialized. When we call CreateMessageSink either URL or  RemoteChannelData can be null but not both.

    IChannelReceiver :- This interface is implemented by any channel to receive messages.    It has an important property called  ChannelData and  3 functions called GetUrlsforUri, StartListening and Stop Listening. ChannelData is a readonly property which  returns an object containing channel specific data. GetUrlsforURI will return all the urls of that can be used to locate the remote  object. Server channels implement IChannelSender to receive messages from the client. StartListening and StopListening  helps the server channels to start or stop listening to its corresponding cleint channel.

    Let us look at the the channels which implement the above interfaces:

    TCPClientChannel :- Uses binary formatter to serialize messages. This channel is the last in the sink heirarchy who is responsible for  finally sending out the message across to the server using TCP Protocol. TcpCleintChannel implements IChannelSender interface.

    TCPServerChannel :- This channel works in conjunction with the client channel. Binary formatted messages sent by the client channel  are accepted by the server channel. Unlike the Client Channel, the server channel is the first in the message sink heirarchy from the  server side to receive messages. TcpServerChannel implements IChannelReceiver interaface.

    TCPChannel :- This channel implements both IChannelSender and IChannelReceiver interfaces that enables it to both send and  receive messages.

    HTTPClientChannel :- Uses SOAP formatter to serialize messages to xml format. Like the TCPClientChannel is last the sink  heirarchy and implements IChannelSender interface. This channel uses HTTP protocol to transport xml messages.

    HTTPServerChannel :-  Like the TcpServerchannel it also works in conjunction with the client channel to receive messages using  HTTP protocol and is first in the sink heirarchy on the server side.

    HTTPChannel : Implements both IChannelSender and IChannelReceiver that enables it to send and recieve messages using HTTP.

    Note :- All HTTP Channels inherit from a common base class called BaseChannelWithProperties which in turn inherits from  BaseChannelObjectWithProperties. They aid in reteriving properties of any channel sink in the sink heirarchy.

    This is all about channels will continue tomm with sinks and formatters.

    January 31

    Article : .NET Remoting ( Part - 1 )

    Today we will be discuss .NET Remoting. Let us start of with its Introduction :-

    Introduction :

    Remoting is used to access objects in the same and another application domains. When the client accesses an object in another  app domain the client receives a proxy to the real object. Hence when the client calls any method of the remote object it actually calls  a method on the proxy. Proxy is has a similar interface to the real object. The proxy in turn sends a message to the message sink.  The message sink further sends the message to the channel. Channel is responsible for connecting the client and the server. Client  Side sends data to the server side channel. The server side channel in turn talks with the server side message sinks. There can be  one or more message sinks. The last message sink calls method on the remote object. The result is sent using the same approach.

    Classes and Remoting:

    There are two main types of objects that play a very important role in remoting Marshal by value and Marshal by ref.

    Marshal by value:
            Objects of type marhsal by value are not bound to any application domain. They can be serialized and passed across  through channels. To serialize these objects it is necessary that there class implements ISerializable interface or are marked with the  [Serializable] attribute.

    Marshal by ref:
            Classes of type marshal by ref are derived from a class known as MarshalByRefObject. Any object of type  MarshalByRefObject is never passed across application domains. Hence one needs a proxy to access these objects from another  application domain. Unlike the classes which are of type Marshal by value which are not bound to there application domain Marshal  by ref classes are bound to there application domain. Objects of these classes are also called ContextBound objects as they are only  valid in the creation context.
           
            Classes that cannot be serialized and not derived from MarshalByRefObject are non-remotable objects
           
    Context:

            We all know that a single application process can have multiple application domains. An application can have multiple  contexts. A Context groups object as per there execution  requirement. Hence Marshal by ref objects are context bound in there  application domain coz thereexecution requirement is defined in there application domain. Thus a proxy is used to make a call to  these objects so that call is executed in the same app domain or context.
            Creating an application domain creates a default context for that application domain.An context also defines certain context  properties which is required by objects created in it.

    January 27

    Article : Access Win Registry through .NET

    Registry has been a central repository for a lot of Microsoft applications over the years. You can access a machine's registry using the regedit tool. . NET also provides us with classes named RegistryKey and Registry under Microsoft.Win32 namespace to access registry.

    Registry class exposes all the main key of the registry i.e. CurrentUser, CurrentConfig, LocalMachine, CurrentConfig, ClassesRoot and Users as Registry.CurrentUser, Registry.CurrentConfig, Registry.LocalMachine, Registry.CurrentConfig, Registry.ClassesRoot and Registry.Users.

    There are methods to get any sub key under any of the main keys (the ones mentioned above).

    You can retrieve reference to the main and then retrieve the list of sub keys under it.

    E.g. Here I am retrieving reference to the registry key CurrentUser and then retrieve the list of sub keys under it.

    RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software");

    string[] keys = rk.GetSubKeyNames(); // returns an array of sub key names.

    Note: In the above code retrieving a reference to the Current User Registry Key returns me an Registry Key object. To retrieve any detail of that registry key I need to call methods registry key object.

    You can retrieve the sub key count calling the SubKeyCount () method on registry key object.

    To create a sub key under any registry key retrieve the reference to that registry key and call CreateSubKey() method.

    E.g. Here I am creating a sub key named "Nasha" under the Root\CurrentUser\Software.

    RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software",true);

    RegistryKey subkey = rk.CreateSubKey("Nasha");

    Remember whenever you open a key to create keys under it pass the second value as true. Passing the second value as true will grant you a write access. CreateSubkey method returns reference to the new key. Thus you can use this reference to create nested keys.

    To create values under that key node call the Setvalue() method and pass the name and value parameters.

    rk.SetValue("abcd","abcd");

    To delete keys and values there are methods like DeleteSubKey(), DeleteSubKeyTree(), DeleteValue().

    There are a lot of other useful methods like

    GetValueNames() and GetSubKeyNames() and properties like rk.ValueCount and rk.SubKeyCount.

    After you are through with your manipulation dont forget to close the key with

    rk.Close();

    January 24

    Locking config setting using <location> tag

    Hi Group,
     
    In ASP.NET is very easy to override configuration settings defined in the machine.config. All that you need to do is create a web.config file and specify the settings in it. Sometimes we want that certain configuration settings are not overridden by any application esp if it is your company server hosting many applications.In that case we need to lock these settings.
     
    There is a tag called <location> tag which can be added to machine.config file. This tag has two attributes named path which is the path of the application and allowOverride which takea a boolean value. If we set the value of allowOverride attribute as false then if the application mentioned in the path tries to override config settings will get an error.
     
    e.g.
     <configuration>
         <location path="DefaultwebsitePath/MyApp" allowOverride="true">
             <system.web>
              |
              | Session state settings, trace settings etc
              |
             </system.web>
          </location>
     </configuration>
     
    Now if MyApp tries to overrider these settings it will get an error.
     

    -- Please post your queries and comments for my articles in the user group for the benefit of all. I hope this step from my end is helpful to all of us. You can find all articles written by me at my personal blog http://spaces.msn.com/members/nasha.

    Regards,

    Namratha (Nasha)   

    January 20

    Configuring machine.config to recycle aspnet_wp

    There has been a lot of times when we feel that our application is slowing down or the ASP.Net worker process is not working as its best. Although ASP.NET does recycle its process after certain number of requests or memory Limit but there are times when you feel that you could control these parameters and explicitly restart the worker process.

    It is possible to restart the worker process explicitly after a certain number of requests.

    In Machine.config under <configuration> <system.web><procesmodel> we have an attribute called requestLimit.

    Set this request Limit to the number of requests after you want to recycle your worker process. It can be set to Infinite or any particular number. The default setting is 5000.

    Suppose if we set to it say 10 then you will notice that after every 10 requests aspnet_wp process will be recycled. You can note the process id's to feel the change.

    Second reason coz of which we may want our process to be recycled is because of high consumption of memory.

    In Machine.config under <configuration> <system.web><procesmodel> we have an attribute called memoryLimit. Set the threshold to the amount you want. The default is 60 i.e. 60%. The moment this threshold is reached aspnet_wp will be recycled.

    Before we make any changes to the machine.config we must remember that these changes are going to affect all the applications on that machine coz we are these changes at the core level. Hence after making these changes we should bench mark all our applications.

    January 19

    Article : COM + Services Part 6 ( Security )

    Today we will implement Role based Security in COM+ Components

    Before we go ahead there have been a lot of times when I have been approached with these questions: - 

    a) How do we start a transaction on COM+?
            In COM+ transaction is implicitly started for all the methods, which are present in the serviced component. There is no way to explicitly start the transaction like begin trans etc.

    b) What type of methods should be present in COM+ components?
            Only those methods that change data should be kept in serviced components. Methods that only retrieve data like GetEmployeeList etc. should not be placed in serviced components.

    c) Is using AutoComplete good?
            Yes. But provided you have done a robust error handling and u are sure to complete your transaction. If not go in for the SetComplete and SetAbort style ... I know its a little old fashioned but it is robust.

    d) If there are two methods in a serviced class say method A and method B and from A there is a call to B then should I call SetComplete from B?
            Yes. We should always remember that COM+ and MTS works on a two phase commit protocol hence every operation has to acknowledge whether it was a success or a failure. Hence all the methods need to either call SetAbort or SetComplete.

    Enabling Role-based security: -

    To enable Role - based Security in our COM+ Components .NET Framework provides us with ContextUtil.IsCallerRole() method. This method authenticates the current user with a Windows 2000 user group and returns a boolean value.

    E.g. To validate whether the current user is a part of  a windows user group "DotNet"

            If(ContextUtil.IsCallerInRole("DotNet") == true)
            {
                    // to perform the required operation
            }

    Add the above code to our Manager classes so that only those users, which belong to the Dot Net user group, will be able to update employee' s details.

    We can also check whether the called component has an existing transaction or not.

    To check whether the called component is in transaction or not .NET framework provides us with ContextUtil.IsInTransaction() method.

    e.g. To check whether there is an existing transaction or not

            If(ContextUtil.IsInTransaction == false)
            {
                    // Perform the required action
            }

    Article : COM + Services Part 5 ( .NET Implementation Contd.)

    Today we will create a client app for our COM+ component the different types of COM+ applications and how to implement JIT and ObjectPooling in them.

    Registering our component and creating a client App:   

    Well All COM+ Components need to be registered with COM+ Services.But before that they need to be strong named hence we will create a strong name using strong name utility and sign all our assemblies with it.

    a. Create a strong name key pair using sn -k "MyKey.snk"
    b. Sign your Serviced Assembly i.e. your Buss Layer and also all those, which are used by your Serviced Component
    c. Change the AssemblyInfo.cs and set the AssemblyKeyFile Attribute as follows [assembly: AssemblyKeyFile    ("..\\..\\MyKey.snk")] and place the MyKey.snk in the project folder.
    d. Build the Solution Components will be registered on the local machines.
    e. To register the assembly on any other machine you can user regsvcs .. Check my blog on .Net framework Tools to know more about it.

    Note:- If your COM Component is used by Managed Code then you dont need to register them explicitly with regscvs as the moment you call a function on the serviced component CLR will automatically register it with COM+. You need to register COM+ components explicitly only if they are being used by unmanaged code coz in that case regsvcs will create corresponding type library for it.

    Lets us now create our cliient app.

    a.Open a Windows or an ASP.NET application
    b. Add References to EmpEntity and Buss Layer DLLs. Also add reference to System.EnterpriseServices
    c. Add a button and write the following code to create the Employee entity and an Arraylist containing Skill entities.
    d. Pass the Employee entity to the EmployeeManager for updation.

                    private void button1_Click(object sender, System.EventArgs e)
                    {
                            EmpEntity.Employee emp = new EmpEntity.Employee();
                            emp.Skills = new ArrayList();
                            Skill skill;
                            for(int i=0; i<10; i++)
                            {
                                    skill = new Skill();
                                    skill.Name = "Skill "  + i;
                                    skill.TotalExpWithSkill = i;
                                    emp.Skills.Add(skill);
                            }
                            BussDLL.EmployeeManager empMgr = new BussDLL.EmployeeManager();
                            empMgr.UpdateEmployee(emp);
                    }

    Compile the project and run it.

    Types of COM+ Components:-

    There are two types of COM+ applications Library Application and Server Application.

    Library Application: - Components of libaray application type are instantiated in client process i.e. there instantiation is done in the caller's process.

    Server Application: - Server application components are instantiated in a serparate process this process is generally a surrogate process that is instantiated only for the components.

    To set the type COM+ application can be done both from the MMC for COM+ Services and code. We will check out how to set it from code.

    There is an attribute called ApplicationActivation you can use this to set the Activation type to either Library or Server. We need to add this to the AssemblyInfo.cs file

            [assembly: ApplicationActivation(ActivationOption.Server)]

    The ActivationOption can be either Server or Library.


    Enabling ObjectPooling : -

    To enable object pooling for .NET components we need to add ObjectPooling attribute to the class.

    [ObjectPooling(Enabled=true, MinPoolSize=1,MaxPoolSize=10)]

    You can even override the following methods to provide customization
    a.CanBePooled
    b.Activate
    c.Deactivate

    Enable JIT: -

    To enable JIT we need to add JustInTimeActivation Attribute to the class

    [JustInTimeActivation(true)]

    Article : COM + Services Part 4 ( .NET Implementation )

    For using COM+ Services from .NET Assemblies is possible with help of System.EnterprisesServices Namespace.

    Let us create a three tiered application containing a Business Manager classes, an Entity and a Data Layer class along with a client which uses the Buss layer object. We will start by creating Entity and DB layer classes.

    The flow goes like this: Our Client creates an Employee object. This employee object has Employee data  and data about employee's skills. Our client calls methods on the Employee Manager by passing the Employee object. Employee Manager calls the UpdateEmployee method on the EmpDataStore by passing the Employee object and then calls the UpdateEmpSkills method on EmpSkillsManager to update employee's skills data. 

    Creating the Employee and Skill Entities

    1) Open a Class Library name it EmpEntity and add a class named Employee and add the below code to it.

    using System;
    namespace EmpEntity
    {
            public class Employee
            {
                    private string name;
                    private ArrayList skills; // will hold an arraylist of Skill objects
                    private string address;
                    public Employee()
                    {}

                    public string Name
                    {
                            get{return name;}
                            set{ name = value;}
                    }
                   
                    public string Address
                    {
                            get{return address;}                   
                            set{address = value;}
                    }

                    public ArrayList Skills
                    {
                            get{return skills;}
                            set{skills = value;}
                    }
            }
    }

    using System;
    namespace EmpEntity
    {
            public class Skill
            {
                    private string name;
                    private int totexp;
                    public Skill()
                    {}
                    public string Name
                    {
                            get{return name;}
                            set{name = value;}
                    }
                    public int TotalExpWithSkill
                    {
                            get{return totexp;}
                            set{totexp =value;}
                    }
            }
    }



    Creating the EmpDataStore and SkillDataStore

    1) Open a new class library project name it EmpDataDLL and add the below two classes
    2) Add Reference to EmpEntity

    using System;
    using EmpEntity;
    using System.Data;
    using System.Data.SqlClient;

    namespace EmpDataDLL
    {
            public class EmpDataStore
            {
                    public EmpDataStore()
                    {}

                    public void UpdateEmployee(Employee emp)
                    {
                            // Implementation using ADO.NET to update the
                            // Emp details to the Employee Table
                    }
            }
    }
                   

    using System;

    namespace EmpDataDLL
    {
            public class SkillDataStore
            {
                    public SkillDataStore()
                    {}

                    public void UpdateSkill(ArrayList skills)
                    {
                        // Implementation using ADO.NET to update the  Emp Skills

                        //details by parsing through the arraylist to update the Employee Skills table
                    }
            }
    }

    Creating the Buss Managers or the Serviced Components

    Any component that has to be COM+ component or as we call it a serviced component in .NET has to subclass from a class called
    Serviced Component.

    1) Open a new class Library project named BussDLL.
    2) Add Reference to System.Enterprises namespace
    3) Create two new classes EmployeeManager and EmpSkillsManager and subclass it from ServicedComponent.

    After we have created a serviced component let us see how we can implement transactions using Transaction and AutoComplete
    Attribute and ContextUtil class.

    We have seen that there are various transaction types that COM+ components can have. You can set the components transaction type from the COM+ Services MMC interface but to implement the transaction type of the component you need to set the Transaction attribute.

    To implement Transactions in .NET we need to first set the transaction option.

    Transaction option can be set only at a class level using the Transaction Attribute. Transaction Attribute takes a parameter called as TransactionOption where you can mention the transaction type as follows :

    [Transaction(TransactionOption.Required)]  // you can mention any one of the five available types.

    4) Add the Transaction attribute at the top of the classes.

    MTS and COM+ both work on a two-phase commit protocol i.e. the transaction will either succeed or fail and all operations taking part in the transaction need to acknowledge its caller whether it succeeded or not. Hence when the transaction is through successfully we need to complete the transaction if we have to rollback we need to abort the transaction.  When a transaction is aborted at any stage all the operations prior to the operation, which failed, are automatically roll-backed. To complete or abort a transaction we need to get its Context.... when I say context what I mean is a handle to the current transaction. There is a class in .NET called as ContextUtil that retrieves the current transaction context. All you need to do is just refer to the class in your code.

    5) Add a method named UpdateEmployee to EmployeeManager class from where we will update employee's info. In this method we receive an employee object which we will send to EmpDataStore class to update employee data in the DB.

    Any Transaction is completed using the SetComplete() method of ContextUtil class and aborted using SetAbort() method.

    6) Finally our class should look something like this

    using System.EnterpriseServices;
    using EmpEntity;
    using EmpDataDLL;
    using System;

    namespace BussDLL
    {
            [Transaction(TransactionOption.Required)]
            public class EmployeeManager:ServicedComponent
            {
                    public EmployeeManager()
                    {}             
                    public void UpdateEmployee(Employee emp)
                    {
                            try
                            {
                                EmpDataDLL.EmpDataStore empDataStore= new EmpDataDLL.EmpDataStore();
                                empDataStore.UpdateEmployee(emp);
                                EmpSkillsManager empSkillMgr = new EmpSkillsManager();
                                empSkillMgr.UpdateSkill(emp);                          
                                ContextUtil.SetComplete();
                            }
                            catch(Exception ex)
                            {
                                    ContextUtil.SetAbort();
                                    throw ex;
                            }
                    }
            }
    }

    Note: - The call to the EmpDataStore is in a try catch block hence if any exception is thrown from the Database layer it will be caught and we will successfully rollback the transaction. If everything goes smooth we go ahead and complete the transaction.

    Similarly we will create the EmpSkillsManager class

    using System;
    using System.Collections;
    using System.EnterpriseServices;
    using EmpDataDLL;
    namespace BussDLL
    {
            public class EmpSkillsManager:ServicedComponent
            {
                    public EmpSkillsManager() {}
                    public void UpdateSkill(EmpEntity.Employee emp)
                    {
                            EmpDataDLL.SkillDataStore skillsDB = new SkillDataStore();
                                    skillsDB.UpdateSkill(emp.Skills);
                                    ContextUtil.SetComplete();
                    }
            }
    }


    Sometimes we want that if everything goes fine the transaction should be automatically completed only incase of any failure when an exception is raised the transaction should be aborted. In that case we can use the AutoComplete attribute i.e. [AutoComplete]

    AutoComplete attribute is used at function level. When we use AutoComplete we need not call SetComplete but yes we need to call SetAbort.

    Using the AutoComplete attribute

    namespace BussDLL
    {
            [Transaction(TransactionOption.Required)]
            public class EmployeeManager
            {
                    public EmployeeManager()
                    {}
                    [AutoComplete] 
                    public void UpdateEmployee(Employee emp)
                    {
                            try
                            {
                                    EmpDataDLL.EmployeeDataStore empDataStore= new EmpDataDLL.EmployeeDataStore();
                                    empDataStore.Update(emp);
                            }
                            catch(Exception ex)
                            {
                                    ContextUtil.SetAbort();
                                    throw ex;
                            }
                    }
            }
    }

    January 16

    COM+ Services Series ( Part - 3 )

    Today we will discuss ECC features of COM+. These features were not present in MTS and but are present in COM+ Services.

    Events: - This is a new service that has been added in COM+. This service one has to register an event interface with COM+ Services. Then you register classes that raise this event. These classes are called as publishers. After registering publishers you create classes that handle the raised events. These are called as subscribers. This model is also called as publisher-subscriber model. Hence when publisher raises an event COM+ will notify all its subscribers.

    Here COM+ acts as an intermediate layer between publisher class and subscriber classes so that they do not refer each other directly.

    Component Message Queuing: - In the past a lot of times there have been instances when we have faced problems of the component not being available or the component being offline. For these situations we had to provide some error handling logic. But COM+ now provides us with a new option for queuing requests for any offline component so that when the component comes online it can forward the request to the component. All these things happen behind the scene and the client is completely unaware of this. As soon as the component available the requests are executed and the results are sent to the client.

    But if we have looking forward for this option then we should have robust error handling coz it should not happen the client is waiting for prolonged period of time or even if the component is available the request raised an error or exception.

    Component Load Balancing: - This is one of the most important feature of COM+. Component load balancing is used to cater a large number of clients by balancing client requests between COM+ Components. When one feels that one server is not enough to provide a quick response to the clients and the client response time is increasing, you can have multiple servers hosting your components. Component Load balancing is used to balance the number requests across servers. It distributes client requests across component servers thus enabling a fast and better performance and reducing the response time.

     If we were to consider component load balancing we should keep in mind the fact the request may not go to the same server every time. Hence the architecture of all our objects should stateless. I had discussed this before also when we checked out JIT and object pooling. Object pooling is not available when Component Load balancing is done for obvious reasons coz you do not where the previous request was executed

    COM+ Services Series ( Part - 2 )

    Let us first discuss the JOTS features. These features were present in MTS and are present in COM+ Service also.

    Just-In-Time Activation: - Object creation by itself is a very expensive process hence before instantiating an object we need to consider a lot of parameters like the amount of memory it will take, how many objects will be created at any given point of time, after instantiating objects how will we deallocate its memory, etc.

    Just-in-time Activation allows the developer to create an object once and then use it wherever required without worrying about resources consumed by that object. This is because behind the scenes JIT deallocates the memory when the object is not used and then reallocates then when the client references the object or calls any method on them. Thus the client can hold references to as many objects required coz COM+ will provide objects whenever necessary and deallocate them when required.

    Since JIT deallocates memory it is quite possible that it may dellocate memory between two function calls, thus there is no guarantee that the same property values will be available between subsequent calls. Hence the COM+ objects should ideally be stateless (i.e. should not have properties).

    Object Pooling:

    - We just discussed JIT and saw how COM+ handles its memory allocation and deallocation coz object creation is an expensive process. Further on to that COM+ even allows you to create an object pool to reuse objects that are created. Whenever any COM+ client releases an object COM+ does not destroy the object if ObjectPooling is enabled but sends the object to the Pool to reuse the object when some other client asks for the same.

    By Nature object Pooling can share the object instance between several clients. Thus if you have properties in your class they will be shared across all the clients. Hence to avoid this it is a good practice to create class that are stateless. So that in between function calls there is no need to maintain the state.

    Note:

    - JIT and Object Pooling together make the heart of COM+. Object Pooling may have a pool of objects reusable across clients but its JIT that decides its allocation and deallocation. Thus making the objects stateless is a very good practice coz then we can use both the services effectively as our classes reduce to function libraries.

    Transaction Enforcement: - There are 5 transactions types that can be used with COM+. Whenever an object is registered with COM+ it has to abide either to these 5 transaction types.

    Disabled: - There is no transaction. COM+ does not provide transaction support for this component.

    Not Supported: - Component does not support transactions. Hence even if the calling component in the hierarchy is transaction enabled this component will not participate in the transaction.

    Supported

    : - Components with transaction type supported will be a part of the transaction if the calling component has an active transaction.

    If the calling component is not transaction enabled this component will not start a new transaction.

    Required: - Components with this attribute require a transaction i.e. either the calling should have a transaction in place else this component will start a new transaction.

    Required

    New: - Components enabled with this transaction type always require a new transaction. Components with required new transaction type instantiate a new transaction for themselves every time.

    Security

    : - This is another important aspect of COM+. This allows granting access rights to users at component level. COM+ allows you to create roles and add users to these roles. Hence when a user tries to instantiate an object COM+ checks the users role. You can define different roles and access rights for these roles. If the user is in role defined he/she will be granted rights as defined for that role.

    COM+ Services Series ( Part - 1 )

    Today we are going to discuss COM+ Services. Some of us know COM+ coz we have worked with MTS during our VB days. However COM+ can be used with .NET also. As a developer I have always inquisitive about a lot questions and I am sure that you must also be having these questions in mind. Let us discuss these: -

    Why COM+ ?

    Well COM+ by itself is a service where you deploy your transaction-based components. Once can say that it is reusable service which can help you in implementing and executing your transactions so that you need not be bothered about the repetitive" transaction execution and management" logic all the time.

    What is MTS and what is difference between MTS and COM +?

    During our VB days with Win NT one could use COM+ Services with the help of MTS i.e. Microsoft Transaction Server. You needed to explicitly install MTS.  After WinNT came Win 2k where it has been an integral part of OS. COM+ services in addition to MTS has come more features like:

    Common features in both MTS and COM+:

    • Just In Time object activation (JIT)
    • Object Pooling
    • Transaction Enforcement
    • Security

    I remember them as JOTS features.

    New Features in COM+:

    • Event Support
    • Component message queuing
    • Component Load Balancing

    I remember them as ECC features.

    What are Transactions? Are they really necessary? What can they do for you?

    Transaction is a set operations that need to work as a unit to either fail or succeed. Whether transactions are really necessary or not totally depends on your requirement e.g. If you are making a banking application where during a Credit transaction money has to be debited from one account and credited to another account. In this scenario it will not work if either debit or credit happens both either need to happen or not. You can also use the ADO or ADO.NET Connection object to execute them under a single transaction.

    How do transactions work?

    COM+ services are controlled by DTC i.e. Distributed Transaction Coordinator. It is DTC, which takes care of transaction execution and is responsible for commit or rollback. DTC works on a "Two - Phase Commit" protocol. Transaction by itself is a unit containing a number of operations. Two phase commit ensures that the transaction is commit only if each of these operations succeed if any one of these operations participating in the transaction fail, the entire transaction is roll backed completely. Thus protocol ensures a successful commit or a rollback.

    Tomorrow we will discuss each of COM+ features in depth. If you have any questions on the basics that we discussed today please post them.

    Overriding, Shadowing and Hiding in .NET

    Most of us I guess are familiar with overridering from C++ or Java. Overriding as the term says is to override  the base class  implementation  or provide a new  implementation in the derived class. We can override members in the base class in VB.Net using  the keyword Overrides and in C# using the key word override. To override a base class member in VB.Net it should be marked as  Overridable and in C# they should be marked with virtual. Method signature of the overiddden methods should be same as the base  class methods.

    Shadowing :- This is a VB.Net Concept by which you can provide a new implementation for the base class member without overriding  the member. You can shadow a base class member in the derived class by using the keyword "Shadows". The method  signature,access level and return type of the shadowed member can be completely different than the base class member.

    Hiding : - This is a C# Concept by which you can provide a new implementation for the base class member without overriding the  member. You can hide a base class member in the derived class by using the keyword "new". The method signature,access level and  return type of the hidden member has to be same as the base class member.

    Comparing the three :-

    1) The access level , signature and the return type can only be changed when you are shadowing with VB.NET. Hiding and overriding  demands the these parameters as same.

    2) The difference lies when you call the derived class object with a base class variable.In class of overriding although you assign a  derived class object to base class variable it will call the derived class function. In case of shadowing or hiding the base class function  will be called.

    Let us create a sample application and this check out :-

    1) Create a new solution and three projects to it. One VB.Net Class Library, another C# Class Library and C# Console Application as  a Client Application.

    2) Name your VB.Net Class Library as Shadowing , C# library as Hiding and Your console application as Client Application.

    3) In Shadowing add a class file called Shadow.vb and add the following classes to it.

    Public Class BaseShadow

        Public Overridable Function OverrideMe() As String
            Return "Base Class Override Me"
        End Function

        Public Function ShadowMe() As String
            Return "Base Class Shadow Me"
        End Function

    End Class


    Public Class DerivedShadow
        Inherits BaseShadow

        Public Overrides Function OverrideMe() As String
            Return "Derived Class Override Me"
        End Function

        Public Shadows Function ShadowMe() As String
            Return "Derived Class Shadow Me"
        End Function

    End Class

    4) In Hiding add class file called Hide.cs and add the following classes to it.

    using System;

    namespace Hiding
    {
            public class BaseHide
            {
                    public BaseHide()
                    {

                    }

                    public virtual string OverrideMe()
                    {
                            return "Base Class Override Me";
                    }

                    public string HideMe()
                    {
                            return "Base Class Hide Me";
                    }

            }

            public class DerivedHide:BaseHide
            {
                    public DerivedHide()
                    {

                    }
                    public override string OverrideMe()
                    {
                            return "Derived Class Override Me";
                    }

                    public new string HideMe()
                    {
                            return "Derived Class Hide Me";
                    }

            }
    }

    5) Build both the Class Libs and add their refernces to the client console application.

    6) Add the following code in the Main of the console Application.

    using System;
    using Hiding;
    using Shadowing;
           
    namespace Client_Application
    {
            /// <summary>
            /// Summary description for Class1.
            /// </summary>
            class Client
            {
                    /// <summary>
                    /// The main entry point for the application.
                    /// </summary>
                    [STAThread]
                    static void Main(string[] args)
                    {

                            Console.WriteLine("// ****  Overriding **** //");
                            // ****  Overriding **** //

                            Shadowing.DerivedShadow derivedShadowOverrideObject = new Shadowing.DerivedShadow();
                            Console.WriteLine("Accessing thru derived class " + derivedShadowOverrideObject.OverrideMe());

                            Shadowing.BaseShadow baseShadowOverrideObject = new Shadowing.DerivedShadow();
                            Console.WriteLine("Accessing thru base class " + baseShadowOverrideObject.OverrideMe());

                            Hiding.DerivedHide derivedHideOverrideObject = new Hiding.DerivedHide();
                            Console.WriteLine("Accessing thru derived class " + derivedHideOverrideObject.OverrideMe());

                            Hiding.BaseHide baseHideOverrideObject = new Hiding.DerivedHide();
                            Console.WriteLine("Accessing thru base class " + baseHideOverrideObject.OverrideMe());


                            // ****  Hiding **** //

                            Console.WriteLine("// ****  Hiding **** //");
                   
                            Hiding.DerivedHide derivedHideObject = new Hiding.DerivedHide();
                            Console.WriteLine("Accessing thru derived class " + derivedHideObject.HideMe());
                           
                            Hiding.BaseHide baseHideObject = new Hiding.DerivedHide();
                            Console.WriteLine("Accessing thru base class " + baseHideObject.HideMe());

                            // ****  Shadowing **** //

                            Console.WriteLine("// ****  Shadowing **** //");

                            Shadowing.DerivedShadow derivedShadowObject = new Shadowing.DerivedShadow();
                            Console.WriteLine("Accessing thru derived class " + derivedShadowObject.ShadowMe());

                            Shadowing.BaseShadow baseShadowObject = new Shadowing.DerivedShadow();
                            Console.WriteLine("Accessing thru base class " + baseShadowObject.ShadowMe());

                            Console.ReadLine();
                    }
            }
    }

    7) Execute the code and checkout the differences. You can even go ahead and change the method signature, accesslevel and return type for Shadowing and check it out.

    December 23

    Article : WebServices Series Part - 5 ( Sync & Async Communication )

    Yesterday we saw how we can communicate with web services using callbacks. Today we will discuss the other two techniques  Polling and Waithandles.

     
    Polling :

    When we made a call to our web service using callback we passed it reference to our fucntion and in return we get an IAsyncResult  object back which acted as a token.

    In case of polling we will again call BeginCoSine method but not pass any parameter for callback. This method will return us an  IAsyncResult object. Polling works on one of the properties of this object called IsCompleted. After calling the method we will have to  continuous POLL for the value of this property. When the webservice is completed with its processing the value IAsyncResult object  will be set to true.After that we call the EndCoSine function passing it our IAsyncResult object (which acts as a token) to retrieve our  result.

    Add another button to your windows form and put in the below code :

                    private void button3_Click(object sender, System.EventArgs e)
                    {
                            int noOfSec = 0;
                            oIAsyncResult = trigoService.BeginCoSine(90,null,null);
                            while(oIAsyncResult.IsCompleted == false)
                            {
                                    noOfSec++;
                                    Thread.Sleep(1000);
                            }
                            MessageBox.Show("Completed in " + noOfSec);
                            label1.Text =  Convert.ToString(trigoService.EndCoSine(oIAsyncResult));
                    }


    Here we are checking out the value of IsCompleted property in a while loop. After the value is set to true we message the number of  seconds that were taken to POLL. Finally we call EndCosine function passing our IAsyncResult object.

    WaitHandles :

    This method also uses one of the properties of IAsyncResult object called AsyncWaitHandle.

    This approach is generally used when u dont want to leave the thread in which you are communicating with the webservice. Thus in  this case you will wait for the webservice to complete its work without releasing the thread in which you were communicating. You can achieve this by using the WaitHandle returned by AsyncWaitHandle property of IAsyncResult object.

    After you have called the BeginCosine method and got your IAsyncResult Token object you can use its AsyncWaitHandle property to  get WaitHandle object then use its WaitOne method to wait for the thread. WaitOne has multiple overloads some also take the  amount of time you want to wait.

    Add another button to your windows form and add the following code snippet

                    private void button4_Click(object sender, System.EventArgs e)
                    {
                            int noOfSec = 0;
                            oIAsyncResult = trigoService.BeginCoSine(90,null,null);
                            oIAsyncResult.AsyncWaitHandle.WaitOne();
                            while(noOfSec++ < 5)
                            {
                                    noOfSec++;
                                    Thread.Sleep(1000);                            
                            }
                            MessageBox.Show("Waited for " + noOfSec);                      
                            label1.Text =  Convert.ToString(trigoService.EndCoSine(oIAsyncResult));        
                    }

    You can also checkout the other static methods of the WaitHandle object like WaitAll and WaitAny. These methods are particularly  used when you have multiple web service calls and you want to wait for either ALL of them to complete their processing and then  move ahead or with ANY ONE of them to complete their processing and then move ahead.

    WAIT ALL :- Wait for all the web services to complete processing.
    WAIT ANY:- Wait for any one of them to complete processing.

    Article : WebServices Series Part - 4 ( Sync & Async Communication )

    Today we will checkout how to consume our web service using SOAP in Synchronous and Asynchronous modes.

    To consume to our web service we need to create our web service client.

    Let us go ahead and create our web service client.

    Open a new windows application and Select References Right click and select Add Web Reference. Select our Trigonometry web service.

    WebReference to this web service will be added and along with it you will notice the reference.map , .disco and .wsdl files will be added for the web service. Our client interacts with our web service using a proxy class.

    To view the proxy class ... Select the solution in the Solution Explorer and click on Show All Files ... You will notice a file under the Reference map node called as Reference.cs.

    Open the Reference.cs file and Checkout the BASE CLASS for our webservice proxy class, it should be SoapHttpClientProtocol.

    You should also notice that for each method in our webservice there are three methods in the webservice proxy class.

    For Example these are the the three methods for Sine.

     public System.Double Sine(System.Double angel)
     public System.IAsyncResult BeginSine(System.Double angel, System.AsyncCallback callback, object asyncState)
     public System.Double EndSine(System.IAsyncResult asyncResult)

    Out of these three the first one is used for Synchronous communication and latter two for Asyncrhomous communication.

    Let us checkout Synchrounous Communication.

    Add a Form and add a button and a label to that Form

    Declare a class level variable for our webservice

                    localhost.Service1 trigoService = new localhost.Service1();

    Write the following code in the button Click event

                    private void button1_Click(object sender, System.EventArgs e)
                    {
                            label1.Text = Convert.ToString(trigoService.Sine(90));
                    }

    Execute the apllication and checkout the results.

    One of methods of Asynchronous communication with web service is using Callbacks.

    To start with declare a class level variable for IAyncResult 

            private IAsyncResult oIAsyncResult;

    To consume our web service in asynchronous mode let us add another button to our form and add the below code. When we communicate with our web service in a asynchronous mode we will have to call the BeginSine method and pass a CALLBACK function to it. After our web service is done with its processing it will callback our function to return the result.

                    private void button2_Click(object sender, System.EventArgs e)
                    {                      
            oIAsyncResult = trigoService.BeginSine(90,new AsyncCallback(CallBackForEndSine),null);
                    }

                    public void CallBackForEndSine(IAsyncResult oIAsyncResult)
                    {
                            double sineVal = trigoService.EndSine(oIAsyncResult);                  
                            label1.Text = Convert.ToString(sineVal);
                    }

    Here I am calling the BeginSine method and passing it the reference of our CallBack method CallBackForEndSine. You should notice that on Calling the BeginSine method I am returned an IAysncResult object. This object acts as a TOKEN between the client and the webservice. Hence when the Webservice is through with its processing and Callback method is called, to get the result from the webserivce we need to call EndSine method in the CallBack method passing IAsyncResult Token.

    The Difference between Asynchronous  & Synchronous consumption of webservices can be noticed when there is a lot of processing done by a webservice. Thus if our webservice is consumed in a synchronous mode then our clients will have to wait for the processing to complete.

    To get a good taste of Asynchronous processing with our webservice we will make a little change in our methods. Before returning the result we will make the thread sleep for 20 secs.  


                    public double Sine(double angel)
                    {
                            Thread.Sleep(20000); // make a similar change in all the methods
                            return System.Math.Sin(angel);
                    }

    Compile the webservice. Update the webservice reference in your Client project and Execute your Client.

    Now if our web service is consumed synchrounsouly our client will have to wait for the result. Click on Button1 and check it out. The control will come back after 20 secs and till then your application will not respond to any other events. Now let us consume the webservice in an ansychronous mode by clicking on Button2. Since the communication is asynchronous the control will return back immediately rather than waiting for 20 seconds. Later the call back function will be called to deliver the results.

    WebServices Series Part - 3 (Accessing with HTTP POSTLOCALHOST, POST and GET)

    Today we will look how we can access web services with HTTP-GET and HTTP-POST protocols. 

     .Net Framework 1.0 had all the three protocols i.e. HTTP-POST,HTTP-GET AND HTTP-SOAP enabled by default. But in version 1.1 only HTTP-SOAP is enabled by default. Hence if you want to access the web service my HTTP-POST or GET then you will have to enable it explicitly.

     Since HTTP-POST is not enabled by default in .Net framework 1.1 to test web service on the local machine there is a new protocol that has been added i.e. HTTPPOSTLOCALHOST. It is because of this protocol that while testing a web service you are able to view a test form on your local machine and not on a remote computer.

    Let us check out each of these protocols individually: -

    HTTPPOSTLOCALHOST: - This is enabled by default in .Net Framework version 1.1. Hence if you access your website as http://localhost you will get the test form but if you test the same web service with http://<name of your computer> from some other computer than the test form will not be displayed.

    e.g. Try and access our trigonometry web service from your machine and then access it from any other machine. You will notice that the test form will not be displayed.

    Before we look at HTTP-POST and HTTP-GET we need to checkout DefaultWsdlHelpGenerator.aspx.

    DefaultWsdlHelpGenerator.aspx is the default wsdl help file located at

    <drive>:\WINNT\Microsoft.NET\Framework\v1.1.4322\CONFIG.

    Open DefaultWsdlHelpGenerator.aspx and checkout showPost flag.

        bool showPost = true; // search for this

    Depending the value of showPost flag HTTP-GET or HTTP-POST  protocol is used.Set its value to true if you want to see a POST test form and false to view  a GET test form.

    Along with this you will have to include the appropriate protocols in the web services tag in Web.config.

    HTTP-POST: - To enable our web service with HTTP-POST we will have to make the following changes.

    1. Open the web.config and add the <webServices> tag under <system.web> as follows to enable the HTTP-POST protocol.

         <webServices>
             <protocols>
                <add name="HttpPost"/>
             </protocols>
          </webServices>

    2. Open DefaultWsdlHelpGenerator.aspx and set the value of showPost to true. By default it is set to true.
    3. Run the web service and checkout the HTTP-POST form.
    4. On execution you will see the xml output of your webservice. Checkout the URL of output in the browser it will not show any querystring parameters.

     http://namrathas/Trigonometery/MyService.asmx/CoSine

    5. Execute your web service from some other computer and you will be able to view HTTP-POST test form.

    HTTP-GET: - To enable our web service with HTTP-GET we will have to make the following changes.

    1. Open the web.config and add <add name="HttpGet"/>  to protocols tage s follows to enable our webservice with HTTP-GET protocol also.

         <webServices>
             <protocols>
                <add name="HttpPost"/>
                <add name="HttpGet"/>
             </protocols>
          </webServices>

    2. Open DefaultWsdlHelpGenerator.aspx and set the value of showPost to false. So now HTTP-POST form will be displayed. All the parameters will be passed as querystring.

     http://namratas/Trigo/MyService.asmx/CoSine?angel=5

    3. Run the web service and checkout the HTTP-GET form. Its looks the same as HTTP-POST form. You will notice the difference on execution.
    4. Execute the web service and you will see the xml output of your webservice. Checkout the URL of output in the browser it will show query string parameters passed to the web method.

    HTTP-SOAP: - Whenever our webservice is accessed from any application HTTP-SOAP protocol is used. HTTP-SOAP is enabled by default. We will look in to more details of HTTP-SOAP when we look into consuming webservices.

    Hence if want our webservice to be enabled for all the four protocols we need to add them in the <protocols> tag.

         <webServices>
             <protocols>
                <add name="HttpPost"/>
                <add name="HttpGet"/>
                <add name="HttpSoap"/>
                <add name="HttpPostLocalhost"/>
             </protocols>
          </webServices>

    WebServices Series Part - 2 (WebMethod and WebService Properties)

     After creating our basic web service yesterday we will look into the web method properties and supported data types.

    Well Whenever we create a web service all those methods of the web service which we want to be web-callable have to be marked with the web method attribute and should have a public access modifier. Web Method Attribute is basically used to make a method web callable.

     WebMethod attribute has the following properties like :-

    • Description
    • TransactionOption
    • CacheDuration
    • BuffferResponse
    • EnableSession
    • MessageName

     

    Description :- It is used for commenting the web method. The description that is added here is included in WSDL. Add the

    webmethod description property above any method as shown below. When you call the webservice from a browser you view the web service.

     

     e.g. [WebMethod(Description = "My WebMethod Description comes here")]

     

    Enable Session :- WebServices are a type of ASP.NET applications hence you can access your ASP.NET application Session from your webservice. By default the session is disabled i.e. set to false. You can enable it by setting its value to true.

     

     e.g. [WebMethod(EnableSession ="true")]

     

    Message Name :- Message Name property is used give an alias to a method name. This is esp. useful when you are using overloaded methods.

     

    e.g. Yesterday we created  3 method in our webservice for cos,sin and tan which took double as an input parameter. Today we will create their overloads that will take int as an input parameter

     

      [WebMethod]
      public double Tan(int angel)
      {
       return System.Math.Tan(angel);
      }
      [WebMethod]
      public double Sine(int angel)
      {
       return System.Math.Sin(angel);
      }
      [WebMethod]
      public double CoSine(int angel)
      {
       return System.Math.Cos(angel);
      }

     

    If you compile this code it will compile successfully. It is on execution that you we view the below error message

     

    Error Message: Both Double Tan(Int32) and Double Tan(Double) use the message name 'Tan'. Use the MessageName property of the WebMethod custom attribute to specify unique message names for the methods.

     

    Web service needs to identify each method uniquely hence we will give alias to the methods by setting the MessageName property.

     

     e.g. [WebMethod(MessageName = "SinInt")]
           [WebMethod(MessageName = "CosInt")]
           [WebMethod(MessageName = "TanInt")]

     

    TransactionOption : - If our web service is a part if any COM/MTS transaction application then we can enable the Transaction Option of the webservice thus making it a part of the  2 phase commit protocol of MTS.

     

     e.g.     [WebMethod(TransactionOption = "Supported")]

     

    The dafault is same as COM/MTS transactions i.e. Required.

     

    CacheDuration :- Like any other ASP.NET applications WebServices also support output caching. Output caching gives a performance boost coz the same request is not executed repeatedly instead the result is return from the cache itself. This feature is

    esp. useful when you are retrieving chunks of data from the database for listing and other purposes. But caching should preferably used with only those methods where we know that the data will not change frequently.

     

     e.g.     [WebMethod(CacheDuration = "180")] 
     
    This means the output of this method will be cached for  seconds.

     

    BuffferResponse :- We all are familiar with the buffering property rite from our ASP days where used Response.Buffer = true so that

    the response is only sent when the Response for the request is completely generated or when the buffer is full. WebServices also use the same logic. If we want our response to be sent across only after its complete processing is done we need to buffer our response by setting its property to true.

     

     e.g.     [WebMethod(BufferResponse = "true")] 

     

    By default it is set to true.

     

    These properties were webmethod properties. We also have some web service properties like

     

    • Description.
    • Name
    • NameSpace
       

    Description :- This is same as web method property. It is used to comment web service and give it a description that is included in WSDL.

     

     e.g. [WebService(Description = "My WebService Description comes here")]
      public class MyService : System.Web.Services.WebService

      {
    Name :- By default the name of the class is used as the service name but incase we want to give a different service name which will to exposed to our clients and in WSDL we can set the Name property. This property will override the default value i.e. the class name.

     

     e.g. [WebService(Name = "MyNewName")]
      public class MyService : System.Web.Services.WebService
      {

     

    NameSpace :-  The default name space is http://tempuri.org. You can change this to http://localhost/MyWebServices. You should set namespace to any unique value.

     

     e.g. [WebService(Namespace = "http://localhost/MyWebServices")]
      public class MyService : System.Web.Services.WebService
      {