XML documents can reference optional documents that specify how the XML documents should be structured. These optional documents called Documents Type Definitions (DTDs) and Schemas.
There are two kinds of definition for schemas currently:
1. Microsoft XML Schema It uses the extension .xdr (XML-Data Reduced) you can check the attached files for the this Schema syntax, it is an xml document, but has special elements and attributes.
2. W3C XML Schema It uses the extension .xsd (XML Schema Definitions) also it is an XML Document with special elements.
The second approach, XSD Schema, has been
supported by Microsoft .NET Framework and is the best approach for .NET
developers. Schema files are a special kind of XML file that define the
structure of an XML file via some pre-defined elements and attributes.
Using this Schema file you can validate your XML file to
make sure it fits to your application's needs and validate the inputs in order to prevent any exception in your
code. The .Net framework gives you all the tools you need so that you can build XSD schemas and also validate them. First, let's see how can we create a schema using XSD.exe file (It comes with Visual Studio): The
XML Schema Definition tool generates XML schema or common language
runtime classes from XDR, XML, and XSD files, or from classes in a
runtime assembly. The following command generates an XML schema from myFile.xml and saves it to the specified directory xsd myFile.xml /outputdir:myOutputDir Consider that we have the following xml data file EmployeeList.xml: <EmployeeList> <Company ID="1"> <Employee>Employee11Employee> <Employee>Employee12Employee> <Employee>Employee13Employee> Company> <Company ID="2"> <Employee>Employee21Employee> <Employee>Employee22Employee> <Employee>Employee23Employee> Company> <Company ID="3"> <Employee>Employee31Employee> <Employee>Employee32Employee> <Employee>Employee33Employee> <Employee>Employee34Employee> Company> EmployeeList>
Now, execute XSD.exe on the xml data file: > XSD EmployeeList.xmlThe result xsd file EmployeeList.xsd will be : xml version="1.0" encoding="utf-8"? ><xs:schema id="EmployeeList" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="EmployeeList" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Company"> <xs:complexType> <xs:sequence> <xs:element name="Employee" nillable="true" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:simpleContent msdata:ColumnName="Employee_Text" msdata:Ordinal="0"> <xs:extension base="xs:string"> xs:extension> xs:simpleContent> xs:complexType> xs:element> xs:sequence> <xs:attribute name="ID" type="xs:string" /> xs:complexType> xs:element> xs:choice> xs:complexType> xs:element>xs:schema>
Second, now that we have our Schema let's see the steps that we need to do in order to validate against our schema (.NET 2.0): 1.
Read the XML file content as Stream, TextReader or XmlReader. 2.
Read the Schema file content as Stream, TextReader or XmlReader. 3.
Create a new instance of XmlSchema object. 4.
Set XmlSchema object by calling XmlSchema.Read() method and passing the
content of Schema file and ValidationEventHandler method address to it. 5.
Create a new instance of XmlReaderSettings object. 6.
Set ValidationType for XmlReaderSettings object to Schema. 7.
Add your XmlSchema object to XmlReaderSettings Schemas collection by
calling its Schemas.Add() method. 8.
Add your ValidationEventHandler method address to XmlValidationReader's
ValidationEventHandler handler. 9.
Create a new instance of XmlReader object and pass your XML file content
(as Stream or a Reader object) and XmlReaderSettings object to it. 10. Call
Read() method of the Reader or Stream object to contain your XML file content
in a loop to parse and validate it completely. 11. Add
your logic to ValidationEventHandler method you created to implement what you
want to be done in the validation process.
Here is the code to accomplish this: private void ValidatingProcess(string XSDPath, string XMLPath) { try { // 1- Read XML file content this.Reader = new XmlTextReader(XMLPath); // 2- Read Schema file content StreamReader SR = new StreamReader(XSDPath); // 3- Create a new instance of XmlSchema object XmlSchema Schema = new XmlSchema(); // 4- Set Schema object by calling XmlSchema.Read() method Schema = XmlSchema.Read(SR, new ValidationEventHandler(ReaderSettings_ValidationEventHandler)); // 5- Create a new instance of XmlReaderSettings object XmlReaderSettings ReaderSettings = new XmlReaderSettings(); // 6- Set ValidationType for XmlReaderSettings object ReaderSettings.ValidationType = ValidationType.Schema; // 7- Add Schema to XmlReaderSettings Schemas collection ReaderSettings.Schemas.Add(Schema); // 8- Add your ValidationEventHandler address to // XmlReaderSettings ValidationEventHandler ReaderSettings.ValidationEventHandler += new ValidationEventHandler(ReaderSettings_ValidationEventHandler); // 9- Create a new instance of XmlReader object XmlReader objXmlReader = XmlReader.Create(Reader, ReaderSettings); // 10- Read XML content in a loop while (objXmlReader.Read()) { /*Empty loop*/} }//try // Handle exceptions if you want catch (UnauthorizedAccessException AccessEx) { throw AccessEx; }//catch catch (Exception Ex) { throw Ex; }//catch } private void ReaderSettings_ValidationEventHandler(object sender, ValidationEventArgs args) { // 11- Implement your logic for each validation iteration string strTemp; strTemp = "Line: " + this.Reader.LineNumber + " - Position: " + this.Reader.LinePosition + " - " + args.Message; this.Results.Add(strTemp); }
Don't use your web methods to return strings as most programmers do, use them to return true XMLs.
instead of using this:
[WebMethod]
public string MyLameWebMethod()
{
XmlDocument dom = new XmlDocument();
// load XML Data ...
return dom.OuterXml;
}
Now when we want to read it on the client side we want the XML and then the operation is:
XML -> String -> XML
Use this:
[WebMethod]
public XmlDocument MyBetterWebMethod()
{
XmlDocument dom = new XmlDocument();
// load some XML ...
return dom;
}
Here we are skipping over the String step and using much more valid XML document.
Now you are avoiding an added level of transferring your XML document to string and then back to XML.
This article discusses the delegate type and how it can be used to point to methods in the application which can be invoked at later time. This article demonstrates also the delegate ability to multicast and delegate covariance.
A delegate is a type-safe object that can point to another method (or possibly multiple methods) in the application, which can be invoked at later time.
Delegates also can invoke methods Asynchronously.
A delegate type maintains three important pices of information :
- The name of the method on which it make calls.
- Any argument (if any) of this method.
- The return value (if any) of this method.
Defining a Delegate in C#
when you want to create a delegate in C# you make use of delegate keyword.
The name of your delegate can be whatever you desire. However, you must define the delegate to match the signature of the method it will point to. fo example the following delegate can point to any method taking two integers and returning an integer.
public delegate int DelegateName(int x, int y);
A Delegate Usage Example
namespace MyFirstDelegate
{
//This delegate can point to any method,
//taking two integers and returning an
//integer.
public delegate int MyDelegate(int x, int y);
//This class contains methods that MyDelegate will point to.
public class MyClass
{
public static int Add(int x, int y)
{
return x + y;
}
public static int Multiply(int x, int y)
{
return x * y;
}
}
class Program
{
static void Main(string[] args)
{
//Create an Instance of MyDelegate
//that points to MyClass.Add().
MyDelegate del1 = new MyDelegate(MyClass.Add);
//Invoke Add() method using the delegate.
int addResult = del1(5, 5);
Console.WriteLine("5 + 5 = {0}\n", addResult);
//Create an Instance of MyDelegate
//that points to MyClass.Multiply().
MyDelegate del2 = new MyDelegate(MyClass.Multiply);
//Invoke Multiply() method using the delegate.
int multiplyResult = del2(5, 5);
Console.WriteLine("5 X 5 = {0}", multiplyResult);
Console.ReadLine();
}
} }
Delegate ability to Multicast
Delegate ability to multicast mean that a delegate object can maintain a list of methods to call, rather than a single method if you want to add a method to the invocation list of a delegate object , you simply make use of the overloaded += operator, and if you want to remove a method from the invocation list you make use of the overloaded operator -= .
Note:Multicast delegate must contain only methods that return void, or you will get a run time exception.
A Multicast Delegate Example
namespace MyMulticastDelegate
{
//this delegate will be used to call more than one
//method at once
public delegate void MulticastDelegate(int x, int y);
//This class contains methods that MyDelegate will point to.
public class MyClass
{
public static void Add(int x, int y)
{
Console.WriteLine("You are in Add() Method");
Console.WriteLine("{0} + {1} = {2}\n", x, y, x + y);
}
public static void Multiply(int x, int y)
{
Console.WriteLine("You are in Multiply() Method");
Console.WriteLine("{0} X {1} = {2}", x, y, x * y);
}
}
class Program
{
static void Main(string[] args)
{
//Create an Instance of MulticastDelegate
//that points to MyClass.Add().
MulticastDelegate del = new MulticastDelegate(MyClass.Add);
//using the same instance of MulticastDelegate
//to call MyClass.Multibly() by adding it to it's
//invocation list.
del += new MulticastDelegate(MyClass.Multiply);
//Invoke Add() and Multiply() methods using the delegate.
//Note that these methods must have a void return vlue
Console.WriteLine("****calling Add() and Multibly() Methods.****\n\n");
del(5, 5);
//removing the Add() method from the invocation list
del -= new MulticastDelegate(MyClass.Add);
Console.WriteLine("\n\n****Add() Method removed.****\n\n");
//this will invoke the Multibly() method only.
del(5, 5);
}
}
}
Delegate Covariance
Assume you are designing a delegate that can point to methods returning a custom class type:
//Define a delegate pointing to methods returning Employee types.
public delegate Employee EmployeeDelegate();
if you were to derive a new class from Employee Type named SalesEmployee and wish to create a delegate type that can point to methods returning this class type you would be required to define an entirely new delegate to do so
//a new delegate pointing to methods returning SalesEmployee types.
public delegate SalesEmployee SalesEmployeeDelegate();
Example
namespace MyEmployeesDelegate
{
//Define a delegate pointing to methods returning Employee types.
public delegate Employee EmployeeDelegate();
//a new delegate pointing to methods returning SalesEmployee types.
public delegate SalesEmployee SalesEmployeeDelegate();
class Program
{
public static Employee GetEmployee()
{
return new Employee();
}
public static SalesEmployee GetSalesEmployee()
{
return new SalesEmployee();
}
static void Main(string[] args)
{
EmployeeDelegate empDel = new EmployeeDelegate(GetEmployee);
Employee emp = empDel();
SalesEmployeeDelegate salesEmpDel = new SalesEmployeeDelegate(GetSalesEmployee);
SalesEmployee emp2 = salesEmpDel();
}
}
public class Employee
{
protected string firstName;
protected string lastName;
protected int Age;
public Employee()
{ }
public Employee(string fName, string lName, int age)
{
this.firstName = fName;
this.lastName = lName;
this.Age = age;
}
}
public class SalesEmployee : Employee
{
protected int salesNumber;
public SalesEmployee()
{ }
public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)
{
this.salesNumber = sNumber;
}
}
}
It would be ideal to build a single delegate type that can point to methods returning either Employee or SelesEmployee types. Covariance allows you to build a single delegate that can point to methods returning class types related by classical inheritance.
Delegate Covariance Example
namespace DelegateCovariance
{
//Define a single delegate that may return an Employee
// or SalesEmployee
public delegate Employee EmployeeDelegate();
class Program
{
public static Employee GetEmployee()
{
return new Employee();
}
public static SalesEmployee GetSalesEmployee()
{
return new SalesEmployee();
}
static void Main(string[] args)
{
EmployeeDelegate emp = new EmployeeDelegate(GetEmployee);
Employee emp1 = emp();
EmployeeDelegate empB = new EmployeeDelegate(GetSalesEmployee);
//to obtain a derived type you must perform an explicit cast.
SalesEmployee emp2 = (SalesEmployee)empB();
}
}
public class Employee
{
protected string firstName;
protected string lastName;
protected int Age;
public Employee()
{ }
public Employee(string fName, string lName, int age)
{
this.firstName = fName;
this.lastName = lName;
this.Age = age;
}
}
public class SalesEmployee : Employee
{
protected int salesNumber;
public SalesEmployee()
{ }
public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)
{
this.salesNumber = sNumber;
}
}
}
I hope you are now have a good idea with the creation and usage of delegates types.
This article explains how you can extract all Tables, including Data, to an Excel file. Every Table will have it's own worksheet. The code does need an excel application installed on the server, while it's using Office Interop.
To get this code to work, you need to add a reference to Excel.dll by using Add Reference on the project and selecting Microsoft Excel 9.0 (or 10.0) Object Library from the COM tab on the Add Reference dialog.
And then import the following namespace:
Imports System.Runtime.InteropServices.Marshal
Now add the following class to your project:
Private Sub create(ByVal sDatabaseName As String) Dim dsTables As DataSet = New DataSet
'Get all Tables from database dsTables = getAllTables(sDatabaseName) 'Create Excel Application, Workbook, and WorkSheets Dim xlExcel As New Excel.Application Dim xlBooks As Excel.Workbooks Dim xlBook As Excel.Workbook Dim tblSheet As Excel.Worksheet Dim xlCells As Excel.Range Dim sFile As String
'File name for the excel file sFile = Server.MapPath("~\Sheets\" & sDatabaseName & "_data.xls")
xlExcel.Visible = False : xlExcel.DisplayAlerts = False xlBooks = xlExcel.Workbooks xlBook = xlBooks.Add
For i As Integer = 0 To dsTables.Tables.Count - 1 tblSheet = xlBook.Worksheets.Add tblSheet.Name = dsTables.Tables(i).TableName xlCells = tblSheet.Cells 'Fill all cells with data GenerateExcelFile(dsTables.Tables(i), xlCells) Next
'Remove initial excel sheets. Within a try catch because the database 'could be empty (a workbook without worksheets is not allowed) Try Dim SheetCount As Integer = xlExcel.Sheets.Count CType(xlExcel.Sheets(SheetCount - 0), Excel.Worksheet).Delete() CType(xlExcel.Sheets(SheetCount - 1), Excel.Worksheet).Delete() CType(xlExcel.Sheets(SheetCount - 2), Excel.Worksheet).Delete() Catch ex As Exception
End Try
'Save the excel file xlBook.SaveAs(sFile)
'Make sure all objects are disposed xlBook.Close() xlExcel.Quit() ReleaseComObject(xlCells) ReleaseComObject(tblSheet) ReleaseComObject(xlBook) ReleaseComObject(xlBooks) ReleaseComObject(xlExcel) xlExcel = Nothing xlBooks = Nothing xlBook = Nothing tblSheet = Nothing xlCells = Nothing 'Let the Garbage Collector know it can get to work GC.Collect()
'Export Excel for download Try HttpContext.Current.Response.ContentType = "application/octet-stream" HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + System.IO.Path.GetFileName(sFile)) HttpContext.Current.Response.Clear() HttpContext.Current.Response.WriteFile(sFile) HttpContext.Current.Response.End() Catch ex As Exception 'An exception will be thrown, but can just be ignored End Try
End Sub
To generate the individual sheets, the following Sub is used:
Private Sub GenerateExcelFile(ByRef table As DataTable, ByVal xlCells As Excel.Range) Dim dr As DataRow, ary() As Object Dim iRow As Integer, iCol As Integer
'Output Column Headers For iCol = 0 To table.Columns.Count - 1 xlCells(1, iCol + 1) = table.Columns(iCol).ToString xlCells(1).EntireRow.Font.Bold = True Next
'Output Data For iRow = 0 To table.Rows.Count - 1 dr = table.Rows.Item(iRow) ary = dr.ItemArray For iCol = 0 To UBound(ary) xlCells(iRow + 2, iCol + 1) = ary(iCol).ToString Response.Write(ary(iCol).ToString & vbTab) Next Next xlCells.Columns.AutoFit() End Sub
And now the trick to getting all tables and data from a database:
Public database as String
Public ReadOnly Property getAllTables(ByVal sDB As String) As DataSet Get database = sDB Dim m_dshelp As DataSet = New DataSet getRequestedAllTables(m_dshelp) Return m_dshelp End Get End Property
Private Function getRequestedAllTables(ByRef p_dataset As DataSet) As Boolean
'Retrieve all tablenames from the database: Dim sSQL As String Dim dsTables As DataSet = New DataSet sSQL = "SELECT [TableName] = so.name, [RowCount] = MAX(si.rows) " & _ "FROM sysobjects so, sysindexes si " & _ "WHERE so.xtype = 'U' AND si.id = OBJECT_ID(so.name) AND si.rows > 0 " & _ "GROUP BY so.name " & _ "ORDER BY 2 DESC"
getData(sSQL, "Tables", dsTables)
'Loop thrue all tables and do a SELECT *. Then add them to the dataset For i As Integer = 0 To dsTables.Tables(0).Rows.Count - 1 sSQL = "SELECT * FROM " & dsTables.Tables(0).Rows(i).Item(0) getData(sSQL, dsTables.Tables(0).Rows(i).Item(0), p_dataset) Next End Function
Private Function getData(ByVal p_sql As String, ByVal p_table As String, ByRef pdataset As DataSet) As Boolean
Dim objDataAdapter As SqlDataAdapter Dim objcommand As SqlCommand objcommand = New SqlCommand(p_sql, getConnection) objDataAdapter = New SqlDataAdapter(objcommand) objDataAdapter.Fill(pdataset, p_table) End Function
Private Function getConnection() As SqlConnection If (ConfigurationManager.AppSettings("SQLPW") <> "") Then getConnection = New SqlConnection("Server=" & _ ConfigurationManager.AppSettings("SQLserver") & ";password=" & _ ConfigurationManager.AppSettings("SQLPW") & "; user=" & _ ConfigurationManager.AppSettings("SQLUser") & ";database=" & database) Else getConnection = New SqlConnection("Data Source=" & _ ConfigurationManager.AppSettings("SQLserver") & ";Initial Catalog=" & _ database & ";Integrated Security=True") End If End Function
It was all going so smoothly. Jason Whittington, Mark Smith and I were teaching the big DevelopMentor event here in Los Angeles (Guerrilla.NET) when my presentation on the ThreadPool took a nose dive. It started with a great joke involving Wilson (the volleyball from Cast Away).
Wilson and I built an application to compute a multiplication table where each computation was (artificially) slow. To speed it up we threw it at the thread pool using delegate.BeginInvoke. We figured that the ThreadPool would allocate 25 or so threads and the table would display quickly. Here's the expected output - pretty much the same thing we've seen since about .NET 1.0:
Each color represents the thread that did that computation.
For the last 7 years, the behavior has been that as the ThreadPool was overloaded, it would steadily start up new threads at the rate of one every 500 milliseconds until it hits its upper limit (typically). Using Performance Monitor (perfmon) we can watch the thread pool adding threads. It usually looks something like this:
Much to our surprise we saw completely different behavior. The thread pool added the first 15 or so threads quickly (as expected) but then stalled. New threads were not created every 500ms, instead they were added at increasingly long intervals. My demo took almost twice as long to run as it had the last time I did this demo a few months ago.
Jason, Mark, and I took this code, ported it back to .NET 1.1 and ran it side-by-side with .NET 3.5 and here's what we saw (blue = 3.5, red = 1.1):
As of .NET 3.5 the upper limit of the ThreadPool was increased: Knew that.
But, it appears that v3.5 of the CLR changes the policy for adding threads to the thread pool. Rather than adding threads regularly when under load the thread pool uses a logarithmic backoff. My colleague Jason Whittington remarked that this behavior looked similar to the behavior of the thread pool in "Rotor" (the shared-source version of the CLR). We speculated that this backoff algorithm makes sense given the new 250-thread per CPU maximum - it would take a long time to reach that if the runtime waits longer and longer to start a new thread. The 250-thread limits makes it less likely that your application will deadlock the thread pool, and the exponential backoff algorithm keeps the thread pool from creating too many threads too quickly.
Why should you care? Usually you won't, but it could have dramatic impact if you count on that behavior. For example, in our contrived case, .NET 1.1 ran about twice as fast as .NET 3.5 ( ! ):
Here's the program and source code (trimmed down to run in both .NET 1.1 and 3.5).
Math.zip (6.38 KB)
Redesigning a website can be a very involved process, and it is important to properly plan and consider the necessary factors that will make or break the redesign. Here is a quick look at 21 factors that you should be contemplated.
1. What is the goal of the redesign?
What do you hope to accomplish? It’s always important to have a clear understanding of your reasons and motivations as they should impact the decisions that you make along the way. Without knowing these goals the project will lack direction and you will likely wind up with a website that still doesn’t meet your needs.
2. Is this going to be just a minor upgrade or a complete overhaul?
A redesign could be anything from a minor facelift to an entirely new site. Obviously the time, effort, and cost involved will vary, but first you should determine what types of changes are required for you to meet your goals with the design. If a complete redesign is done you will also want to consider to what extent the new design should resemble the old design. If visitors are coming back to the site, chances are you will want them to notice the new design without feeling like they’ve never been to your site before.
3. What aspects of the current design are most effective?
Most likely there are some things about the current design that work very well, and these may be aspects that you would like to keep or incorporate into the new design. It’s a good idea to make a simple list of your likes and dislikes to help with decisions on the new design.
4. What aspects of the current design are not effective?
Building on point #3, if you are redesigning the site you are bound to want to get rid of some specific aspects of the website or the design. Are there some characteristics of the design that do not accurately portray your business to new visitors?
5. Who are your target users?
During any design process you never want to lose focus on the visitors. By knowing who you are targeting and how you can meet their needs, you will be on your way to building an effective website. What style of design are your users going to like?
6. How can the website be more user-friendly?
Improving the functionality and usability of a website is always a good thing. It’s pointless to spend time and money on a redesign that looks great but simply isn’t user-friendly.
7. Does the logo/branding need to be changed or updated?
Most likely the website will include some form of a logo or branding. Are these items still up-to-date and will they function effectively with a new design? If your logo is out-of-date and not attractive, a new design may not do much good if it is still using the same old logo.
8. Should the color scheme change or remain the same?
In point #2 I mentioned that most of the time you will want to keep the website at least looking familiar to repeat visitors. Using a similar color scheme is one of the best ways to accomplish this. A lot of times it can be a good idea to make some minor changes to the color scheme, such as changing shades of colors or adding a few new colors, just to give the site a fresh look.
9. What screen resolutions are visitors using?
It’s important to know how your visitors are going to be viewing the site. A program such as Google Analytics can easily give you this information. Obviously, a fixed-width design should take into consideration the typical screen resolutions of visitors.
10. What connection speed are visitors using?
Knowing the connection speed will help you to know what types of elements you can include in the design without causing hardships for the average visitor.
11. What should be the focal points of the design?
Every design is going to draw attention to certain parts of the page in one way or another. By knowing what you want to emphasize you will have more control over what gets attention from visitors. In a comment on a recent article, Caroline Middlebrook mentioned that in her redesign she used the area above blog posts to feature some select content, such as a free e-book that she has written. Obviously, in her case this is a focal point that she wants visitors to notice.
12. How can the navigation be made more effective?
Navigation is one of the most critical elements of a site’s usability. If a significant amount of content and/or pages have been added to the site since the last design, it is possible that navigation is no longer optimal. Before designing think about how visitors will want to move through the site, and make it as easy as possible for them.
13. What will visitors want from the website?
Meeting the needs of visitors is important to the success of any website. Will visitors be coming to the site looking for information? If so, make it easy to find the information and make it a prominent part of the design. Will they be coming to the site to find products? Will they be coming for some other reason? Anticipate what your visitors will want and do your best to give it to them.
14. How can increased user interaction be incorporated?
The most successful websites are able to get visitors involved in one way or another. Blogs are great for this purpose because they allow for comments and discussion. Other possibilities are forums, games, user-generated content, polls, quizzes, etc. By making the website more engaging to visitors you are more likely to get a high number of repeat visitors.
15. Who will be doing the maintenance/updates?
Will you be the one doing routine maintenance and updates? Will someone else be doing them? If multiple people will be using the website commenting the code becomes even more important. Code should always be kept as clean as possible, but when others will be doing work on the site has a bigger impact.
16. Is a content management system (CMS) needed?
Many website owners now prefer to use a CMS, such as WordPress, so that the site can easily be updated without requiring a designer. Depending on the amount and type of updates that are anticipated, a CMS may be a good, time-saving decision.
17. How can SEO be improved?
Any time a website is being designed, search engines should be considered. The current design may or may not be search engine-friendly, but the new one certainly should be. Should the current page titles be kept, or could they be done more effectively? How can internal linking be improved? Where can headers be used? This list could obviously go on for a while.
18. What keywords and phrases are being targeted?
Of course, keywords should be used in titles, headers, anchor text, alt tags, etc. Designing a website without knowing what words and phrases you are targeting means that you are most likely targeting none, at least not effectively. Don’t simply consider the search terms that are being targeted with the current site, make sure that these are the most effective terms to go after.
19. What pages and search terms are currently drawing traffic?
If there are pages on the site that are currently doing very well with search engines, you’ll probably not want to make major changes to the content of those pages. This can easily be overlooked during a redesign, but making excessive changes to pages that are ranking well can kill the rankings. Likewise, what search terms are currently producing traffic? Be sure that they are used in the new design.
20. What pages currently have inbound links?
Whatever pages on the site have a significant number of inbound links or are drawing traffic through those links, you’ll want to make sure that any changes do not negatively affect these links. If possible, use the same URL structure. If not, be sure to re-direct visitors to the appropriate page.
21. What will make visitors want to come back?
Most likely you’ve considered how the new design can make a solid first impression, but what is it about the website that will keep visitors coming back for more?
If you are like me, you hate hand editing HTML and XML! But unfortunately, as a .NET Developer you often find yourself doing it, and if for no other reason, you have to do it for parts of the Web.Config and Application.Config files. Last night, I was googling for something, and just found this tool from ASPhere by luck. It's really easy, nice, and looks great :)
Here you are the URL : http://asphere.aspweb.cz/default.aspx
Under the category of "you learn something new every day": While watching dnrTV this morning, I saw something that I've never seen done in C# before.
I knew that it was possible to make an "alias" for a namespace in C#. For example, if you have a complex namespace like MadProps.Windows.Controls (a contrived example) that you don't want to add to your "using" list, but you don't want to have to retype every time, you can use code like this to "alias" it: using MPControls = MadProps.Windows.Controls;
That means that instead of typing "MadProps.Windows.Controls.TextBox" all through your code, you can just type "MPControls.TextBox". Nice.
What I learned this morning, however, is that you can do the same thing with types! If you have a type name that's really complex (think generic types) you can create an alias for them, too! using MyDict = System.Collections.Generic.Dictionary<int, MyLongClassName>;
Now I can just declare a variable as type "MyDict" in code instead of retyping the full dictionary definition!
Granted the uses are limited. Unless it's a particularly nasty type name I think your code readability would be best served by avoiding these sorts of aliases. However, it's great to know that the feature exists.
For a long time I have been looking for a really easy way to create a cryptographically random string in c#. I knew it had to be simple but I just had not spend the time to dig one up. Specifically I was looking for a quick and easy way to get a string that was acceptable for use as a Token for session use.
using System; using System.Security.Cryptography;
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { byte[] random = new Byte[128]; //Tell it how long you want it to be RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetNonZeroBytes(random); // The array is now filled with cryptographically strong random bytes.
Console.WriteLine(System.Convert.ToBase64String(random)); Console.ReadKey(); } } }
If you are looking for a ASP.NET Google Map Control, your search is now over.
Jacob Reimers from http://www.reimers.dk/ offers a great asp.net control in 2 flavors.
The free version which lets you easily display a map with markers and/or lines and a licensed version which gives you the full power of Google Maps.
Download the free control, unzip it to your Bin folder in your web app and add a reference to it.
This is a sample asp.net page:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="GoogleMap" Namespace="Reimers.Map" TagPrefix="Reimers" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Google Map test</title> </head> <body> <form id="form1" runat="server"> <div> <reimers:googlemap id="GMap" runat="server" width="349" height="354" onmarkerclick="GMap_MarkerClick" /> </div> </form> </body> </html>
and the code behind:
using System;
using System.Web.UI;
using Reimers.Map;
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
GMap.GoogleKey = "Your API Code here";
GMap.MapType = MapType.Map;
GMap.TypeControl = MapTypeControl.None;
GMap.MapControl = ControlType.Small;
GoogleMarker testMarker = new GoogleMarker("newMarker", new GoogleLatLng(43.611611, -88.952931));
testMarker.MarkerText = "Test Marker";
GMap.Markers.Add(testMarker);
GMap.Latitude = testMarker.Latitude;
GMap.Longitude = testMarker.Longitude;
GMap.Zoom = 10;
}
protected void GMap_MarkerClick(GoogleMap GMap, GoogleMarker Marker, ref String MapCommand)
{
MapCommand = Marker.OpenInfoWindowHTML(GMap, Marker.MarkerText);
}
}
Sometimes we need to make some write to logs, trace, and maybe limit some features during debug. It's good to know that in debug mode we have precompiler identifier DEBUG is set. So, first of all you can try #if #endif construction. In my opinion, it's not very good to use #if directive, especialy if there is something better.
Conditional attribute. It can be applied to any method that returns void. Why void? Because the method call ignored if the condition is not fulfilled. The method can be static or not. [Conditional("DEBUG")]
static void DebugMethod()
{
}
So, this is the best way to make some job in DEBUG configuration. Also, it can be used to make different build configurations.
Partial methods are a new feature available in C# 3.0 that don't seem to get enough credit. I think there was a lot of confusion early on about what partial methods were and how they were used.
Partial methods are intended to solve a major problem that is not only caused by code-generation tools and also affects those same tools. For instance, you are writing a code-generation tool but want to provide a way for the developers that are using your generated classes to hook in to specific areas of the code. As such, you don't want them editing your generated code since those customizations will be lost the next time the tool runs. On the flip side of this scenario is the developer who needs to write the code that hooks into those specific areas and doesn't want that code being lost the next time the tool runs.
Delegates are one solution to this type of problem. In the generated code, you declare a delegate method that you then call at the appropriate areas. If no one has implemented a concrete version of the delegate, the call will not do anything. However, if someone has implemented am instance of that delegate then the call will run the code in that instance. This sounds like a pretty good solution, and, until partial methods it really was the only solution. The drawback is that the code for the delegate is always compiled in to the runtime of your application and add to the runtime overhead of application (granted, that overhead is minimal but it's still there).
Partial classes helped with this problem by allowing the code-generation tools to isolate the generated code in a partial class. This allowed the developer to add their own methods to the class without fear that they would be overwritten the next time the tool ran. However, it only helped partially. In order to accomplish our scenario, you still needed to provide a delegate to allow the developer to hook into your process.
If we take this a step further and look at partial methods, you will start to see how they work and what the benefit is of using them. The following rules govern how partials methods can be declared and used:
- Must be declared inside a partial class.
- Must be declared as a void return type.
- Must be declared with the partial.
- Cannot be marked as extern.
- Can be marked static or unsafe.
- Can be generic.
- Can have ref but not out parameters.
- Cannot be referenced as a delegate until they are implemented
- Cannot have access modifiers such as public, private or internal.
- Cannot be declared as virtual.
Partial methods are implicitly marked as private. This means they cannot be called from outside the partial class.
Now that we have the rules out of the way, let's take a look at an example. This is a completely contrived example, as you typically wouldn't declare both portions of the partial class yourself.
1: // This is the class that would normally have been autogenerated. 2: public partial class CustomTypedCollection 3: { 4: partial void BeforeAddingElement(CustomElement element); 5: 6: public void AddElement(CustomElement element) 7: { 8: BeforeAddingElement(); 9: } 10: } 11: 12: public partial class CustomTypedCollection 13: { 14: partial void BeforeAddingElement(CustomElement element) 15: { 16: Console.WriteLine("Element " + element + " is being added."); 17: } 18: } 19: 20: class Program 21: { 22: static void Main(string[] args) 23: { 24: CustomTypedCollection c = new CustomTypedCollection(); 25: c.AddElemeent(new CustomElement()); 26: } 27: }
In this example, the code-generation tool declares a partial method BeforeAddingElement. It is declared as just a function prototype with no implementation. Effectively, this tells the developer that if they want to hook in to the AddElement process, they can do so by declaring an implementation of the BeforeAddingElement method. If an implementation is declared, the implementation and the call inside AddElement will be compiled in to the runtime code. However, if no implementation is declared the call will be optimized by the compiler and it will be entirely eliminated in the runtime code.
This mechanism provides a lot of the same flexibility as delegates without the runtime overhead. It also allows the developer to work with a much smaller implementation of their portion of the partial class that contains only the few partial methods that have been implemented.
If you want to store configuration information in a XML file, you can easily use serialization to assist you. Instead of using XPath or DOM, and have some code to maintain, simply use the XmlSerializer to retrieve information.
Here's an example of a XML file:
-
<?xml version="1.0" encoding="utf-8"?>
-
<DatabaseConfig>
-
<Data>
-
<DatabaseConfigData
-
File="Data/Principal.xml"
-
EntityName="Principal"
-
Format="Xml" />
-
<DatabaseConfigData
-
File="Data/Role.xml"
-
EntityName="Role"
-
Format="Xml" />
-
</Data>
-
</DatabaseConfig>
And if you have the following classes (C#):
-
public class DatabaseConfig
-
{
-
public DatabaseConfigData[] Data { get; set; }
-
};
-
-
public class DatabaseConfigData
-
{
-
[System.Xml.Serialization.XmlAttribute()]
-
public string File { get; set; }
-
-
[System.Xml.Serialization.XmlAttribute()]
-
public string EntityName { get; set; }
-
-
[System.Xml.Serialization.XmlAttribute()]
-
public string Format { get; set; }
-
};
All you have to do to load the XML information into the DatabaseConfig class is (C#):
-
DatabaseConfig GetDatabaseConfig(string file)
-
{
-
XmlSerializer serializer =
-
-
using (StreamReader reader = new StreamReader (file ))
-
{
-
object obj = serializer.Deserialize(reader);
-
return (DatabaseConfig)obj;
-
}
-
}
There are a few issues you have to handle when using XML Serialization, wich you can see at my earlier posts about XML, XSD and Serialization.
Which .NET Framework Data Provider to Use?
To achieve the best performance for your application, use the .NET Framework data provider that is most appropriate for your data source. There are a number of data provider options for use in your applications. The following table provides information about the available data providers and which data sources a data provider is most appropriate for.
|
Provider |
Details |
|
SQL Server .NET Data Provider |
Found in the System.Data.SqlClient namespace.
Recommended for middle-tier applications using Microsoft SQL Server version 7.0 or later.
Recommended for single-tier applications using the Microsoft Data Engine (MSDE) or Microsoft SQL Server 7.0 or later. |
|
OLE DB .NET Data Provider |
Found in the System.Data.OleDb namespace.
Recommended for middle-tier applications using Microsoft SQL Server 6.5 or earlier, or any OLE DB provider that supports the OLE DB interfaces listed in OLE DB Interfaces Used by the OLE DB .NET Data Provider in the .NET Framework SDK.
For Microsoft SQL Server 7.0 or later, the .NET Framework Data Provider for SQL Server is recommended.
Recommended for single-tier applications using a Microsoft® Access database. Use of an Access database for a middle-tier application is not recommended. |
|
ODBC .NET Data Provider |
Found in the Microsoft.Data.Odbc namespace.
The ODBC .NET Data Provider is available for download.
Provides access to data sources that are connected to using an ODBC driver. |
|
Oracle .NET Data Provider |
Found in the System.Data.OracleClient namespace.
The .NET Framework Data Provider for Oracle, unlike the Microsoft OLE DB provider for Oracle, also supports new Oracle 9i datatypes, as well as ref cursors (useful for running Oracle stored procedures that return result sets). This provider, System.Data.OracleClient, is similar to the .NET Framework Data Provider for SQL Server, System.Data.SqlClient.
The Oracle .NET Data Provider is available for download |
The fastest database read mechanism will be ADO.NET Data Readers, as opposed to Data Sets.
PDFsharp is the Open Source library that easily creates PDF documents from any .NET language.
The same drawing routines can be used to create PDF documents, draw on the screen, or send output to any printer.
Here are just a few highlights:
- Creates PDF documents on the fly from any .Net language
- Easy to understand object model to compose documents
- One source code for drawing on a PDF page as well as in a window or on the printer
- Modify, merge, and split existing PDF files
- Images with transparency (color mask, monochrome mask, alpha mask)
- Newly designed from scratch and written entirely in C#
- The graphical classes go well with .Net
- Includes MigraDoc Lite for high level text layouting (you can use both PDFsharp and MigraDoc Lite in one document)
|
This sample shows how to create a PDF document, add a page, draw some text, and save it to disk. // Create a new PDF document
PdfDocument document = new PdfDocument();
// Create an empty page
PdfPage page = document.AddPage();
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
// Create a font
XFont font = new XFont("Verdana", 20, XFontStyle.Bold);
// Draw the text
gfx.DrawString("Hello, World!", font, XBrushes.Black,
new XRect(0, 0, page.Width, page.Height),
XStringFormat.Center);
// Save the document...
string filename = "HelloWorld.pdf";
document.Save(filename);
// ...and start a viewer.
Process.Start(filename);The result is this: | HelloWorld.pdf (2.41 KB)
Today, Google released their Chart API. Basically, the Google Chart API allows you to dynamically generate charts for use in your web applications. All you do is pass your data in the querystring and an image is returned. This isn't really a service to get too excited about, but it is pretty simple to use and it's Free.
Here is a bit about this:
The Google Chart API lets you dynamically generate charts. To see the Chart API in action, open up a browser window and copy the following URL into it:
http://chart.apis.google.com/chart?cht=p3&chd=s:hW&chs=250x100&chl=Hello|World
Press the Enter or Return key and - presto! - you should see the following image:

I decided to code up a small ASP.NET Server Control that uses the Google Chart API to put simple line graph charts on a page.
How to use this control:
Put the Chart control on the page:
<GoogleAPI:Chart runat="server" id="Chart1" Width="200" Height="150" LineColor="ff0000" BackgroundColor="efefef" ToolTip="Hello World"> </GoogleAPI:Chart>
In the page load event define the values to be charted:
Chart1.MaxValue = 60;
Chart1.Values.Clear();
Chart1.Values.Add("Jan", 10); Chart1.Values.Add("Feb", 20); Chart1.Values.Add("Mar", 30); Chart1.Values.Add("Apr", 50); Chart1.Values.Add("May", 5); Chart1.YAxisLabels.Add("0 Kb"); Chart1.YAxisLabels.Add("25+ Kb"); Chart1.YAxisLabels.Add("50+ Kb");
And, that's all you have to do to put a Chart on your page using the control.
The result is this:

Download the example / source code here: GoogleChartAPI.rar (3.33 KB)
Last week (december 5th) Microsoft announced the Volta technology preview, a developer toolset for building multi-tier web applications using existing and familiar tools, techniques and patterns.
Volta’s declarative tier-splitting enables developers to postpone architectural decisions about distribution until the last possible responsible moment. Also, thanks to a shared programming model across multiple-tiers, Volta enables new end-to-end profiling and testing for higher levels of application performance, robustness, and reliability. In effect, Volta extends the .NET platform to further enable the development of software+services applications, using existing and familiar tools and techniques.
You architect and build your application as a .NET client application, assigning the portions of the application that run on the server tier and client tier late in the development process.
After tier assignments, Volta's deep integration with Visual Studio debugger and testing infrastructure dramatically improves the deployment experience for developers.
- Volta automatically creates communication, serialization, and remoting code. Developers simply write custom attributes on classes or methods to tell Volta the tier on which to run them.
- Developers may base tier assignments on any criteria, such as load management, performance, or location of critical assets and capabilities. Because Volta automates the hidden plumbing code, it is easy for developers to experiment with varying assignments of classes and methods to tiers.
- Developers can use all the .NET languages, libraries, and tools they already know, including debuggers, profilers, test generators, refactoring, and code analysis tools.
Volta offers deep integration with Visual Studio 2008, including debuggers, profilers, and testing frameworks. Developers can step through code seamlessly from one tier to another, can set breakpoints on any tier, and trace flows of control across distributed systems.
What do you need to use Volta?
The Volta developer toolset requires Visual Studio 2008 and the .NET Framework 3.5 for writing and building applications. Volta applications run virtually anywhere, even where an MSIL runtime is not available. A Volta client-side application can run in most standards-compliant browsers, but can also be targetted also take advantage of MSIL runtimes like the .NET CLR.
All this sounds great, except the requirements that are trying to enforce the developers to use Visual Studio 2008 and the new .NET Framework 3.5.
I wonder why the long wait for this release? And why it does not compatible with .NET Framework 2.0?
BTW, It is just me or the Volta logo reminds firefox logo a bit:
<- VS -> 
This is one of those "Yeah I've always seen people use it differently but I don't know why!" questions.
Re-throwing exceptions can be misused, although it may not cause any harm to your application - there are multiple ways of re-throwing an exception, most likely for the purpose of bubbling it up to a higher level.
Lets look at how many ways we can use throw:
- throw
- throw ex
- throw new Exception();
You should not use #3 except if you are throwing a specific exception other that the one that was fired such as a custom exception. To re-throw an exception in .NET your best option is #1 instead of #2 and that is simply because of how they stack up in the stack trace. Lets take a look at the stack trace for both instances using the following snippet.
protected void Page_Load(object sender, EventArgs e)
{
try
{
DoMath();
}
catch(Exception ex)
{
throw ex;
}
}
/// <summary>
/// A method that simply calls another method.
/// </summary>
/// <remarks>
/// Just a helper to show stack trace
/// </remarks>
private void DoMath()
{
MethodWithError();
}
/// <summary>
/// This method will throw an error
/// </summary>
private void MethodWithError()
{
throw new Exception("Generic exception");
}
The stack trace looks like this: [Exception: Generic exception]
throwerror.Page_Load(Object sender, EventArgs e) in d:\My Websites\demoweb\throwerror.aspx.cs:22
System.Web.Util.CalliHelper.EventArgFunctionCaller (IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback (Object sender, EventArgs e) +34
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
However, if I replace "throw ex;" with just "throw;", here is the new stack trace.
[Exception: Generic exception] throwerror.MethodWithError() in d:\My Websites\demoweb\throwerror.aspx.cs:42 throwerror.DoMath() in d:\My Websites\demoweb\throwerror.aspx.cs:34 throwerror.Page_Load(Object sender, EventArgs e) in d:\My Websites\demoweb\throwerror.aspx.cs:22 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34 System.Web.UI.Control.OnLoad(EventArgs e) +99 System.Web.UI.Control.LoadRecursive() +47 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
Its all about the details. Obviously, using just "throw;" gives us much more details - so use "throw" to re-throw an error.
Now that the .NET Framework 3.5 has been released, this version includes logic to detect the presence of the .NET Framework 3.5 and also .NET Framework 3.0 service packs, which was missing from previous versions of this sample code.
You can download updated versions of the sample code at the following locations:
For reference, the registry locations used in this sample code to detect the .NET Framework 3.0 service pack level and the .NET Framework 3.5 are listed below.
To detect the .NET Framework 3.0 service pack level:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0] SP = <value>
Note - this SP value will not exist at all if you only have the original release of the .NET Framework 3.0. This value was added starting in the .NET Framework 3.0 SP1 and will be updated for future service packs.
To detect the .NET Framework 3.5 final release:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5] Install = 1 Version = 3.5.21022.08
To detect the .NET Framework 3.5 service pack level:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5] SP = <value>
Note - this SP value does exist in the final release of the .NET Framework 3.5, and will be set to 0. Future service packs will increment this value as appropriate.
|