papadi Development Blog

.NET and Software Development by Dimitris Papadimitriou 
Filed under

C#

 

For Silverlight starters...

For Silverlight 2 starters I recommend this free tutorial from silverlight.net:

http://silverlight.net/learn/tutorials.aspx

There is code available both in C# and VB.

Filed under  //   .NET   C#   Silverlight   Tutorials   VB   Web  

Comments [0]

Using extension methods to extend classes that already inherit from another class

As you may already know .NET does not allow multiple inheritance. Bill Warner describes how one can override this limitation by using interfaces and extension methods on that interfaces.

The result is impressive! You end up with some class A that inherits from some class B, implements some interface C, but since that interface C has extension methods, class A ends up inheriting them! If I may say so.... class A inherits the interface C!

Read this...

Filed under  //   .NET   C#  

Comments [0]

File transfer with progress indication using Windows Communication Foundation

UPDATE: For latest version of this article please refer to the related article on CodeProject. Please provide comments and questions there.

This article examines the implementation of upload and download functionality with progress indication (progress bar feature) using the Windows Communication Foundation. Here is a list of what you need:

Sample code consists of three C# projects bundled in a solution. A brief description of these projects follows.

FileService

This is the main server project.

The Server Contract

File Server project includes FileTransferServiceContract.cs file which contains the IFileTransferService. This interface describes the operations provided by our server. No actual work is done in this code file except from describing the operations provided. If you worked with service oriented applications before, you know that this job is important enough to spare a separate file for. Here are the two operations of our file transfer service:

  • DownloadFile server method. Accepts a DownloadRequest instance which contains the name of the file to be downloaded by the client and returns a RemoteFileInfo instance, defined in the same code file. RemoteFileInfo contains the name of the file to be downloaded, the file stream and the length of the file in bytes. This instance of the RemoteFileInfo class will be used by the client to download the file. You notice that file name and length are marked with the MessageHeader attribute in RemoteFileInfo class. This is because when a message contract contains a stream, this can be the only body member of the contract.
  • UploadFile server method. Accepts an instance of the RemoteFileInfo message contract. This is the same used in DownloadFile, only in this case length property is not required.
[ServiceContract()]
public interface IFileTransferService
{
[OperationContract()]
void UploadFile(RemoteFileInfo request);

[OperationContract]
RemoteFileInfo DownloadFile(DownloadRequest request);
}

public class RemoteFileInfo
{
[MessageHeader(MustUnderstand = true)]
public string FileName;

[MessageHeader(MustUnderstand = true)]
public long Length;

[MessageBodyMember(Order = 1)]
public System.IO.Stream FileByteStream;
}

The Server Implementation

File Server also includes the FileTransferService.cs code file which contains the implementation of the contract, i.e. the actual code that does all the work. Apparently the included class implements the IFileTransferService class which constitutes the service contract. If you have worked with streams before in .NET you will find out that the code the handles the stream and related information for upload or download is pretty straightforward. If you are new to .NET streams, please use google for a quick introduction.

Note here that since actual downloading of the file starts after the execution of DownloadFile method is completed (i.e. after the client gets the RemoteFileInfo instance returned by this method), the server must close the opened stream later, after the client completes the process. To do this, the WaitToClose method starts in a separate thread and queries the current position of the stream once in a while. If it detects that the position of the stream remains the same for some time (1 second in our sample code) this means that the client finished downloading, failed to do so or intentionally interrupted the procedure. In any case the stream should be closed. If not, the stream will remain locked and the corresponding file will be locked for writing. (Updated on 2007/09/09) A  more elegant approache was suggested by Buddhike) To do this IDisposable interface is implemented by the RemoteFileInfo contract and the stream is disposed on the corresponding Dispose method. If this is not done the stream will remain locked and the corresponding file will be locked for writing.

ConsoleHost

FileService is a class library, hence it cannot start as a window process; therefore it needs another executable file-process that will host it. Several type processes can host a WCF service, such as .NET executables, IIS process, Windows Activation Service (new feature of Vista) and many more. Our example uses a .NET executable to host our service. So ConsoleHost is a console application that does exactly this. Is has a reference to the FileService project, however it is not related in any way with the business our service is doing, i.e. transferring files. Actually the code you will find in Program.cs would be the same even if our service was designed to host an on-line grocery. Take a quick look at this code file to understand how our service is started and closed.

static void Main(string[] args)
{
ServiceHost myServiceHost =
new
ServiceHost(typeof(FileService.FileTransferService));
myServiceHost.Open();

Console.WriteLine("This is the SERVER console");
Console.WriteLine("Service Started!");
foreach (Uri address in myServiceHost.BaseAddresses)
Console.WriteLine("Listening on " + address.ToString());
Console.WriteLine("Click any key to close...");
Console.ReadKey();

myServiceHost.Close();
}

Configuration of ConsoleHost is what matters most! It is divided into three sections and configures the way our service will behave and how it will be exposed to the rest of the world. It is not the goal of this article to describe in detail how a WCF service is configured, so please refer to the WCF reference on MSDN for more information. Something noticeable in configuration of our service is that is uses MTOM as message encoding and stream as transfer mode. See also the maxReceivedMessageSize property. This defines the maximum size of messages transferred by our service. Since we are transferring files we want this property to have a large value.

<binding name="FileTransferServicesBinding" 
transferMode
="Streamed"
messageEncoding
="Mtom"
maxReceivedMessageSize="10067108864">
binding>

Client

Client project is a sample consumer of our service. You will notice that Client project includes a folder called 'Service References'. This folder contains a bunch of files created automatically by Visual Studio, by right clicking on the Client project root and selecting 'Add Service Reference'. If you don't see this option apparently you haven't installed VS 2005 extensions for .NET 3.0. Please see the requirements at the top of this document. The files in this folder are the proxy of our file transfer service on client side. Client is using these files to send requests to the server, hiding this way the complexity of Web Service and SOAP protocols.

Again, if you have worked with streams before you will notice that things are pretty simple in the TestForm file, except one small part, which is also the difference in implementing the progress indication when uploading than when downloading. When downloading, client has the control of the procedure. You can see in the TestForm.cs that downloading is implemented using a loop that reads the server stream piece by piece. So the client knows what part of the server stream is read and how many more remains. When uploading, that loop resides on server. In order for the client to know how many bytes the server read, it uses the StreamWithProgress class which inherits the System.IO.Stream. An instance of this class is passed to the server, instead of the original file stream. And since this class overrides the default Read method of the stream (see code bellow), it can report to the client the progress of the uploading process!

public override int Read(byte[] buffer, int offset, int count)
{
int result = file.Read(buffer, offset, count);
bytesRead += result;
if (ProgressChanged != null)
ProgressChanged(this, new ProgressChangedEventArgs(bytesRead, length));
return result;
}

UPDATE: For latest version of this article please refer to the related article on CodeProject. Please provide comments and questions there.

Filed under  //   .NET   C#   WCF  

Comments [0]

Throw command difference in C# and VB.NET

Have you ever noticed that throw command behaves somewhat differently in VB.NET and C#? See the following two code parts. It's the same thing written in VB.NET and C#. DummyMethod throws an exception (line 12) that is caught by a try/catch statement in the Main method. Line 7 writes the exception into the console window.

 1: static void Main(string[] args) {
 2:  try
 3:  { DummyMethod(); }
 4:  catch (Exception ex)
 5:  { Console.WriteLine(ex);
 6:  }
 7:  Console.ReadKey();
 8: }
 9:  
 10: private static void DummyMethod() {
 11:  try
 12:  { throw new Exception("Dummy Exception"); }
 13:  catch (Exception ex)
 14:  { throw ex;
 15:  }
  16: }
 1: Sub Main()
 2:  Try
 3:  DummyMethod()
 4:  Catch ex As Exception
 5:  Console.Write(ex)
 6:  End Try
 7:  Console.ReadKey()
 8: End Sub
 9:  
 10: Private Sub DummyMethod()
 11:  Try
 12:  Throw New Exception("Dummy Exception")
 13:  Catch ex As Exception
 14:  Throw ex
 15:  End Try
 16: End Sub

If you execute both pieces of code in Release configuration you see in your console window that the exception was thrown by line 14. Now remove the underlined ex variable from line 14, so that Throw command is left alone. If you execute the code now (still in Release configuration) C# code will write that the exception was thrown by line 14 again, but VB.NET code will write that exception was thrown by line 12!

Click here to download:
ExceptionTest._zip (9 KB)

Filed under  //   .NET   C#   VB  

Comments [0]

Write dataset contents to zip file

Assume that you want to write the contents of a dataset to xml, in order to send that data via e-mail or any other means. Have you noticed how verbose xml files are? However, if you try to compress one, you will notice that size of the compressed file is only a small fragment of the original! Just for testing, I compressed an 200MB XML file into a zip file, to see that the resulting file was 9MB only!
So, is it possible to write the contents of a dataset into an xml but include that xml directly into a zip file, without even creating a temporary file? Yes it is! Here is how. Note that the following code uses SharpZipLib, an open source Zip, GZip, Tar and BZip2 library.

        ' create a sample dataset
        Dim data As New DataSet
        ' TODO : add code that fills the dataset here

        ' create a zip output stream
        Dim FileStream As IO.FileStream = System.IO.File.Create("c:\output.zip")
        Using ZipOutputStream As New Zip.ZipOutputStream(FileStream)
            ZipOutputStream.SetLevel(9) ' maximum compression level

            ' create a new empty entry in zip file
            ' myData.xml will be the name of the xml file inside the zip
            Dim objZipEntry As New Zip.ZipEntry("myData.xml")
            ZipOutputStream.PutNextEntry(objZipEntry)

            ' write dataset to zip stream
            data.WriteXml(ZipOutputStream)
        End Using

Click here to download:
Dataset2Zip._zip (86 KB)

Uses : Visual Studio 2005, VB8

Filed under  //   .NET   C#   Code  

Comments [0]

ASP.NET on J2EE-enabled servers - Microsoft.VisualBasic.jar!

I downloaded and installed Grasshopper just to try it out! Installation was very smooth, without any of the difficulties I came upon every time I tried to install a non-Microsoft development tool. Well, ok, us, Microsoft oriented developers, may be a little spoiled! I just clicked on File-New-Project and there it was! VB for J2EE and C# for J2EE Projects! Amazing. My "Hello World" sample project was up and running on Tomcat (included in Grasshopper 50MB installation package) within 5 minutes! Right clicking on solution explorer allows to adding a reference to .NET and Java files! But one of the most astonishing things I have even seen in my humble carrier is this:

Microsoft.VisualBasic.jar !!!

Now I'm convinced!!! Anything is possible!
Unfortunately, since Grasshopper is based on Mono Project, it is available only for .NET Framework 1.1 and Visual Studio 2003. I read somewhere in Grasshopper forum that version for .NET Framework 2.0 is expected by the end of this summer.

About Grasshopper
Grasshopper, the freely available Visual MainWin® for J2EE™, Developer Edition, is a plug-in to the Visual Studio .NET IDE that enables .NET developers to port existing ASP.NET and server applications to J2EE servers. Developers can also use .NET skills to develop, debug, and deploy server and Web applications from within the Visual Studio .NET development environment, and run applications natively on the J2EE platform. Grasshopper is designed for small user group deployments.

Filed under  //   .NET   C#   VB   Visual Studio  

Comments [0]

Setting and restoring cursor for a time consuming operation in a single line of code

For the proper handling of the Hourglass during a time consuming operation the following code is required (more or less):

C# VB.NET
this.UseWaitCursor = true;
try
{  // DO JOB
   this.UseWaitCursor = false; }
catch (Exception ex)
this.UseWaitCursor = false;
    throw ex; }
Me.UseWaitCursor = True
Try
   ' DO JOB
   Me.UseWaitCursor = False
Catch ex As Exception
   Me.UseWaitCursor = False
   Throw ex
End Try

What if we wanted to be more accurate and restore the cursor to it's original state, which could be 'true' and not 'false'? Then we should declare a local variable, hold the original state and restore it later.
How would you like to use the following code!? Isn't it much more elegant?

C# VB.NET
using (new WaitCursorHandler(this))
{
   // DO JOB
}
Using WaitCursorHandler(Me)
   ' DO JOB
End Using

Simply add one of these files into your project (code requires .NET 2.0).

Filed under  //   .NET   C#   VB   Windows Forms  

Comments [0]

Most of things require much lesser code in .NET. Some things NOT!!!

Intro | After a few years dealing with .NET I can say that I'm very please with the fact that I have been working with Microsoft Development tools in my carreer. And this includes starting from GW-Basic, moving to VB5 and 6 and now 7 and 8 and a little C#.
Less Code | Most of things require much lesser code to implement. The code is almost completely managed and there are much fewer chances of using third part components or WIN32 API to get thigs done.
However | There are some other things however that require more code than before. And the question is why? For instance, to detect if the user clicked on the X button of a window to close it was 5 lines of code, including the event declaration, in VB6:

[code language="vb"]
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    If UnloadMode = vbFormControlMenu Then
        Cancel = True
    End If
End Sub
[/code]

Now, the code in NET Framework 2 is the following, as David Kean indicated to me in this thread http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=63488 (its in C#, but the same applies to VB8). It about 10 lines of code, without the brackets, which include a class level variable declaration:

[code language="c#"]
using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Windows.Forms;

namespace MyApplication
{
    public class Form1 : Form
    {
        private const int WM_SYSCOMMAND = 0x0112;
        private const int SC_CLOSE = 0xF060;
        private bool _UserClose;

        public Form1()
        {
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (_UserClose)
            {
                MessageBox.Show("The user clicked the X button.");
            }
            base.OnClosing(e);
        }

        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SYSCOMMAND && ((int)m.WParam & 65520) == SC_CLOSE)
            {
                _UserClose = true;
            }
            base.WndProc(ref m);
            _UserClose = false;
        }
    }
}
[/code]

Filed under  //   .NET   C#   Desktop   VB   Visual Basic 6   Windows Forms  

Comments [0]