Thursday, November 9, 2006

Calling a Windows or DOS Process from a Web Application

Your favorite program (graphics package, spell checker, translator, data converter) is written in Windows or DOS and you like to utilize it in your new web application. Suppose you like to generate your favorite pie chart (in real-time) using a DOS application and display the resulting pie image on your web page. When the Web user presses the submit button you will generate a new chart and display it to the user. This could be done seamlessly by invoking your DOS application using the System.Diagnostics.Process.Start() method or the more versatile System.Diagnostics.ProcessStartInfo class.

Lets start with the basic System.Diagnostics.Process.Start() method
It is simply a method call with conventional DOS space-seperated parametrs. For example in C#:

System.Diagnostics.Process.Start("MyImageProgram.bat", @"MyFile -g -r MyLastParam");

The first parameter is the program you want to run and the second parameter is a space-seperated list of parameter(s) to pass to the program.
Process.Start() waits forever for the process to execute. This could make your web site non-responsive.
System.Diagnostics.ProcessStartInfo gives you much more control to accomplish the same thing. For example, you could control the maximum amount of time to wait for the process completion.
Lets look at an example:


using System.Diagnostics;
using System.IO;

public void Main()
{
SyncCall(@"C:\MyWebSites\Images\MyImageProgram.bat", @"MyFile -g -r MyLAstParam");
}

private void SyncCall(string strProgramName, string syncParam)
{


System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(strProgramName);

// store your parameters
psi.Arguments = syncParam;< /FONT >

psi.UseShellExecute = false;< /FONT > // Specify for proper execution

System.Diagnostics.Process listFiles;
listFiles = System.Diagnostics.Process.Start(psi);< /FONT >

// optional for debugging. Grab the program console output
//System.IO.StreamReader myOutput = listFiles.StandardOutput;

// Wait a Maximum of 5000 milliseconds (5 seconds ) for the program execution.
listFiles.WaitForExit(5000);

// optional for debugging. Grab the program console output
/* string output;
if (listFiles.HasExited)
{
output = myOutput.ReadToEnd();
}
*/

}

Above, you specify the maximum amount to wait with the WaitForExit() method. If your program finishes faster than the amount of time you specified the system will not wait any longer and execution proceeds to the next line

(Also if your program outputs to the console you could grab the text using System.IO.StreamReader. Grabbing the text slows down execution. So it is only recommended for debugging.)

Above, after the image file is generated in real-time you could refer to it using an tag or server side tag.



Copyright @ Isaac Levy, Los Angeles, CA

Finding duplicates in a table using SQL

In Transact SQL duplicate rows for a table mytable based on column mycolumn may be found as follows:

SELECT myfield, COUNT(*)
FROM mytable
GROUP BY myfield
HAVING COUNT(*) > 1;

Caching in .NET handlers

Browser caching of a .NET handler may prevent the server-side code of the handler to be invoked. A user requesting an action for a second time may not get his/her results because your handler is cached and the invocation does not occur.

This problem also depends on how long the handler is being cached. If in your browser you delete all offline content (Tools - Internet Options - Delete Fiels - Check Delete all offline content - OK - OK) then your handler is no longer cached.


The solution is to add the following code to the ProcessRequest function of the handler:

// Don't allow this response to be cached by the browser.
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
context.Response.Cache.SetExpires(DateTime.MinValue);




Isaac Levy, August 2006

RegisterForEventValidation and event validation

When submitting pages in ASP.NET 2.0 you may get a validation error.

"Invalid postback or callback argument.
Description: An unhandled exception occurred during the execution of the current web request. "

Event validation is enabled using in configuration or <%@ Page> EnableEventValidation="true" %> in a page

For security purposes it is not advisable to turn off validation.

The error occurs for one of the following reasons:

1) You have a server-side asp control (such as a drop down) that you populate using javascript. The server-side rendered values do not match the populated values since you populated the drop down on the client-side.

2) You have an invalid HTML on the page. (For example, you may have a closing /form tag without a corresponding beginning form tag!). You may want to run your HTML through one of many free HTML validators on the Internet.


In the first case where you have populated your drop down with Javascript you could eliminate the error by calling the RegisterForEventValidation function. RegisterForEventValidation can only be called during Render().
You will need to register each valid value that you use in the Javascript code. For example if you populate a drop down with U.S. state abbreviations, you need to register each state code on the server side as follows:

Page.ClientScript.RegisterForEventValidation(ddlState.UniqueID, "AK");
Page.ClientScript.RegisterForEventValidation(ddlState.UniqueID, "AL");
Page.ClientScript.RegisterForEventValidation(ddlState.UniqueID, "CA");

And so forth ...


You may also want to consider the following as another workaround:
(Check the following article for more details: http://msdn2.microsoft.com/en-us/library/w1sw53ds.aspx)

1)If you want to display strings in your application but do not trust them, apply HTML encoding to them when the strings are written back in a response. For example, with encoding, the tag b becomes <b>. You might do this if the strings that you are displaying are from a database whose contents you are not sure that you can trust.

2)If you want your application to accept some HTML (for example, some formatting instructions from users), you should encode the HTML at the client before it is submitted to the server.





@Copyright 2006, Isaac Levy

Cool Mouse Over Effects
















Ever wanted to show a popup information window when the mouse rolls over an
image, a grid cell, a hyper link or any other UI control?


In this article we display a table (window) when the user rolls over an ASP.NET
server-side control.


The window to display is contained in a "div" tag. The content of the "div" tag
may be changed at runtime using the javascript "innerHtml" property. These will
be described later.


First, We need to define a style for the "div" tag. The style could be defined
within the html HEAD tags as follows:




Above position:absolute is necessary. The position of
the <div> tag will change as we move the mouse over different controls.
position:absolute position 
insures
the div will be positioned at the new location.


Next we define two javascript functions for showing and hiding the div:





Above the showimage() function will be called on the onmouseover event.
window.event.x and window.event.y specify the location of the mouse during the
onmouseover event.

The coordinates of the "div" will be set using the x, y mouse location. To the
mouse x location we simply add extra space so that the window will be displayed
a bit to the right of our control.


The content of the "div" is changed using the innerHTML attribute as follows:





Next, In the .ASPX file define your rollover div tag:



Next, we need to program our asp.net server side control to respond to
javascript client-side events. This would be done on the server side. For
example in C#:




Above we program our server control, MyServerControl1, to respond to the
client-side


onmouseover and onmouseout events. To the showimage function we pass strTitle
which is the text we want to display in the window. The info is displayed using
innerHTML attribute as described above.






Copyright @ Isaac Levy, Los Angeles, CA


(Author's Email: RisingDeepStar@yahoo.com)





Simulating Return Key

Place this code on page load where buttonID is the ID of the button or image that you want to associate with the Form's return key. On pressing the return key the onclick event for the button is executed.

Page.RegisterHiddenField("__EVENTTARGET", buttonID);