Click here to Skip to main content
Click here to Skip to main content

.NET Remoting under IIS - ASP.NET Application as Client

By , 2 Aug 2009
 

Introduction

I have come across couple of good articles that tell us about creating .NET remote application, but none of these use ASP.NET application as client. Even the MSDN example, Hosting in Internet Information Services (IIS), uses a console application as client.

Background

If the remote object is to be accessed through the internet, one should implement their own security to authenticate the user as .NET remote applications require FullTrust permissions to execute. By hosting remote application under IIS, implementing security becomes much easier especially when the intranet is protected from the outside world by a firewall and the allowed communication channel is HTTP.

Using the Code

Here are the steps to create a server application and client application.

Server Object

  1. Create a new VB.NET or C# class library IServer and replace code in Class1.vb with the following. Compile the project to IServer.dll.
    Public Interface IServer
    
        Function getServerTime() As DateTime
    
    End Interface
  2. Create new VB.NET or C# Class Library project with clsServer class which will implement getServerTime function of interface IServer.
    Public Class clsServer
        Inherits MarshalByRefObject
        Implements IServer.IServer
    
        Public Overridable Function getServerTime() _
                 As DateTime Implements IServer.IServer.getServerTime
            Return Now.ToString()
        End Function
    End Class
  3. I have also included one more function in the demo project to create a file in the server. This will convince the user beyond any doubt that remote object did get activated through transparent proxy. Please make sure that the folder where you want to create the file has write permissions.
  4. Compile this project into "Server.dll" or any other name that is appropriate.
  5. Create a new virtual directory, Server under IIS - either by using "Virtual Directory Creation Wizard" or
    • Create new folder under c:\Inetpub\wwwroot and rename it to Server.
    • Open IIS management console, view properties of the Server folder.
    • Click on the Create button against the "Application name", by default new application name will be the name of the folder. Click on OK button to close the properties window.
  6. Navigate to Server folder in Windows Explorer and create a sub folder "bin" under Server folder.
  7. Copy "Server.dll" into the bin folder.
  8. Create new text file, type the following XML code and save it as "web.config" and not as web.config.txt (by selecting "All files" in the Save As dialog box or by enclosing the file name in double quotes in the save dialog box). This XML code declares the service and channel. MSDN has a lot of information about each of these XML attributes that we are coding here.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <system.runtime.remoting>
        <application>
    
            <service>
                <wellknown mode="Singleton" type="Server.clsServer,
                           Server" objectUri="server.soap" />
            </service>
            <channels>
                <channel ref="http" />
                <serverProviders>
                    <formatter href="binary" />
                </serverProviders>
            </channels>
        </application>
    </system.runtime.remoting>
    </configuration>
  9. The most important attribute that we need to understand is "type". In the above example, its value is "Server.clsServer, Server" which is nothing but "RootNamespace.ClassName, Assembly name". To find out what these value are for an existing project, just right click on the project name in solution explorer and choose properties. ObjectUri is something that uniquely identifies this object which is required to invoke this object from client. We can use the other format "Server.rem" .
  10. The channel that we are using is HTTP and formatter is binary. Please refer to MSDN for alternative channels and formatters. We need to use HTTP here as we are hosting our server object under IIS and binary formatter is more efficient over SOAP formatter.
  11. At this stage, if you type the URL http://localhost/Server/Server.soap?wsdl in the explorer address bar (assuming that you are hosting the server object in your local system, else replace "localhost" with valid webserver name), you should see the XML output. This XML is what describes the service that we are hosting under IIS.
  12. It's about time to talk about the client.

ASP.NET Client Application

  1. Create a new ASP.NET web application.
  2. We need a reference to the server object before coding any of the function calls. Now we have several options at this stage, you could actually add the server.dll to the references (even though we are not going to use the local objects, this is the laziest way), create a proxy using soapsuds.exe tool or create an interface and reference that interface. Soapsuds tool has a limitation in that you need to create a proxy for each of the class objects in an assembly. Try the following command at .NET command prompt, you should have "proxy.dll" created for you by soapsuds.exe and you can add a reference to this proxy object. But this will not work for assemblies that encapsulate several classes.

  3. We can also use a more powerful WSDL.exe tool to create proxy class source code which can be included in the project. The remote objects can be created as if they are local to the client.

    If you open this file, you will find the URL, http://localhost/server/server.soap in the class constructor. This proxy class will also have other methods like BegingetServerTime and EndgetServerTime which are used for making asynchronous calls.

  4. The other recommended method is to use Interfaces as we are doing in this case. In the client ASP.NET project, add a reference to the ISever.dll.
  5. Type...
    Imports System.Runtime.Remoting

    ... at the top of the page to use .NET remoting infrastructure.

  6. Now type the following code in the Page_Load event of the WebForm1.
    Private Sub Page_Load(ByVal sender As System.Object, _
                       ByVal e As System.EventArgs) Handles MyBase.Load
    
        Dim objRemote As IServer.IServer
    
        'Getting transparent proxy 
        objRemote = Activator.GetObject(GetType(IServer.IServer), _
                      "http://localhost/server/server.soap")
    
        'Executing remote object function
        Response.Write(objRemote.getServerTime())
    
    End Sub
  7. Press F5 to execute and you should see the time displayed.

Points of Interest

You may be surprised that there is no mention of Client.exe.config or Global.aspx files so far. Client.exe.config file is required only when you want to use "new" operator instead of Activator.GetObject method. Having this file is a good idea when the server hosting remote objects is changing often and your code will execute normally by modifying ObjectUri in client.exe.config file without recompiling the server objects. This can also be achieved (as I do) by specifying remote object's URL as key under appSettings tag in web.config. This technique is extremely useful when copying projects from development/testing to production environment, all that you have to do is modify these config files to change the remote object's URL!

Another important aspect to remember is, if you want to pass custom class objects as parameters between the client and server application, these objects should be serialized at one end and deserialized at the other end. This can be achieved by implementing ISerializable interface or by implementing your own methods to convert objects into byte arrays.

References

  1. Absolute beginner's introduction to remoting
  2. Simple but potentially useful example of .NET Remoting
  3. .NET Remoting - Basic Maneuvers
  4. MSDN

History

  • 3rd March, 2005: Initial post
  • 1st August, 2009: Updated download file

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Raj Settipalli
Web Developer
Australia Australia
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhy is my example not working?memberPraveenBalanagendra21 Feb '13 - 11:31 
GeneralcoolmemberMubi | www.mrmubi.com3 Aug '09 - 10:11 
Generalu just copied others workmemberRAINBOW00727 Feb '08 - 23:23 
GeneralRe: u just copied others workmemberRaj Settipalli27 Feb '08 - 23:33 
QuestionProblem with .NET 2.0 :(memberajai808521 Sep '07 - 3:58 
Hi ,
First of all very much thanks for this article , and my full vote .
 
I know only c# ,so I have written a simple app as follows to host in IIS

using System;
 
namespace SvrApp
{
///
/// Summary description for Class1.
///

public class CRemotable:MarshalByRefObject
{
public CRemotable()
{
//
// TODO: Add constructor logic here
//
}
public string Hello()
{
return "Hello.... blah blah..";
}
}
}

 
and created the web.config






<!-- AjaiX.rem also seems working fine -->





<formatter href="binary" />






 
created a folder c:\inetpub\wwwroot\AjaiX\ and bin folder under this and pasted the file under bin as well as ajaix too , I dont know some times its showing file not found error , so i did like this
 
and generated stub like this
soapsuds -url http://ajai/ajaix/ajaix.soap?wsdl -gc
 
and created a console app which is the client

class IISHostTester
{
public static void Main()
{
SvrApp.CRemotable obj =Activator.GetObject(typeof(SvrApp.CRemotable),"http://ajai/ajaix/ajaix.soap") as SvrApp.CRemotable;
if(obj!=null)
{
Console.WriteLine(obj.Hello());
}
Console.Read();
}
}

 
This is just working fine , But the problem comes when I compile the code in .net 2.0 it will show the following error ....if i host the same dll compiled using csc2.0 , do you know how to solve this . I set the guid for the assembly every thing but still the problem is there .
 

Please let me know how to solve it this is coming in the Internet Explorer
 

 

 
System.BadImageFormatException: The format of the file 'SvrApp' is invalid.
File name: "SvrApp"
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(String assemblyString)
at System.Runtime.Remoting.RemotingConfigInfo.LoadType(String typeName, String assemblyName)
at System.Runtime.Remoting.RemotingConfigInfo.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingConfigHandler.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingServices.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.Channels.Http.HttpRemotingHandler.CanServiceRequest(HttpContext context)
at System.Runtime.Remoting.Channels.Http.HttpRemotingHandler.InternalProcessRequest(HttpContext context)
 
=== Pre-bind state information ===
LOG: DisplayName = SvrApp
(Partial)
LOG: Appbase = file:///c:/inetpub/wwwroot/AjaiX
LOG: Initial PrivatePath = bin
Calling assembly : (Unknown).
===
 
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Post-policy reference: SvrApp
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/ajaix/f395f484/78813567/SvrApp.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/ajaix/f395f484/78813567/SvrApp/SvrApp.DLL.
LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/AjaiX/bin/SvrApp.DLL.
 


 

 
<
 
Warm Regards
Ajai NP
 

GeneralEasy to understand, great articlememberrderose16 May '07 - 11:59 
QuestionWhat if server assemble containe more than one classmembersan.vb26 Feb '07 - 0:39 
AnswerRe: What if server assemble containe more than one classmemberRaj Settipalli26 Feb '07 - 13:19 
QuestionCannot load typememberdistressedflesh6 Feb '07 - 17:47 
QuestionChange in .net 2.0?memberfleclerc213 Nov '06 - 0:34 
GeneralDoesnt work on a live websitememberHemalRathod19 Aug '06 - 0:37 
GeneralRe: Doesnt work on a live websitememberRaj Settipalli24 Aug '06 - 11:21 
GeneralStrange problemmemberHet210925 Jul '06 - 1:54 
GeneralRe: Strange problemmemberRaj Settipalli25 Jul '06 - 20:36 
GeneralEvent Handlermemberaahmed1922 Jan '06 - 16:19 
QuestionHow about using Client Activated ObjectsussDavid Bartolome19 Sep '05 - 6:00 
AnswerRe: How about using Client Activated ObjectmemberRaj Settipalli19 Sep '05 - 12:49 
General(405) Method Not Allowedmemberxty_ceron29 Jun '05 - 9:46 
GeneralRe: (405) Method Not Allowedmemberajai808521 Sep '07 - 4:00 
GeneralCannot load type Server.clsServer, Serversusspv12345631 Mar '05 - 1:14 
GeneralRe: Cannot load type Server.clsServer, Serversusspv12345631 Mar '05 - 1:19 
GeneralRe: Cannot load type Server.clsServer, ServersussAnonymous31 Mar '05 - 14:19 
GeneralRe: Cannot load type Server.clsServer, Serversusspv12345631 Mar '05 - 18:38 
GeneralRe: Cannot load type Server.clsServer, ServersussRaj Settipalli31 Mar '05 - 19:00 
GeneralRe: Cannot load type Server.clsServer, Servermembermikecran15 Apr '05 - 5:15 
General'The remote server returned an error: (404) Not Foundmemberfipil23 Mar '05 - 5:46 
GeneralRe: 'The remote server returned an error: (404) Not FoundmemberRaj Settiappli28 Mar '05 - 11:59 
GeneralRe: 'The remote server returned an error: (404) Not FoundmemberRaj Settiappli28 Mar '05 - 12:01 
GeneralRe: 'The remote server returned an error: (404) Not Foundmembernitinpai20009 Oct '08 - 0:38 
AnswerRe: 'The remote server returned an error: (404) Not FoundmemberSarvesh Gupta24 Feb '09 - 1:59 
GeneralRe: 'The remote server returned an error: (404) Not FoundmemberHighCommand23 Dec '09 - 20:40 
AnswerRe: 'The remote server returned an error: (404) Not FoundmemberRaj Settipalli23 Dec '09 - 22:07 
GeneralRe: 'The remote server returned an error: (404) Not FoundmemberHighCommand12 Jan '10 - 0:27 
GeneralIServer.dllmemberTechnoBerry14 Mar '05 - 7:20 
GeneralRe: IServer.dllmemberRaj Settiappli14 Mar '05 - 12:28 
GeneralRe: IServer.dllmemberTechnoBerry14 Mar '05 - 14:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 2 Aug 2009
Article Copyright 2005 by Raj Settipalli
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid