
Monday, 18 October 2010

Tuesday, 28 September 2010
Why ASP.NET AJAX UpdatePanels are dangerous
Unfortunately, that very lack of transparency regarding the mechanics of the client/server exchange makes it all too easy to shoot yourself (or your application) in the foot. Let me give you an example that you’re probably familiar with by now, and thoroughly sick of seeing:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel runat="server" ID="up1"> <ContentTemplate>
<asp:Label runat="server" ID="Label1" Text="Update Me!" /><br />
<asp:Button runat="server" ID="Button1" Text="Postback Update"
OnClick="Button1_Click" /> ContentTemplate> asp:UpdatePanel>
protected void Button1_Click(object sender, EventArgs e)
{ Label1.Text = DateTime.Now.ToLongDateString(); }
Simple enough. Button1 is clicked, an asynchronous request is made for the current date/time, and that is displayed as Label1′s content. As simple as it sounds, take a look at the actual HTTP post and response necessary to accomplish the partial postback:
Shocking, isn’t it? To display a 22 character string, that’s an awful lot of data sent and received. Acceptable for infrequently used functionality, but a potential deal breaker in heavy use. Luckily, Microsoft has given us a more efficient way to do this, as part of the ASP.NET AJAX framework.
Page Methods
Page methods allow ASP.NET AJAX pages to directly execute a page’s static methods, using JSON (JavaScript Object Notation). JSON is basically a minimalistic version of SOAP, which is perfectly suited for light weight communication between client and server. For more information about how to implement page methods and JSON, take a look at Microsoft’s Exposing Web Services to Client Script in ASP.NET AJAX.
Instead of posting back and then receiving HTML markup to completely replace our UpdatePanel’s contents, we can use a web method to request only the information that we’re interested in:
<asp:ScriptManager ID="ScriptManager1" runat="server"
EnablePageMethods="true" /> <script language="javascript">
function UpdateTime() {
PageMethods.GetCurrentDate(OnSucceeded, OnFailed); }
function OnSucceeded(result, userContext, methodName) {
$get('Label1').innerHTML = result; }
function OnFailed(error, userContext, methodName) {
$get('Label1').innerHTML = "An error occured."; }
script> <asp:Label runat="server" ID="Label1" Text="Update Me!" />
<br /> <input type="button" id="Button2" value="Web Method Update"
onclick="UpdateTime();" />
Using JSON, the entire HTTP round trip is 24 bytes, as compared to 872 bytes for the UpdatePanel. That’s roughly a 4,000% improvement, which will only continue to increase with the complexity of the page.
Not only has this reduced our network footprint dramatically, but it eliminates the necessity for the server to instantiate the UpdatePanel’s controls and take them through their life cycles to render the HTML sent back to the browser.
While I’m a proponent of the simplicity inherent in the UpdatePanel, I think that it is crucial that we use them judiciously. In any heavy use situation, they are very rarely the best solution.
Convert DataTable to JSON string
{
string[] StrDc = new string[Dt.Columns.Count];
string HeadStr = string.Empty;
for (int i = 0; i <>
{
StrDc[i] = Dt.Columns[i].Caption;
HeadStr += "\"" + StrDc[i] + "\" : \"" + StrDc[i] + i.ToString() + "\",";
}
HeadStr = HeadStr.Substring(0, HeadStr.Length - 1);
StringBuilder Sb = new StringBuilder();
Sb.Append("{\"" + Dt.TableName + "\" : [");
for (int i = 0; i <>
{
string TempStr = HeadStr;
Sb.Append("{");
for (int j = 0; j <>
{
TempStr = TempStr.Replace(Dt.Columns[j] + j.ToString(), Dt.Rows[i][j].ToString());
}
Sb.Append(TempStr + "},");
}
Sb = new StringBuilder(Sb.ToString().Substring(0, Sb.ToString().Length - 1));
Sb.Append("]};");
return Sb.ToString();
}
Differences between ASMX and WCF Web Services
Serialization is the process of translating binary objects into a data format that can be transmitted across process boundaries, computer boundaries, and network boundaries. When serialized data reaches the destination, or endpoint, it can be deserialized back into binary objects for use by an application. Both ASMX and WCF use SOAP for messages passed between two endpoints. However, for serialization, each uses different classes that implement different rules.
ASMX uses the XmlSerializer to translate classes into XML for communication, and to translate the XML back into classes on the receiver's end. All public members are serialized unless they are marked as non-serializable using the XmlIgnoreAttribute. A large number of attributes can also be used to control the structure of the XML. For example, a property can be represented as an attribute using theXmlAttributeAttribute, or as an element using the XmlElementAttribute. The use of these attributes provides a great deal of control over how a type is serialized into XML; however, that power comes with an unfortunate downside. It may be possible to create XML structures that are not easily translated by other type systems, such as Java; XML structures that are not easily translated can hamper interoperability.
WCF uses a DataContractSerializer to perform the same translation; however, the behavior is different from the XmlSerializer. The XmlSerializer uses an implicit model where all public properties are serialized unless they are marked with the XmlIgnoreAttribute, but the DataContractSerializer uses an explicit model where the properties and/or fields that you want to serialize must be marked with aDataMemberAttribute. It is important to note that WCF can also use the XmlSerializer to perform serialization operations.
A notable difference between ASMX and WCF is the WCF ability to serialize class members regardless of the access specifier used. This means it is now possible to serialize private fields. Using this capability, you can encapsulate fields in a data type. For example, you can provide read-only access to a private field by implementing only the get method on a property. You can then serialize that private field by adding the DataMemberattribute to the field in a WCF service.
Another important difference is that the DataContractSerializer generates a simplified XML structure that increases its ability to interoperate between different operating systems. In addition, the ability for users to control the XML structure is limited. This simplified structure also means that future versions of WCF will be able to target this structure for optimization. Finally, in comparison to the XmlSerializer, the serialization of data is greatly improved with the DataContractSerializer.
Recommendation
Using WCF, you can use the XmlSerializer for types that are already created. However, to maximize interoperability, it is recommended to use WCF data contracts and the DataContractSerializer. The Web Service Software Factory (ASMX) guidance package, also referred to as the ASMX guidance package, creates types that should also migrate to WCF data contracts if no additional XML serialization attributes, such asXmlAttributeAttribute, are added. The ASMX guidance package includes an XmlNamespaceAttribute to specify the namespace of the types.
Developers can use the SOAP extensions feature of ASP.NET to interact directly with SOAP messages. By using SOAP extensions, you can intercept the SOAP message and insert your own code into the SOAP message pipeline, which allows you to extend the capabilities of SOAP. For example, features such as security, transaction management, routing, and tracing can be implemented by using SOAP extensions. The downside of this capability is that it reduces the SOAP message's ability to interoperate with other operating systems. In other words, other operating systems may not be able to handle a SOAP message that has been customized.
WCF does not support the use of SOAP extensions, but it does have other extensibility points that can be used to intercept and manipulate SOAP messages. For example, you can use a behavior extension to hook into the WCF Dispatcher with a class that implements IDispatchMessageInspector.
Recommendation
Avoid the use of SOAP extensions when developing new ASMX services that will be migrated to WCF unless you are willing to rewrite them or if you are confident that WCF provides a similar capability.
3. Transport Protocols
ASMX services use the HTTP transport protocol for communications with Internet Information Services (IIS) as the host. An ASMX service file has the file name extension .asmx, which is accessed using a Uniform Resource Locator (URL); for example, http://localhost/ASMXEmployee/EmployeeManager.asmx.
WCF services can also use the HTTP protocol, but unlike ASMX services, you also have the option to use other transport protocols. The following protocols are supported by WCF:
- Hypertext Transfer Protocol (HTTP)
- Transmission Control Protocol (TCP)
- Message Queuing (also known as MSMQ)
- Named pipes
Many different hosts can also be used with WCF services. For example, IIS can be used as a host with the HTTP transport protocol. Windows services and stand-alone applications can be used as a host for other transport protocols.
Accessing a service hosted in IIS is similar to accessing an ASMX service; for example, http://localhost/WCFEmployee/EmployeeManager.svc.
The only difference between the two services is the file name extension. However, you can also configure a WCF service to use the .asmx file name extension, as described in the Service Configuration topic. WCF services that use other transport protocols are accessed using methods associated with the specific protocol.
When migrating an ASMX service to WCF, the protocol you choose is based on the client applications that will be accessing the service. If you need to support ASMX client applications, you also need to use the HTTP protocol. In addition, when configuring a WCF service for ASMX client applications, you need to configure the service to use BasicHttpBinding, as described in the Service Configuration topic.
Recommendation
When migrating services from ASMX to WCF, and if ASMX client applications need to access the migrated service, use the HTTP protocol and configure the new service to use BasicHttpBinding.
Typically, authentication and authorization with ASMX is done using IIS and ASP.NET security configurations and transport layer security. In addition, Web Service Extensions (WSE) can be used to provide additional security capabilities, such as message layer security.
WCF can use the same security components as ASMX, such as transport layer security and WSE. However, WCF also has its own built-in security, which allows for a consistent security programming model for any transport. The security implemented by WCF supports many of the same capabilities as IIS and WS-* security protocols. However, when using IIS, you must also enable anonymous access to the service so that WCF security is implemented.
A powerful reason for migrating an ASMX service to WCF is to take advantage of new security capabilities that are provided by WCF. For example, WCF provides support for claims-based authorization that provides finer-grained control over resources than role-based security. In addition, instead of depending on a transport protocol such as HTTP and extensions such as WSE, security is built into WCF. The end result is that security is consistent regardless of the host that is used to implement a WCF service.
Recommendation
When possible, migrate both client applications and services to WCF to take advantage of the new security features that are available with WCF. Use of the WCF Security guidance package is also recommended when configuring security for WCF services and client applications.
If a migrated WCF service must support ASMX client applications, you can use transport security associated with HTTP and HTTPS. You can also use WSE 3.0, but you must configure a custom WCF binding for this to work. For additional information about using WSE 3.0 with WCF
With ASMX services, unhandled exceptions are always returned to client applications as SOAP faults. An ASMX service can also throw the SoapException class, which provides more control over the content of the SOAP fault that is returned to the client application.
However, when an unhandled exception occurs, the default configuration of WCF protects sensitive data from exposure by not returning sensitive information in SOAP fault messages. You can override this behavior by adding a serviceDebug element to the service behavior in the configuration file that is associated with a WCF service. Overriding this behavior is not recommended for deployment; it should be used only in a development environment.
Similar to the SoapException class used with ASMX services, you can also throw a custom exception by using the FaultException type, where T is a data contract that contains the exception information. The use of custom exceptions also requires the declaration of a FaultContract on operations that will throw the exception.
The following code example demonstrates how a DataContract is used to define a FaultContract declared on a service operation in a ServiceContract.
ASMX services have access to the HttpContext class, which provides access to state managers with a different scope, such as application scope and session scope. ASP.NET also provides control over how state data is managed. Consequently, you should minimize the use of state in a service because of the effect it has on the scalability of an application. WCF provides extensible objects that can be used for state management. Extensible objects implement the System.ServiceModel.IExtensibleObject interface. The two main classes that implement theIExtensibleObject interface are ServiceHostBased and InstanceContext. The ServiceHostBased class provides the ability for all service instances in the same host to access the same state data. On the other hand, the InstanceContext class only allows access to state data within the same service instance. To implement state management in WCF, you need to define a class that implements the IExtension interface, which is used to hold the state data. Instances of this class can then be added to one of theIExtensibleObject classes using the Extensions property. The following code example shows how to implement state using the InstanceContext.
Wednesday, 8 September 2010
Introduction
CAPTCHA stands for "completely automated public Turing test to tell computers and humans apart." What it means is, a program that can tell humans from machines using some type of generated test. A test most people can easily pass but a computer program cannot.
You've probably encountered such tests when signing up for an online email or forum account. The form might include an image of distorted text, like that seen in the sample screen shot, which you are required to type into a text field.
The idea is to prevent spammers from using web bots to automatically post form data in order to create email accounts (for sending spam) or to submit feedback comments or guestbook entries containing spam messages. The text in the image is usually distorted to prevent the use of OCR (optical character reader) software to defeat the process. Hotmail, PayPal, Yahoo and a number of blog sites have employed this technique.
This article demonstrates how to create such an image and employ it within an ASP.NET web form.
Background
You can find more information on CAPTCHA at The CAPTCHA Project and read about its use in foiling purveyors of pills, pr0n and pyramid-schemes in an article from Scientific American entitled Baffling the Bots.
Before using this technique however, you should consider how it will affect your site's accessibility to the blind and other visually impaired visitors. PayPal attempts to address this problem on their sign up form by including a link to an audio file, in which a voice spells out the image text.
The code presented here produces only an image. But, if you had code to generate an audio file, you could easily integrate it.
Using the code
The source code zip file contains the source for one class and two web forms. To use it, just create a new web project and add those items.
Files
- CaptchaImage.cs - defines the
CapchaImageobject which actually creates the image. - Default.aspx, Default.aspx.cs - a sample web form.
- JpegImage.aspx, JpegImage.aspx.cs - a web form designed to output a JPEG image rather than HTML.
Let's look at each component and it's purpose.
CaptchaImage.cs
The CaptchaImage object creates an image given parameters for the text to be displayed, the image dimensions and, optionally, the font to use.
The heart of the code is the GenerateImage() method, shown below, which creates a bitmap image of the specified width and height. This method is called from the CaptchaImage constructor, so the image is ready as soon as you create a new instance of the object.
To create the image, we first fill in the background using a hatched brush (the "dirtier" the image appears, the harder it is for an OCR program to read it).
To make the text fit within the image, we start with an initial font size based on the image height and use the Graphics.MeasureString() method to find the resulting dimensions of the drawn text. If the text exceeds the image dimensions, we reduce the font size and test again and again until a suitable font size is found.
// ==================================================================== // Creates the bitmap image. // ==================================================================== private void GenerateImage() { // Create a new 32-bit bitmap image. Bitmap bitmap = new Bitmap( this.width, this.height, PixelFormat.Format32bppArgb); // Create a graphics object for drawing. Graphics g = Graphics.FromImage(bitmap); g.SmoothingMode = SmoothingMode.AntiAlias; Rectangle rect = new Rectangle(0, 0, this.width, this.height); // Fill in the background. HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti,Color.LightGray,Color.White); g.FillRectangle(hatchBrush, rect); // Set up the text font. SizeF size; float fontSize = rect.Height + 1; Font font; // Adjust the font size until the text fits within the image. do { fontSize--;font = new Font(this.familyName,fontSize,FontStyle.Bold); size = g.MeasureString(this.text, font); } while (size.Width > rect.Width); // Set up the text format. StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; // Create a path using the text and warp it randomly. GraphicsPath path = new GraphicsPath(); path.AddStringhis.text,font.FontFamily,(int) font.Style,font.Size, rect,format);float v = 4F; PointF[] points = { new PointF(this.random.Next(rect.Width) / v,this.random.Next(rect.Height) / v),new PointF(rect.Width - this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),new PointF(this.random.Next(rect.Width) / v,rect.Height - this.random.Next(rect.Height) / v),new PointF(rect.Width - this.random.Next(rect.Width) / v,rect.Height - this.random.Next(rect.Height) / v) }; Matrix matrix = new Matrix(); matrix.Translate(0F, 0F); path.Warp(points, rect, matrix, WarpMode.Perspective, 0F); // Draw the text. hatchBrush = new HatchBrush(HatchStyle.LargeConfetti,Color.LightGray,Color.DarkGray);g.FillPath(hatchBrush, path); // Add some random noise. int m = Math.Max(rect.Width, rect.Height);for (int i = 0; i < (int) (rect.Width * rect.Height / 30F); i++) {int x = this.random.Next(rect.Width);int y = this.random.Next(rect.Height);int w = this.random.Next(m / 50);int h = this.random.Next(m / 50);g.FillEllipse(hatchBrush, x, y, w, h); } // Clean up. font.Dispose(); hatchBrush.Dispose(); g.Dispose(); // Set the image. this.image = bitmap; } Once the font is set, we define a GraphicsPath() which essentially converts the text to a set of lines and curves. This can then be distorted using the GraphicsPath.Warp() method with some randomly generated values. The effect is similar to holding a cardboard sign up by opposite corners and giving it a bit of a twist. The resulting path is drawn onto the image, again using a hatch brush to give it a "dirty" appearance.
To complete the distortion, small blots are randomly painted over the image. You could experiment with other effect to thwart OCRs, but keep in mind that it should still be legible to humans, some of whom may have visual impairments
private void Page_Load(object sender, System.EventArgs e)
{ if (!this.IsPostBack) // Create a random code and store it in the Session object. this.Session["CaptchaImageText"] = GenerateRandomCode(); else { // On a postback, check the user input. if (this.CodeNumberTextBox.Text ==this.Session["CaptchaImageText"].ToString()) { // Display an informational message. this.MessageLabel.CssClass = "info"; this.MessageLabel.Text = "Correct!"; } else { // Display an error message. this.MessageLabel.CssClass = "error"; this.MessageLabel.Text = "ERROR: Incorrect, try again."; // Clear the input and create a new random code. this.CodeNumberTextBox.Text = ""; this.Session["CaptchaImageText"] = GenerateRandomCode(); } }} The reason for storing the text string in the Session object is so that it can be accessed by JpegImage.aspx.
JpegImage.aspx
For this web form, no HTML is needed (what's there is just the default code generated by Visual Studio when the file was created). Instead of HTML, the code will produce a JPEG image.
In the code-behind, we first create a CaptchaImage object, using the text retrieved from the Session object. This creates a bitmap image for us.
private void Page_Load(object sender, System.EventArgs e){// Create a CAPTCHA image using the text stored in the Session object.CaptchaImage ci = new CaptchaImage(this.Session["CaptchaImageText"].ToString(),200, 50, "Century Schoolbook");// Change the response headers to output a JPEG image. this.Response.Clear(); this.Response.ContentType = "image/jpeg"; // Write the image to the response stream in JPEG format. ci.Image.Save(this.Response.OutputStream, ImageFormat.Jpeg); // Dispose of the CAPTCHA image object. ci.Dispose();} We then modify the HTTP response headers to set the Content-type to "image/jpeg" so the client browser will know we are sending an image.
The last step is to retrieve the bitmap image from CaptchaImage.Image and write it to the HTTP response output stream in JPEG format. Fortunately, the Save() method of the Bitmap object makes this simple. Any other supported image format could be used as well so long as the Content-type header is set accordingly.
Points of Interest
Because the CaptchaImage class contains a Bitmap object, and bitmaps employ unmanaged resources, a custom Dispose() method is implemented. This allows those unmanaged resources to be freed whenever a CaptchaImage is destroyed.
Downloads
- CaptchaImage_src.zip - Source files (6KB)
- class files
Sunday, 5 September 2010
How to get table values using javascript without "FOR LOOP"
Thursday, 2 September 2010
ADO.NET Connection Pooling at a Glance
Introduction
This table shows all connection string properties for the ADO.NET SqlConnection object. Most of the properties are also used in ADO. Using this table will give you a better understanding of the options available.
The Properties
Some of the keywords have several equivalents. For those, each variant is specified on its own line separated with "-or-".
| Name | Default | Description |
| Application Name | | The name of the application, or '.Net SqlClient Data Provider' if no applicationname is provided. |
| Async | 'false' | When true, enables asynchronous operation support. Recognized values are true, false, yes, and no. |
| AttachDBFilename | | The name of the primary database file, including the full path name of an attachable database. AttachDBFilename is only supported for primary data files with an .mdf extension. The attachment will fail if the primary data file is read-only. The path may be absolute or relative by using the DataDirectory substitution string. If DataDirectory is used, the database file must exist within a subdirectory of the directory pointed to by the substitution string. |
| Connect Timeout | 15 | The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error. |
| Connection Lifetime | 0 | When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by Connection Lifetime. This is useful in clustered configurations to force load balancing between a running server and a server just brought online. A value of zero (0) causes pooled connections to have the maximum connection timeout. |
| Context Connection | 'false' | true if an in-process connection to SQL Server should be made. |
| Connection Reset | 'true' | Determines whether the database connection is reset when being removed from the pool. Setting to 'false' avoids making an additional server round-trip when obtaining a connection, but the programmer must be aware that the connection state is not being reset. |
| Current Language | | The SQL Server Language record name. |
| Data Source | | The name or network address of the instance of SQL Server to which to connect. The port number can be specified after the server name: server=tcp:servername, portnumber. When specifying a local instance, always use (local). To force a protocol, add one of the following prefixes: np:(local), tcp:(local), lpc:(local) |
| Encrypt | 'false' | When true, SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed. Recognized values are true, false, yes, and no. |
| Enlist | 'true' | When true, the pooler automatically enlists the connection in the creation thread's current transaction context. Recognized values are true, false, yes, and no. |
| Failover Partner | N/A | The name of the failover partner server where database mirroring is configured. The Failover Partner keyword is not supported by .NET Framework version 1.0 or 1.1. |
| Initial Catalog | | The name of the database. |
| Load Balance Timeout | 0 | The minimum time, in seconds, for the connection to live in the connection pool before being destroyed. |
| MultipleActiveResultSets | 'false' | When true, an application can maintain multiple active result sets (MARS). When false, an application must process or cancel all result sets from one batch before it can execute any other batch on that connection. Recognized values are true and false. The keyword is not supported by .NET Framework version 1.0 or 1.1. |
| Integrated Security | 'false' | Whether the connection is to be a secure connection or not. Recognized values are 'true', 'false', and 'sspi', which is equivalent to 'true'. |
| Max Pool Size | 100 | The maximum number of connections allowed in the pool. |
| Min Pool Size | 0 | The minimum number of connections allowed in the pool. |
| Network Library | 'dbmssocn' | The network library used to establish a connection to an instance of SQL Server. Supported values include dbnmpntw (Named Pipes), dbmsrpcn (Multiprotocol, Windows RPC), dbmsadsn (Apple Talk), dbmsgnet (VIA), dbmslpcn (Shared Memory, local machine only) and dbmsspxn (IPX/SPX), dbmssocn (TCP/IP) and Dbmsvinn (Banyan Vines). |
| Packet Size | 8192 | Size in bytes of the network packets used to communicate with an instance of SQL Server. |
| Password | | The password for the SQL Server account logging on. Not used with (the strongly recommended) 'Integrated Security=true' option. |
| Persist Security Info | 'false' | When set to 'false' (strongly recommended), security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state. Resetting the connection string resets all connection string values including the password. |
| Pooling | 'true' | When true, the SQLConnection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool. Recognized values are true, false, yes, and no. |
| Replication | 'false' | true if replication is supported using the connection. |
| Transaction Binding | Implicit Unbind | Controls connection association with an enlisted System.Transactions transaction. Possible values are: |
| TrustServerCertificate | 'false' | When set to true, SSL is used to encrypt the channel when bypassing walking the certificate chain to validate trust. If TrustServerCertificate is set to true and Encrypt is set to false, the channel is not encrypted. Recognized values are true, false, yes, and no. |
| Type System Version | N/A | A string value that indicates the type system the application expects. Possible values are: |
| User ID | | The SQL Server login account. |
| User Instance | 'false' | A value that indicates whether to redirect the connection from the default SQL Server Express instance to a runtime-initiated instance running under the account of the caller. |
| Workstation ID | The local computer name | The name of the workstation connecting to SQL Server. |
Summary
There is no point in always defining each of these properties. Return to this sheet to look up definitions as a way to ensure proper connections. Also use this as a reference to ensure that you have included every property applicable to your specific situation.



