Archive for the “.NET” Category

If you install VS2005 and then ODP.Net you will probably get a strange error when you will try to use Oracle Explorer for the first time:

Package ‘Oracle Developer Tools for Visual Studio .NET’ has failed
to load properly ( GUID = {D601BB95-E404-4A8E-9F24-5C1A462426CE} ).
Please contact package vendor for assistance. Application restart is
recommended, due to possible environment corruption. Would you like to
disable loading this package in the future? You may use
‘devenv /resetskippkgs’ to re-enable package loading.
 

The problem is an assembly mismatch. As Christian Shay (principal product manager for ODP.net at Oracle) said in an announcement, there are 2 options to solve this issue:

1. My recommended solution:

Execute the following command from a command prompt:

gacutil /i <Oracle Home>\odp.net\bin\2.x\Oracle.DataAccess.dll

where is the Oracle Home directory where you installed ODT 2005. For example, on my machine is c:\oracle\product\10.2.0\client_1.

2. Reinstall:

Deinstall ODP.NET 1.x from your machine (if you’re not using it) and install ODP.NET 2.0 in the same Oracle Home.

Andrei
http://www.webxpert.ro

Comments 1 Comment »

This is intended to be a tutorial of how to use ASP.Net DataGrid for view, edit, insert and delete items from an XML file.
Many people probably would need to keep some small amount of data in XML files rather than in the database. Manipulating this data is very simple and it can be made with a DataGrid, and this is the scope of this article, to show you how.

The result must look like this one:

First of all we need the XML file

< ?xml version="1.0" standalone="yes"?>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <price>10.90</price>
    <year>1985</year>
    <style>1</style>
  </cd>
  <cd>
    <title>Flick Of The Switch</title>
    <artist>AC DC</artist>
    <country>Australia</country>
    <price>15.90</price>
    <year>1983</year>
    <style>2</style>
  </cd>
  <cd>
    <title>Gold</title>
    <artist>Nirvana</artist>
    <country>USA</country>
    <price>10.90</price>
    <year>1991</year>
    <style>4</style>
  </cd>
  <cd>
    <title>Kings of Metal</title>
    <artist>Manowar</artist>
    <country>USA</country>
    <price>17.90</price>
    <year>1988</year>
    <style>3</style>
  </cd>
  <cd>
    <title>Rocka Rolla</title>
    <artist>Judas Priest</artist>
    <country>England</country>
    <price>16.90</price>
    <year>1974</year>
    <style>3</style>
  </cd>
</catalog>

We saved this file in the application root as source.xml

Then we will create a new webform page named xmlDataGrid.aspx, and add a DataGrid control, a Button and set tht title, exactly like in the above screenshot.
AutoGenerateColumns must set to false and must add the following columns in the DataGrid:
– Title binded to TITLE DataField
– Artist binded to ARTIST DataField
– Country binded to COUNTRY DataField
– Price binded to PRICE DataField
– Year binded to YEAR DataField
– Style binded to STYLE DataField
– Button column for “Edit, Update, Cancel”
– Button column for “Delete”

The code for the aspx page is the following:

<html>
<head>
</head>
<body>
    <form runat="server">
        <p align="center">
            <font face="Tahoma"><strong>DataGrid &amp; XML DataSource Example</strong></font>
           

           

            <asp :Button id="btnAdd" onclick="btnAdd_Click" runat="server" Text="Add new row"></asp>
           

            <asp :DataGrid id="dgCatalog" runat="server" AlternatingItemStyle-BackColor="#EEEEEE" ItemStyle-BackColor="#FFFFCC" HorizontalAlign="Center" Font-Size="10px" Font-Name="Tahoma" CellPadding="3" Font-Names="Tahoma" AutoGenerateColumns="False" OnCancelCommand="dgCatalog_CancelCommand" OnDeleteCommand="dgCatalog_DeleteCommand" OnEditCommand="dgCatalog_EditCommand" OnUpdateCommand="dgCatalog_UpdateCommand" Width="550px">
                <alternatingitemstyle backcolor="#EEEEEE"></alternatingitemstyle>
                <itemstyle backcolor="#FFFFCC"></itemstyle>
                <headerstyle backcolor="Aqua" font-italic="False" font-strikeout="False" font-underline="False" font-overline="False" font-bold="True"></headerstyle>
                <columns>
                    <asp :BoundColumn DataField="TITLE" HeaderText="Title"></asp>
                    <asp :BoundColumn DataField="ARTIST" HeaderText="Artist"></asp>
                    <asp :BoundColumn DataField="COUNTRY" HeaderText="Country"></asp>
                    <asp :BoundColumn DataField="PRICE" HeaderText="Price"></asp>
                    <asp :BoundColumn DataField="YEAR" HeaderText="Year"></asp>
                    <asp :BoundColumn DataField="STYLE" HeaderText="Style"></asp>
                    <asp :EditCommandColumn CancelText="Cancel" UpdateText="Update" EditText="Edit"></asp>
                    <asp :ButtonColumn CommandName="Delete" Text="Delete"></asp>
                </columns>
            </asp>
        </p>
        <p align="center">
            <font face="Tahoma" size="1">©2005 Andrei DANEASA – <a href="http://www.webxpert.ro">http://www.webxpert.ro</a></font>
        </p>
    </form>
</body>
</html>

In order to add some functionality to the DataGrid, first of all we need to load the data to the grid.
In the Page_Load event, we wil fill the dataset with XML data and then bind the DataGrid to this dataset:

//the dataset that will keep the data
System.Data.DataSet myDataSet = new System.Data.DataSet();

void Page_Load(object sender, EventArgs e) {
    FillData();
    if (!Page.IsPostBack) {
        dgCatalog.DataBind();
    }
}

//populate the dataset from XML
void FillData() {
    //read the XML into the DataSet
    myDataSet.ReadXml(Server.MapPath("source.xml"));
    //set the grid’s DataSource to DataSet
    dgCatalog.DataSource = myDataSet;
}

Now the DataGrid will display the data like in the above screenshot. We need to add functionalities for Edit, Delete and Update events.
Before writing these events, we must write the function that will save the dataset back to disk as XML file.

//write XML back to disk
void SaveData() {
    myDataSet.WriteXml(Server.MapPath("source.xml"));
}

The simplest events are Edit and Delete:

//event occurs when Edit link is clicked
void dgCatalog_EditCommand(object sender, DataGridCommandEventArgs e) {
    //turn the selected Item in Edit mode
    dgCatalog.EditItemIndex = e.Item.ItemIndex;
    dgCatalog.DataBind();
}

//event occurs when Delete link is clicked
void dgCatalog_DeleteCommand(object sender, DataGridCommandEventArgs e) {
    //delete from DataSet
    myDataSet.Tables[0].Rows[e.Item.ItemIndex].Delete();
    //Write the changes to disk
    SaveData();
    //rebind the data
    dgCatalog.DataBind();
    dgCatalog.EditItemIndex = -1;
    dgCatalog.DataBind();
}

A little complicated is Cancel event. Because we have a button that adds a new row to the dataset and change the text for Update link to “Insert”, we must assure that on Cancel event the text for the link is set back to “Update”.

//event occurs when Cancel link is clicked
void dgCatalog_CancelCommand(object sender, DataGridCommandEventArgs e) {
    //put the link title back to "Update"
    EditCommandColumn ecc = (EditCommandColumn) dgCatalog.Columns[6];
    ecc.UpdateText = "Update";

    //reset the selection
    dgCatalog.EditItemIndex = -1;
    dgCatalog.DataBind();
}

The “Add new row” button adds non-default functionality to the DataGrid control. A simple DataGrid does not have an event for Add or Insert. We used a trick to do this by adding a blank row to the dataset and then turn that row into edit mode and change the text for Update link to “Insert”.

//event occurs when "Add new row" button is pressed
void btnAdd_Click(object sender, EventArgs e) {
    //add an extra row to the dataSet
    InsertEmpty();
    //the new row is the last one in the dataset
    dgCatalog.EditItemIndex = myDataSet.Tables[0].Rows.Count-1;

    //change the update button title to "Insert"
    EditCommandColumn ecc = (EditCommandColumn) dgCatalog.Columns[6];
    ecc.UpdateText = "Insert";

    //rebind
    dgCatalog.DataBind();
}

//procedure that add an empty row to the DataSet
private void InsertEmpty() {
    //insert a new row at the end of the dataSet
    myDataSet.Tables[0].Rows.InsertAt(myDataSet.Tables[0].NewRow(), myDataSet.Tables[0].Rows.Count);
}

We missed one single event: Update. Here’s the code (it’s a little complicated due to the duble functionality: Update and Insert:

//event occurs when Update or Insert link is clicked
void dgCatalog_UpdateCommand(object sender, DataGridCommandEventArgs e) {
    System.Data.DataRow dr;
    //we must use the catch to identify a wrong index
    try {
        //if this event is called from Update
        dr = myDataSet.Tables[0].Rows[e.Item.ItemIndex];
    }
    catch {
        //if the event is called from Insert
        myDataSet.Tables[0].Rows.InsertAt( myDataSet.Tables[0].NewRow(), myDataSet.Tables[0].Rows.Count);
        dr = myDataSet.Tables[0].Rows[e.Item.ItemIndex];
    }

    //pupulate the dataRow cells with the supplied values
    dr[0] = ((TextBox) (e.Item.Cells[0].Controls[0])).Text;
    dr[1] = ((TextBox) (e.Item.Cells[1].Controls[0])).Text;
    dr[2] = ((TextBox) (e.Item.Cells[2].Controls[0])).Text;
    dr[3] = ((TextBox) (e.Item.Cells[3].Controls[0])).Text;
    dr[4] = ((TextBox) (e.Item.Cells[4].Controls[0])).Text;
    dr[5] = ((TextBox) (e.Item.Cells[5].Controls[0])).Text;
    //save dataset
    SaveData();

    //put the link title back to "Update"
    EditCommandColumn ecc = (EditCommandColumn) dgCatalog.Columns[6];
    ecc.UpdateText = "Update";

    //rebind
    dgCatalog.DataBind();
    dgCatalog.EditItemIndex = -1;
    dgCatalog.DataBind();
}

You can download the sources here
* All this article was written using only Freeware applications: ASP.NET Web Matrix for writing and testing the page, Notepad++ for writing the XML file, Gimp for screenshots.

Comments 5 Comments »

#develop (short for SharpDevelop) is a free IDE for C# and VB.NET projects on Microsoft’s .NET platform. It is open-source (GPL), and you can download both sourcecode and executables from this site.

This new version ( 1.1.0.1964 May Beta Refresh, 5/19/2005) has the following features:

  • Command window addin
  • #report localized
  • Help 2.0 improvements
  • Editor fixes (selection issues, freezing)
  • Web References now async
  • Updated Mono support

Executables are available here:
http://www.sharpdevelop.com/OpenSource/SD/Download/


Andrei
http://www.webxpert.ro

Comments No Comments »

Encryption in .NET Framework is a little tricky… not just create an object and call Encrypt and Decrypt methods, but terms like CryptoServiceProvider, CipherMode, IV and so on…Most of the examples that i found on the internet treats file encryption instead of text encryption (which i’m interested in).
These days i found a very useful article about text encryption written by Chidi C. Ezeukwu. Based on it i wrote a class for encryption/decryption with RC2 algorythm. This class can be used stand-alone in the application or as an assembly.

An archive that contains the VS.NET project for the assembly is available here: .NET rc2 Encryption assembly project
The compiled DLL assembly zipped is available here: .NET rc2 Encryption DLL assembly

The class code is the following:

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace webxpert
        {
                public class wx_crypt
                {
                        #region Variables
                        private string mKey = string.Empty;
                        private string mSalt = string.Empty;
                        private SymmetricAlgorithm mCryptoService;
                        #endregion

                        #region Properties
                        public string Key
                        {
                                get
                                {
                                        return mKey;
                                }
                                set
                                {
                                        mKey = value;
                                }
                        }

                        public string Salt
                        {
                                // Salt value
                                get
                                {
                                        return mSalt;
                                }
                                set
                                {
                                        mSalt = value;
                                }
                        }

                        #endregion

                        #region Constructor
                        public wx_crypt()
                        {
                                mCryptoService = new RC2CryptoServiceProvider();
                                mCryptoService.IV = new byte[] {0xf, 0x6f, 0x13, 0x2e, 0x35, 0xc2, 0xcd, 0xf9};
                                mCryptoService.Mode = CipherMode.CBC;
                        }

                        #endregion

                        #region Methods
                        public virtual byte[] GetLegalKey()
                        {
                                // Adjust key if necessary, and return a valid key
                                if (mCryptoService.LegalKeySizes.Length > 0)
                                {
                                        // Key sizes in bits
                                        int keySize = mKey.Length * 8;
                                        int minSize = mCryptoService.LegalKeySizes[0].MinSize;
                                        int maxSize = mCryptoService.LegalKeySizes[0].MaxSize;
                                        int skipSize = mCryptoService.LegalKeySizes[0].SkipSize;
                               
                                        if (keySize > maxSize)
                                        {
                                                // Extract maximum size allowed
                                                mKey = mKey.Substring(0, maxSize / 8);
                                        }
                                        else if (keySize < maxSize)
                                        {
                                                // Set valid size
                                                int validSize = (keySize <= minSize)? minSize : (keySize – keySize % skipSize) + skipSize;
                                                if (keySize < validSize)
                                                {
                                                        // Pad the key with asterisk to make up the size
                                                        mKey = mKey.PadRight(validSize / 8, ‘*’);
                                                }
                                        }
                                }
                                PasswordDeriveBytes key = new PasswordDeriveBytes(mKey, ASCIIEncoding.ASCII.GetBytes(mSalt));
                                return key.GetBytes(mKey.Length);
                        }

                        public virtual string Encrypt(string plainText)
                        {
                                byte[] plainByte = ASCIIEncoding.ASCII.GetBytes(plainText);
                                byte[] keyByte = GetLegalKey();

                                // Set private key
                                mCryptoService.Key = keyByte;
                               
                                // Encryptor object
                                ICryptoTransform cryptoTransform = mCryptoService.CreateEncryptor();
                       
                                // Memory stream object
                                MemoryStream ms = new MemoryStream();

                                // Crpto stream object
                                CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write);

                                // Write encrypted byte to memory stream
                                cs.Write(plainByte, 0, plainByte.Length);
                                cs.FlushFinalBlock();

                                // Get the encrypted byte length
                                byte[] cryptoByte = ms.ToArray();

                                // Convert into base 64 to enable result to be used in Xml
                                return Convert.ToBase64String(cryptoByte, 0, cryptoByte.GetLength(0));
                        }
               
                        public virtual string Decrypt(string cryptoText)
                        {
                                // Convert from base 64 string to bytes
                                byte[] cryptoByte = Convert.FromBase64String(cryptoText);
                                byte[] keyByte = GetLegalKey();

                                // Set private key
                                mCryptoService.Key = keyByte;
                               
                                // Decryptor object
                                ICryptoTransform cryptoTransform = mCryptoService.CreateDecryptor();
                                try
                                {
                                        // Memory stream object
                                        MemoryStream ms = new MemoryStream(cryptoByte, 0, cryptoByte.Length);

                                        // Crpto stream object
                                        CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read);

                                        // Get the result from the Crypto stream
                                        StreamReader sr = new StreamReader(cs);
                                        return sr.ReadToEnd();
                                }
                                catch
                                {
                                        return null;
                                }
                        }

                        #endregion
                }
        }


Andrei
http://www.webxpert.ro

Comments No Comments »