.Net 2.0 Cryptography Implementation – Scenario 1

I am playing with .Net2.0 Cryptography,  and want to Implement different scenarios. Let me start with this one and please comment if you know of a better solution.

Scenario 1: I want to setup a Public Key Interface, where Sender signs a Message using Senders Certificate and then Encrypts / Envelops it using Recipients Certificate and then Send the Encrypted Message.

Solution: I am writing a Sender WebApplication where on click of a Button, Recipients Certificate is downloaded from a WebService Store and then signed and encrypted and sent to the Webservice. The Webservice then saves the encrypted Message in the c:\temp folder.

I ll be using the new X509Certificate2 that ships with .Net2.0.

Step 1 : I created 2 Certificate one for Recipient and one for Sender using the makecert tool.

C:\Program Files\Microsoft Visual Studio 8\VC>makecert -n “CN=SmartCryptoGraphy

Recipient1″ -ss My

Succeeded


C:\Program Files\Microsoft Visual Studio 8\VC>makecert -n “CN=SmartCryptoGraphy

Signer1″ -ss My

Succeeded

for more details on the Certificate Creation Tool please refer to this link.
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sag_cmprocsimport.mspx?mfr=true

Step 2: Create a WebService with the implementation of 2 Methods:

[WebMethod]
public byte[] GetRecipientCertificateFromStore(string recipientName)
{
}

[WebMethod]
public bool SendMessage(string message)
{
}

 

GetRecipientCertificateFromStore will return Recipients Certificate from My store. Here is the Implementation.

	
	[WebMethod]
        public byte[] GetRecipientCertificateFromStore(string recipientName)
        {
            //Do the searching of Certificate and send it back
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
                       
            X509Certificate2Collection certColl =
                store.Certificates.Find(X509FindType.FindBySubjectName,
                recipientName, false);            
            if (certColl.Count == 0)
            {
                store.Close();
                return null;
            }   
            store.Close();
            return certColl[0].Export(X509ContentType.Cert);
        }


The code is self explanatory it instantiates a X509Store object pointing to StoreName.My where I have previously saved the Certificates. Then it searches the store by the recipientName using the store.Certificates.Find method, and when it finds the desired certificate, returns byte[] using the X509Certificate2.Export Method.


 


SendMessage will recive encrypted message and simply store it to c:\temp folder. Here is the implementation:


	[WebMethod]
        public bool SendMessage(string message)
        {
            Guid id = Guid.NewGuid();
            try
            {
                using (System.IO.StreamWriter sw = System.IO.File.CreateText(string.Format(@"C:\temp\message_{0}.txt",id.ToString())))
                {
                    sw.Write(message);
                }
            }
            catch
            {
                return false;
            }
	
            return true;
        }


The above code is self explanatory.

Step 3: Creating the Sender WebApplication

I chosen a WebApplication for Sender as in future Scenarios I want to implement SSL, RequestClientCertificate etc.
Now the WebService can be communicated via any client but in future scenarios I want to restrict that communication too and want to implement autorized clients access to the webservice using SSL and Certificates…

Anyways now its simple and the future scenarios will be more complicated….Now I created I WebPage with 2 TextBox and a Send Button.


<form id=”form1″ runat=”server”>
<div>
Recipient Name<br />
<asp:TextBox ID=”tbRecipientName” runat=”server”></asp:TextBox><br />
Enter Message<br />
<asp:TextBox ID=”tbMessage” runat=”server” Height=”88px” TextMode=”MultiLine”></asp:TextBox><br />
<asp:Button ID=”btnSend” runat=”server” OnClick=”btnSend_Click” Text=”Send” /><br />
<asp:Label ID=”lblReport” runat=”server”></asp:Label></div>
</form>

On Button Click the web application loads the Signers Certificate then contacts the previously created webservice and requests the Recipient Certificate……by the RecipientName entered in the textbox.



After getting both Certificates it signs the message entered in the textbox, and then encrypts and envelops it using the Recipients Certificate and then Sends to the WebService…..The source code looks like this. 

        protected void btnSend_Click(object sender, EventArgs e)
        {
            //Get Signer Certificate
            X509Certificate2 signerCertificate = GetSignerCert();
            if (signerCertificate == null)
                return;
            //Get Recipient Certificate
            GetRecipientCert();
            if (recipientCertificate == null)
            {
                lblReport.Text ="Recipient Certificate to use for this application could not be found.";
                return;
            }
            //Sign the Message
            Encoding unicode = Encoding.Unicode;
            byte[] msgBytes = unicode.GetBytes(tbMessage.Text);
            byte[] encodedSignedCms = SignMesage(msgBytes, signerCertificate);
            //Encrypt the Message
            //  Encrypt the encoded SignedCms message.
            byte[] encodedEnvelopedCms = EncryptMsg(encodedSignedCms,
                recipientCertificate);            
            //Send
            string encryptedMessage = Convert.ToBase64String(encodedEnvelopedCms);
            Send(encryptedMessage);
        }
        
        public X509Certificate2 GetSignerCert()
        {
            //  Open the My certificate store.
            X509Store storeMy = new X509Store(StoreName.My,
                StoreLocation.CurrentUser);
            storeMy.Open(OpenFlags.ReadOnly);
           
            X509Certificate2Collection certColl =
                storeMy.Certificates.Find(X509FindType.FindBySubjectName,
                signerName, false);           

            if (certColl.Count == 0)
            {
                lblReport.Text ="Signer Certificate to use for this application could not be found in the certificate store. Please check the SignerName in Web.config for signing the message.";
                storeMy.Close();
                return null;
            }
            storeMy.Close();
            return certColl[0];
        }

        X509Certificate2 recipientCertificate = null;
        public void GetRecipientCert()
        {
            SmartCryptoGraphyService service = new SmartCryptoGraphyService();            
            byte[] recipientCertificateByte = service.GetRecipientCertificateFromStore(tbRecipientName.Text);            
            X509Certificate2 cert = new X509Certificate2(recipientCertificateByte);
            recipientCertificate = cert;
        }        

        public byte[] SignMesage( Byte[] message, X509Certificate2 signerCert)
        {
            //  Place message in a ContentInfo object.
            //  This is required to build a SignedCms object.
            ContentInfo contentInfo = new ContentInfo(message);

            //  Instantiate SignedCms object with the ContentInfo above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            //  Has default Detached property value false, so message is
            //  included in the encoded SignedCms.
            SignedCms signedCms = new SignedCms(contentInfo);

            //  Formulate a CmsSigner object, which has all the needed
            //  characteristics of the signer.
            CmsSigner cmsSigner = new CmsSigner(signerCert);

            //  Sign the PKCS #7 message.
            signedCms.ComputeSignature(cmsSigner);
            //  Encode the PKCS #7 message.
            return signedCms.Encode();
        }

        public byte[] EncryptMsg(Byte[] message, X509Certificate2 recipientCert)
        {
            //  Place message in a ContentInfo object.
            //  This is required to build an EnvelopedCms object.
            ContentInfo contentInfo = new ContentInfo(message);

            //  Instantiate EnvelopedCms object with the ContentInfo
            //  above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            //  Has default ContentEncryptionAlgorithm property value
            //  RSA_DES_EDE3_CBC.
            EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);

            //  Formulate a CmsRecipient object that
            //  represents information about the recipient
            //  to encrypt the message for.
            CmsRecipient recip1 = new CmsRecipient(
                SubjectIdentifierType.IssuerAndSerialNumber,
                recipientCert);                      

            //  Encrypt the message for the recipient.
            envelopedCms.Encrypt(recip1);            

            //  The encoded EnvelopedCms message contains the encrypted
            //  message and the information about each recipient that
            //  the message was enveloped for.
            return envelopedCms.Encode();
        }

        private void Send(string message)
        {
            SmartCryptoGraphyService service = new SmartCryptoGraphyService();
            service.SendMessageCompleted +=new SendMessageCompletedEventHandler(service_SendMessageCompleted);
            service.SendMessageAsync(message);

        }

        void service_SendMessageCompleted(object sender, SendMessageCompletedEventArgs e)
        {
            if (e.Result)
            {
                lblReport.Text = "Message Sent Successfully";
            }
            else
            {
                lblReport.Text = "Message sending failed";
            }
        }
The above code is self explanatory but you can study a bit more about these
classes in MSDN.... ContentInfo, SignedCms, CmsSigner, EnvelopedCms, CmsRecipient.
Note the signedCms.ComputeSignature(cmsSigner); 
The CheckSignature(Boolean) method verifies the digital signatures on the signed CMS/PKCS #7 message and, optionally, validates the signers' certificates.

Also Note the signedCms.Encode(); The Encode method encodes the information in the object into a CMS/PKCS #7 message.

Also Note the envelopedCms.Encrypt(recip1);
The message is encrypted by using a message encryption key with a symmetric encryption algorithm such as triple DES.
The message encryption key is then encrypted with the public key of each recipient.

The application worked ok for me as a demonstration of example
and generated encrypted messages…here is an example message

MIID7gYJKoZIhvcNAQcDoIID3zCCA9sCAQAxgcQwgcECAQAwKj
AWMRQwEgYDVQQDEwtSb290IEFnZW5jeQIQtoMOH1HeyJNCKmxxp
3EJRTANBgkqhkiG9w0BAQEFAASBgCi5O+Oe/Wp2Ju/6RkpVRKl
HedkAS7Q0t0j5ht/SEBf5uXkqz2SH23or283msqM07nt52oh
FW/2bU42gpcU8JkU3YenMyC/GCatHdwk5QgsDMZ6jEmcKaQs
RXtux7UVWK6TXbYuDoUyQgH0XafTutWC3HGRw2hz/bva7CkFZZ+
EnMIIDDQYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAhBUF7do+aaAI
CCAuiCqzjjI0APbhwStHLw1NXw8sUyNCmPsDhT2KHsXtVNhxXVVhQnA
7A2c6c4H2s6n9X71TGx0UIK2b+Dy6kR4PzzkTROLUWCImp8tt9gh++mz
UUDjicCxUjBUpwUdyPmMw0eD2WV9ZIoJpg47KmoKqdezoj0WUHKzjXp
6n8Tnp6FWvKnP+AgiVPqagagOamPVRJ+Du/x5Kf8PbVTLixIdUOBXVb
G1cd1qROp+o7d9Gfb6G1NDQHLOzG74R0Hbn30ut9NOpXir7QI/ZL4who
2xAm7WAFLJKvS/jvRQCSJo+4iPEdrHCIl+f0Ls93URiZeJKvygleNMEw1
Aze0GAwF5ydHLcohMA2BlcUReCkKi8s7qXM9OMq2mqU8QSnc7c5/keoPiun
DXWj/yBJYWDbw7PXhIuD56Ai8rdDbAjd7EQp1HXVD14X+RLUvKAgLohzm7N2
G1jDXOgkB+IV6d50l+mVMJWHUwUS+g37I3iUfnUWpIzhHmzZK5NOEeFfnEtRo
/did1ufmSMOrblV5WVi18hQ/n5VdmSq4mXYratb4v97BBqmPoSqT45CY8e15FCm
BUF+SJ6I07ZGaHBIk0/Il/DEmezLDUlU7df9vCY/BfpQ27zcVL2twTaLD1Zf7KrB8
J+mBODXiV3x1s06AJ6ZPtWXk9jXWBhWKCcCNMr3S1WBJ4lFjwHvYR8dHCmbKkqmluEwe
2tRHRA8mbTI9G200JAJY/oWqgbpFVr2U1eCU73OQUaXYe4bI10nfByDxiDi4c4O+





I ll keep posting my learnings and implementation of different Scenarios.
Probably next would be Veryfying the Encrypted Message Dycrypting and then
looking at the original message from another application....

Recovery of Community Server / Asp.Net Membership Password

2 days back I installed Community Server 2.1 (SP2) with hosting provider webhost4life. They have a very handy Pre Installed Community Server Thing… Just 2 clicks and you get the Community Server Installed…All was going ok and I was very happy with this new hosting provider and about to test the emailsettings so I put the smtp details as provided by the hosting provider and then logged off. Pressed forgot password link and wanted to test whether the forgot password email sending option is working with the admin account….. The email never came and I wanted to log back again to find out what is wrong—but soon realised for some reason the admin account got locked and I cannot log in any more……………

Go figure the forgot password link is not working and I cannot login as the only admin account I have. Also Client is going to demo the forum site Saturday Morning……..

I rushed and lodged my first ever service ticket with this new hosting provider (webhost4life)……..

which was something like this:

My Admin account for CommunityServer has got locked for some reason.
I need to work on this…asap…..Please help a quick help will be very very appreciated….

I Keept my fingers crossed and was waiting for the reply…..I was already running behind schedule and now this mess…..Finally after 1 hour of waiting a reply came…. and I was very surprised to see the reply…..

( Staff )
2/21/2007 10:31:28 PM
There is service charge $19.95 to reset your password in you database, please let us know if you want to proceed, thanks!

I told myself “blood hell” just for resetting the password I am not going to pay USD 19.95……..and they are asking for money on my first ever service ticket…. I bought their service, they looked good and reasonable to me…..never realised hidden cost for support…. not sure what they are going to charge if in future I go and ask for anything else.

I then replied asking if they can fix the email settings so that the forgot password link starts working and get my password… I was more surprised when the second reply came after 21 hours of waiting saying more or less they can’t do anything and advised me to look at the changing the password in db directly. 

I was simply bursting on anger realising the level of service that I am getting from them……I believe they have all the steps documented on how to reset the password and they did not want to share that with me and did not help me at all…..

Anyways I decided not to pay them and I am going to stick on my decision ……..

And after spending just 15 minutes on this problem I resetted the password successfully.

1. Connect to the CommunityServer Database

2. Two tables you should be interested in [aspnet_Membership] and [aspnet_Users]

3. Run this SQL in [aspnet_Users]
select * from aspnet_Users
find the UserID for the username you are looking for

4. Run this SQL in [aspnet_MemberShip]
select * from [aspnet_MemberShip] where UserID= ‘TheUseridYouFoundOnYourLastQuery’

5a. This first should be the easiest and this method worked on my local machine but did not work on the production server….
Simply browse
http://yourdomain.com/user/ChangePassword.aspx?UserName=TheUserNameYouAreLookingFor&Token=F186A349-B10B-44E3-B0FE-8A7E0312825E
here the last guid is what I found in the UserID field.

Then the ChangePassword will popup and you can reset your password its that easy….

5b. When the first method did not work I went for this second method…..
I chosen a User of whom I know the password then I queried for the Password and PasswordSalt data from the aspnet_Membership table for that user and replaced it with my admin account.

To do this I ran the following Update statement

update [dbo].[aspnet_Membership]
set failedpasswordattemptcount = 0,
password =’mi81BiiXFeBYGgA5uW_This password I got from a different UserID’,
passwordsalt=’D7AzdbILB7LGGBmBQn_This one also I got from that different UserID’,
passwordformat=1
where userid = ‘The UserID that you want to Update’

Walla all good now …. I logged in as admin again and the first thing I did is created a second admin account so if for some reason this first one do not work I have a backup admin account…..

Good Luck on recovering your AspNet Membership password

List of RPC Ping for Blog

source: http://blog.davestechshop.net/

Matt Ridings has a nice list of blog ping services he calls, “Ultimate List of RPC Ping Services For Your Blog“. Use this list to get the word out that you have posted something new on your blog.
Here is the list. All credit goes to Matt, and I’m sure he would appreciate a comment on his blog if you find this list useful. I’m simply passing along his good work.
As Matt says, “Check to see if your blogging tool or software requires a separator (such as a semicolon, comma, etc.) between each item, and if so be sure to add it before pasting into your tool.  For example, Community Server requires a semicolon after each URL.”
http://1470.net/api/ping
http://www.a2b.cc/setloc/bp.a2b
http://api.feedster.com/ping
http://api.moreover.com/RPC2
http://api.moreover.com/ping
http://api.my.yahoo.com/RPC2
http://api.my.yahoo.com/rss/ping
http://www.bitacoles.net/ping.php
http://bitacoras.net/ping
http://blogdb.jp/xmlrpc
http://www.blogdigger.com/RPC2
http://blogmatcher.com/u.php
http://www.blogoole.com/ping/
http://www.blogoon.net/ping/
http://www.blogpeople.net/servlet/weblogUpdates
http://www.blogroots.com/tb_populi.blog?id=1
http://www.blogshares.com/rpc.php
http://www.blogsnow.com/ping
http://www.blogstreet.com/xrbin/xmlrpc.cgi
http://blog.goo.ne.jp/XMLRPC
http://bulkfeeds.net/rpc
http://coreblog.org/ping/
http://www.lasermemory.com/lsrpc/
http://mod-pubsub.org/kn_apps/blogchatt
http://www.mod-pubsub.org/kn_apps/blogchatter/ping.php
http://www.newsisfree.com/xmlrpctest.php
http://ping.amagle.com/
http://ping.bitacoras.com
http://ping.blo.gs/
http://ping.bloggers.jp/rpc/
http://ping.blogmura.jp/rpc/
http://ping.cocolog-nifty.com/xmlrpc
http://ping.exblog.jp/xmlrpc
http://ping.feedburner.com
http://ping.myblog.jp
http://ping.rootblog.com/rpc.php
http://ping.syndic8.com/xmlrpc.php
http://ping.weblogalot.com/rpc.php
http://ping.weblogs.se/
http://pingoat.com/goat/RPC2
http://www.popdex.com/addsite.php
http://rcs.datashed.net/RPC2/
http://rpc.blogbuzzmachine.com/RPC2
http://rpc.blogrolling.com/pinger/
http://rpc.icerocket.com:10080/
http://rpc.pingomatic.com/
http://rpc.technorati.com/rpc/ping
http://rpc.weblogs.com/RPC2
http://www.snipsnap.org/RPC2
http://trackback.bakeinu.jp/bakeping.php
http://topicexchange.com/RPC2
http://www.weblogues.com/RPC/
http://xping.pubsub.com/ping/
http://xmlrpc.blogg.de/

.Net Cryptography related Resources and Links

Here are some good Cryptography related resources.

Cryptography Overview
http://msdn2.microsoft.com/en-us/library/92f9ye3s.aspx

New and improved Security in the .Net Framework2.0
 http://msdn2.microsoft.com/en-us/library/aa480472.aspx the examples are very useful

Protect Private Data with the Cryptography Namespaces of the .NET Frameworkhttp://msdn.microsoft.com/msdnmag/issues/02/06/crypto/ should help you get an insight on .NET Cryptography essentials.

Walkthrough Creating a Cryptographic Application.
http://msdn2.microsoft.com/en-us/library/aa964697.aspx

Cryptographic Services
http://msdn2.microsoft.com/en-us/library/93bskf9z.aspx

Cryptographic Tasks

http://msdn2.microsoft.com/en-us/library/7yx4d854.aspx

Encrypting and Decrypting Data

Describes how to generate and manage keys and how to encrypt and decrypt data.

Cryptographic Signatures

Describes how to generate and verify cryptographic signatures.

Ensuring Data Integrity with Hash Codes

Describes how to generate and verify hash codes.

Creating a Cryptographic Scheme

Describes how to help create a cryptographic scheme from the various cryptographic primitives.

Extending the KeyedHashAlgorithm Class

Describes how to extend the .NET Framework cryptographic classes by creating a keyed hash algorithm class that implements the MD5 hash algorithm.

XML Encryption and Digital Signatures

Provides links to reference and task-based documentation for XML encryption and digital signatures.

How to: Use Data Protection

Describes how to use the managed data protection API (DPAPI) to encrypt and decrypt data.

How to: Access Hardware Encryption Devices

Describes how to use hardware encryption devices with the .NET Framework.

XML Encryption and Digital Signatures
http://msdn2.microsoft.com/en-us/library/ms229749.aspx

How to: Encrypt XML Elements with Symmetric Keys

Describes how to encrypt an XML element using the Rijndael algorithm.

How to: Decrypt XML Elements with Symmetric Keys

Describes how to decrypt an XML element that was encrypted using the Rijndael algorithm.

How to: Encrypt XML Elements with Asymmetric Keys

Describes how to encrypt an XML element using the RSA algorithm.

How to: Decrypt XML Elements with Asymmetric Keys

Describes how to decrypt an XML element using the RSA algorithm.

How to: Encrypt XML Elements with X.509 Certificates

Describes how to encrypt an XML element using an X.509 certificate from a certificate store.

How to: Decrypt XML Elements with X.509 Certificates

Describes how to decrypt an XML element using an X.509 certificate from a certificate store.

How to: Sign XML Documents with Digital Signatures

Describes how to sign an XML document using the RSA algorithm.

How to: Verify the Digital Signatures of XML Documents

Describes how to verify an XML document using the RSA algorithm.

About System.Security.Cryptography.Pkcs
http://msdn2.microsoft.com/en-us/library/ms180945.aspx


Using System.Security.Cryptography.Pkcs
http://msdn2.microsoft.com/en-us/library/ms180955.aspx

 

How to: Sign Messages by One Signer

Creates a CMS/PKCS #7 signed message. The message is signed by a single signer.

How to: Sign a Message by Multiple Signers

Creates a CMS/PKCS #7 signed message. The message is signed by multiple signers.

How to: Countersign a Message

Creates a CMS/PKCS #7 signed message. The message is signed by a single signer. That signature is then countersigned by two other signers.

How to: Envelope a Message for One Recipient

Creates a CMS/PKCS #7 enveloped message. The message is encrypted for a single recipient.

How to: Envelope a Message for Multiple Recipients

Creates a CMS/PKCS #7 enveloped message. The message is encrypted for multiple recipients.

How to: Sign and Envelop a Message

Creates a CMS/PKCS #7 enveloped signed message. The message is first signed by a single signer and is then encrypted for a single recipient.

Supporting Tasks for Using System.Security.Cryptography.Pkcs

Contains additional programming tasks.

 

SmartCodeGenerator CTP2.6 Uploaded and 2 articles at Code Project

SmartCodeGenerator fans the CTP 2.6.0 has been uploaded to CodePlex. This latest version remembers the entered values on the custom properties and does not require you to retype the property values repeatedly everytime you run the application. I hope this will make codegeneration and debugging experience more simpler.

Also Uploaded 2 Articles at Code Project, but still in the Unedited Section. Hope Code Project will move them to the right section soon.

This article demonstrates how to use SCG
SmartCodeGenerator: Code Generation experience with Visual Studio and Asp.Net – Usage Overview

And this article gives an overview of the architecture behind SCG
SmartCodeGenerator: Code Generation experience with Visual Studio and Asp.Net – Architectural Overview

If you like this project please contribute/donate 1 template for the community. If all of us atleast write 1 template this can give the community a huge resource to refer to.

Templates can be uploaded in the communiy site http://community.smartcodegenerator.com

using the downloads tab
http://community.smartcodegenerator.com/files/default.aspx

MSMQueuing from .Net for VB(legacy). Use ActiveXMessageFormatter

I was Queuing a Serialized object in MSMQ. But soon realized that VB (legacy) do not like the format.

        public  void QueueJob(Job job, string destinationQueue, string messageLabel)
        {
            try
            {
                // open the queue
                MessageQueue mq = new MessageQueue(destinationQueue);
                // set the message to durable.
                mq.DefaultPropertiesToSend.Recoverable = true;
                // send the job object
                mq.Send(job, messageLabel);
                mq.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
            
        }
 
The Queued Serialized Job Object was picked up by VB as "?????????????????"

For example when I queued a string= “Hello”

VB(Legacy) would pick up from the queue as “?????”

I did the opposite then to find out what is wrong:


I Queued from VB(legacy) “Hello”
I discovered via going through the Message.BodyStream of .Net that the stream is returning something like this: “H0\e0\l0\l0\o and was appending a “0\” in front of every character.

I soon realized that the default formatting of VB(legacy) and .Net Serialized object is not same…..

Soon discovered (after googling and from a link from my collegue) that Message should be Queued using ActiveXMessageFormatter for VB(legacy) to pick it correctly.
Here is the final code:

        public  void QueueJob(Job job, string destinationQueue, string messageLabel)

{
try
{
// open the queue
MessageQueue mq = new MessageQueue(destinationQueue);
// set the message to durable.
mq.DefaultPropertiesToSend.Recoverable = true;
// send the job object
mq.Formatter = new ActiveXMessageFormatter();
XmlSerializer xmlSer = new XmlSerializer(job.GetType());
StringWriter sWriter = new StringWriter();
// Serialize the job to xml.
xmlSer.Serialize(sWriter, job);
mq.Send(sWriter.ToString(), messageLabel);
mq.Close();
}
catch (Exception e)
{
throw e;
}

}
What I have done here is got the string of the the Job object using the StringWriter after serializing it. And specified the Formatter to be ActiveXMessageFormatter, and then Send the message as usual to the Queue.

Asp.Net Caching Resources and Links

Asp.Net Caching
http://msdn2.microsoft.com/en-us/library/xsbfdd8c.aspx

 

Asp.Net Caching Features
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspcachingfeatures.asp

 

Asp.Net Quickstart- Caching for performance
http://quickstarts.asp.net/QuickStartv20/aspnet/doc/caching/default.aspx


Video: How Do I Make use of Caching
http://www.asp.net/learn/videos/view.aspx?tabid=63&id=42


Video: How Do I make Greater use of Caching
http://www.asp.net/learn/videos/view.aspx?tabid=63&id=41

Articles
Implement Custom Cache Dependencies in ASP.NET 1.x
http://msdn.microsoft.com/msdnmag/issues/04/07/CuttingEdge/


Supporting Database Cache Dependencies in Asp.Net
http://msdn.microsoft.com/msdnmag/issues/03/04/WickedCode/default.aspx


Use Data Caching Techniques to Boost Performance and Ensure Synchronization
http://msdn.microsoft.com/msdnmag/issues/02/12/webfarms/default.aspx


Asp.Net Caching Techniques Best Practices
http://msdn2.microsoft.com/en-us/library/aa478965.aspx

 

Data Caching Techniques in Asp.Net 1.x and 2.0
http://www.daveandal.net/articles/aspnet-caching/html/ASPNET-Caching.htm

 

Tip/Trick: Implement “Donut Caching with the Asp.NET 2.0 Output Cache Substitution Feature
http://weblogs.asp.net/scottgu/archive/2006/11/28/tip-trick-implement-donut-caching-with-the-asp-net-2-0-output-cache-substitution-feature.aspx

 

Also look at Enterprise Library Caching Application Block.

Design Pattern for P/Invoke Dll from c#

http://www.pinvoke.net comes with handy C# /VB.Net signatures for invoking with core Win32 API.

for example if we search for MessageBox in http://www.pinvoke.net we get the following result:

C# Signature (Original):

[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern uint MessageBox(IntPtr hWnd, String text, String caption, uint type);

This is the bare minimum and we can use this straight way in our application but I always prefer to write a Wrapper around it. Which turns into something like this:

sealed class MessageBoxWrapper
{
  private MessageBoxWrapper(){}

  public static void MessageBox(int h, string message, string errorMessage, MessageBoxStyles style)
  {
    if (MessageBox(new IntPtr(h), message, errorMessage, (uint)style) < 1)
    {
      Int32 err = Marshal.GetLastWin32Error();
      throw new Win32Exception(err);
    }
  }
  [DllImport("user32.dll",CharSet=CharSet.Auto)]
  public static extern int MessageBox(IntPtr hWnd,String text,String caption, uint style);
}
enum MessageBoxStyles : uint
{
  MB_OK = 0x00000000,
  MB_OKCANCEL = 0x00000001,
  MB_YESNO = 0x00000004
}


Now you might be asking why a wrapper? There are couple of good reasons:
1. This avoids application logic to call externs directly.
2. The wrapper is also Sealed and has a private constructor so it prevents creation of instance of the wrapper by mistake.
3. Resusability of the Wrapper accross the application.
4. The hardcore api calls reside all inside the wrapper and developers using the wrapper do not need to know the nity gritty of the internals and can do .Net Style coding.
5. Use of enumerators and all magic numbers reside at a central location.
6. Opportunity to do Error Handling and also return Meaningful Errors.


And the following code show how to call the method:

static void Main(string[] args)
{
  MessageBoxWrapper.MessageBox(0,”Test”,”Error”,MessageBoxStyles.MB_YESNO); 
}


I believe, its a very good practice/pattern to throw a wrapper around any extern methods.