Web Q&A

Pop-Ups, Encrypting an ADO.NET Data Stream, and More

Edited by Nancy Michell

Q I am using a WebBrowser control in a C# application. When using the control to navigate to a Web page, some pop-up windows appear, which I'd like to disable. I tried the following code:

private void axWebBrowser1_NewWindow2(object sender,
    AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
    e.cancel = true;
}

Q I am using a WebBrowser control in a C# application. When using the control to navigate to a Web page, some pop-up windows appear, which I'd like to disable. I tried the following code:

private void axWebBrowser1_NewWindow2(object sender,
    AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
    e.cancel = true;
}

This causes another problem: when I click a link in the page, if the link is opened in a new window, this window is also killed.

A It's really difficult to determine whether a new window is one the user wants to see or not; she could be browsing to a page or Web app that's supposed to open a new window or she could have right-clicked and selected "open in new window." Ideally you would probably want to parse the Web page that's being loaded in the new window and determine its relevance, but that's nearly impossible.

A It's really difficult to determine whether a new window is one the user wants to see or not; she could be browsing to a page or Web app that's supposed to open a new window or she could have right-clicked and selected "open in new window." Ideally you would probably want to parse the Web page that's being loaded in the new window and determine its relevance, but that's nearly impossible.

So, it's a tough problem. You have to consider things such as targeting unknown frame names, using NavigateAndFind, and so forth. You could set a flag when you get the click message, but when do you unset the flag? Some pop-up blockers use timers. When you get a click, the first new window opened in the next 2500 ms is allowed; everything else is blocked. But even this is not foolproof.

Windows® XP Service Pack 2 contains a new event, NewWindow3, which adds a parameter that includes flags indicating whether or not mshtml.dll thinks a pop-up window is the result of a user-initiated action. Using that flag would be the optimal solution, once you upgrade to Windows XP Service Pack 2.

For more information, take a look at Changes to Functionality in Microsoft Windows XP Service Pack 2 and also check out Jeff Davis' blog at XP SP2 RC1.

Q Is there any way to encrypt an ADO.NET data stream as part of SQL replication? My SQL server is hosted at an ISP and I want to use SQL replication to replicate the database to my internal site.

Q Is there any way to encrypt an ADO.NET data stream as part of SQL replication? My SQL server is hosted at an ISP and I want to use SQL replication to replicate the database to my internal site.

A Take a look at the Encrypt connection string keyword (SqlConnection.ConnectionString Property). When this value is true, SQL Server™ uses Secure Sockets Layer (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.

A Take a look at the Encrypt connection string keyword (SqlConnection.ConnectionString Property). When this value is true, SQL Server™ uses Secure Sockets Layer (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.

Q My group is porting a legacy ASP application to ASP.NET. The old version uses lots of calls to the JScript® escape and unescape methods. It doesn't look like there are direct C# equivalents in the ASP.NET world for server-side calls to escape.

Q My group is porting a legacy ASP application to ASP.NET. The old version uses lots of calls to the JScript® escape and unescape methods. It doesn't look like there are direct C# equivalents in the ASP.NET world for server-side calls to escape.

What is the best practice for porting the JScript server-side escape method to C#? Ideally, we don't want to have to modify our client-side script calls to unescape.

A You probably shouldn't try to port it to C# in the first place. Why not just use JScript .NET? JScript .NET was specifically designed for your scenario—you've got a bunch of JScript code that has to be ported to ASP.NET. Why go through all the expense and difficulty of porting working code to a new language?

A You probably shouldn't try to port it to C# in the first place. Why not just use JScript .NET? JScript .NET was specifically designed for your scenario—you've got a bunch of JScript code that has to be ported to ASP.NET. Why go through all the expense and difficulty of porting working code to a new language?

If you're set on porting it to C#, and you have determined that you meant to call escape (not UrlEncode, UriEncode, or any other encoding methods) then probably the easiest thing for you to do would be to call Microsoft.JScript.GlobalObject.escape.

Q I've got a client that creates a proxy and calls a Web service. It works fine until I deploy it on another server, but if the time difference between the client and server is more than five minutes, the Message Expired exception is thrown from SoapHttpClientProtocol.ReadResponse. I don't want to sync the time between the client and the server. Where can I set a value for Microsoft.Web.Services.HttpSoapContext.ResponseContext.Timestamp.Ttl?

Q I've got a client that creates a proxy and calls a Web service. It works fine until I deploy it on another server, but if the time difference between the client and server is more than five minutes, the Message Expired exception is thrown from SoapHttpClientProtocol.ReadResponse. I don't want to sync the time between the client and the server. Where can I set a value for Microsoft.Web.Services.HttpSoapContext.ResponseContext.Timestamp.Ttl?

A You can set the Ttl (time-to-live) value on the response inside the Web service before sending the response back if the message is expiring on the response. To be clear, set RequestSoapContext.Timestamp.Ttl from the client if the message is expiring on the request; set ResponseSoapContext.Timestamp.Ttl inside the Web service if the message is expiring on the response.

A You can set the Ttl (time-to-live) value on the response inside the Web service before sending the response back if the message is expiring on the response. To be clear, set RequestSoapContext.Timestamp.Ttl from the client if the message is expiring on the request; set ResponseSoapContext.Timestamp.Ttl inside the Web service if the message is expiring on the response.

Q What's the best way to load site configuration settings stored in a database into an ASP.NET Web site before the Web site is accessed by users? I want to run an initialization process on a subsite before it is accessed by users.

Q What's the best way to load site configuration settings stored in a database into an ASP.NET Web site before the Web site is accessed by users? I want to run an initialization process on a subsite before it is accessed by users.

A Within Global.asax you will find the empty shell method:

protected void Application_Start(Object sender, EventArgs e)
{

}

This method is fired when the ASP.NET worker process or Microsoft® Internet Information Services (IIS) starts up an instance of this application, and this method will also fire every time the application is recycled (in IIS 5.0 and IIS 6.0) or when starting another process to handle requests (IIS 6.0).

A Within Global.asax you will find the empty shell method:

protected void Application_Start(Object sender, EventArgs e)
{

}

This method is fired when the ASP.NET worker process or Microsoft® Internet Information Services (IIS) starts up an instance of this application, and this method will also fire every time the application is recycled (in IIS 5.0 and IIS 6.0) or when starting another process to handle requests (IIS 6.0).

One caveat to address is to make sure any resource (config file, database, share, for example) that you are accessing from the Application_Start is safe for concurrent access. By that I mean that the resource is read-only and specifically allows concurrent access or has some mitigation to resource contention.

You should also be aware that when the application has not yet executed on a server (after a shutdown or recycle), the first client will trigger the application to be started and loaded into memory, and this will trigger the App_Start. Depending on how long your configuration resources take to load and process, the first client will take significantly longer to load the page.

Q Can I use Active Directory® to store relatively static application data? My business application has a set of reference tables (about 10 tables with a total of about 2,000 to 5,000 rows). Can I place those tables into Active Directory? I plan to store pure business application data such as a set of permitted operations and the code to perform these operations.

Q Can I use Active Directory® to store relatively static application data? My business application has a set of reference tables (about 10 tables with a total of about 2,000 to 5,000 rows). Can I place those tables into Active Directory? I plan to store pure business application data such as a set of permitted operations and the code to perform these operations.

A You should have no problem at all. Keep in mind that you have to define a proper schema definition for your attributes. You also have to decide whether you want them to replicate with the Global Catalog. If you do, you need to ensure you are prepared for the schema update and possible Global Catalog rebuild (if you are running domains with Windows 2000 domain controllers). You could also store your application-specific data through an application partition in Active Directory or in a separate Active Directory Application Mode (ADAM) instance. These both have different implications for your design that you will have to evaluate, but both will give you more control over replication.

A You should have no problem at all. Keep in mind that you have to define a proper schema definition for your attributes. You also have to decide whether you want them to replicate with the Global Catalog. If you do, you need to ensure you are prepared for the schema update and possible Global Catalog rebuild (if you are running domains with Windows 2000 domain controllers). You could also store your application-specific data through an application partition in Active Directory or in a separate Active Directory Application Mode (ADAM) instance. These both have different implications for your design that you will have to evaluate, but both will give you more control over replication.

The other thing you'll want to keep in mind is that whatever data you store in the directory should be fairly static. If you know that you're going to be writing more than reading the data, you're probably better off with a SQL store.

If you're trying to implement role-based access control for the application, an alternative approach would be to use AzMan which enables you to create the operations, tasks, and roles and store them in Active Directory or in an XML file store, depending on your application requirements.

Q I have a problem regarding the default HTML Submit button. I need the Cancel button to appear in the left side of the OK button, which is the opposite of the default behavior. I also need the default Submit button to say "Okay," not "OK." I found Microsoft Internet Explorer will set focus to the first declared button (Cancel in this case) when users start to input data. When users hit the Enter button, a Cancel.Click is fired.

Q I have a problem regarding the default HTML Submit button. I need the Cancel button to appear in the left side of the OK button, which is the opposite of the default behavior. I also need the default Submit button to say "Okay," not "OK." I found Microsoft Internet Explorer will set focus to the first declared button (Cancel in this case) when users start to input data. When users hit the Enter button, a Cancel.Click is fired.

A Here's one solution: don't use two submit inputs in the form; use one submit and, if needed, add buttons. If you need your Cancel button to submit the form, implement this in client-side code, as shown in Figure 1.

onclick="javascript: Form1.Submit();"

A Here's one solution: don't use two submit inputs in the form; use one submit and, if needed, add buttons. If you need your Cancel button to submit the form, implement this in client-side code, as shown in Figure 1.

onclick="javascript: Form1.Submit();"

Figure 1 Submit Button

<HTML>
    <HEAD>
    </HEAD>
    <body>
        <form name="Form1" id="Form1">
        <table cellspacing="0" cellpadding="0" border="0">
            <TR>
                <TD colspan="2"><input name="TextBox1" type="text" 
                    id="TextBox1" style="width:150px;"></TD>
            </TR>
            <TR>
                <TD><input type="button" name="Cancel" 
                     onclick="javascript: Form1.Submit();" value="Cancel" 
                     id="Cancel" tabindex="2" style="width:60px;"></TD>
                <TD><input type="submit" name="Okay" value="Okay" 
                     id="Okay" tabindex="2" style="width:60px;"></TD>
            </TR>
        </form>
    </body>
</HTML>

Q I have a form that has a server-side textbox control and a Submit button. The textbox is a server control because some data validation needs to happen right away. If the user makes an edit in the textbox and doesn't tab off but rather clicks the Save button, only the change event for the textbox fires. Is there a way to get both events to fire on the server?

Q I have a form that has a server-side textbox control and a Submit button. The textbox is a server control because some data validation needs to happen right away. If the user makes an edit in the textbox and doesn't tab off but rather clicks the Save button, only the change event for the textbox fires. Is there a way to get both events to fire on the server?

A If you have AutoPostback turned on for the textbox, it will submit as soon as the focus is moved out of that textbox, causing you to lose the next Submit button event. In order to get both events, you need to turn off the AutoPostBack for the textbox. Then when you click the Submit button, the TextChanged event will fire first, then the button click event will fire. As far as providing user feedback as they tab off the field, if you use a validator control for the textbox, you can get immediate feedback using script but still preserve the textbox's event on postback.

A If you have AutoPostback turned on for the textbox, it will submit as soon as the focus is moved out of that textbox, causing you to lose the next Submit button event. In order to get both events, you need to turn off the AutoPostBack for the textbox. Then when you click the Submit button, the TextChanged event will fire first, then the button click event will fire. As far as providing user feedback as they tab off the field, if you use a validator control for the textbox, you can get immediate feedback using script but still preserve the textbox's event on postback.

Q Is it possible to redirect the client browser to a new page by passing parameters via an HTTP POST request? If so, how? I don't want to use a meta tag refresh to redirect the page.

Q Is it possible to redirect the client browser to a new page by passing parameters via an HTTP POST request? If so, how? I don't want to use a meta tag refresh to redirect the page.

A You can process the parameters through the Request.Forms property, then use Response.Redirect or Server.Transfer to perform a redirect. An article comparing Server.Transfer and Response.Redirect can be found at Server.Transfer Vs. Response.Redirect. If you are looking to post to a page not on your server, then you won't be able to use either of them. In that case, you may have to go for a page with hidden forms and a JavaScript onload event. As soon as the onload event fires, submit your hidden form. You can build the form on the fly, parameterizing the required fields and the action. The only caveat is that there will be tracking information about this page stored in the browser's URL history.

A You can process the parameters through the Request.Forms property, then use Response.Redirect or Server.Transfer to perform a redirect. An article comparing Server.Transfer and Response.Redirect can be found at Server.Transfer Vs. Response.Redirect. If you are looking to post to a page not on your server, then you won't be able to use either of them. In that case, you may have to go for a page with hidden forms and a JavaScript onload event. As soon as the onload event fires, submit your hidden form. You can build the form on the fly, parameterizing the required fields and the action. The only caveat is that there will be tracking information about this page stored in the browser's URL history.

Q Can I run an exe from a button click in ASP.NET?

Q Can I run an exe from a button click in ASP.NET?

A Yes, if the requester has adequate permissions, it is possible to run an exe on the server. You can use the System.Diagnostics namespace to launch it. The code in Figure 2 shows how to use this object to display the directory information using cmd.exe. First create a wrapper class for this functionality. Then you can execute the command from any event or function like so:

dim myp As New myproc("cmd.exe", "/C Dir e:\")
myp.Start()

A Yes, if the requester has adequate permissions, it is possible to run an exe on the server. You can use the System.Diagnostics namespace to launch it. The code in Figure 2 shows how to use this object to display the directory information using cmd.exe. First create a wrapper class for this functionality. Then you can execute the command from any event or function like so:

dim myp As New myproc("cmd.exe", "/C Dir e:\")
myp.Start()

Figure 2 Imports System.Diagnostics

Imports System.Diagnostics
 
Public Class myproc
    Public WithEvents p As System.Diagnostics.Process

    Public Sub New(ByVal ExeName As String, ByVal params As String)
        p = New System.Diagnostics.Process()
        p.StartInfo.FileName = ExeName
        p.StartInfo.Arguments = params
        p.StartInfo.UseShellExecute = False
        p.StartInfo.RedirectStandardOutput = True
        p.EnableRaisingEvents = True
 
        ' Handle the Exited event that the Process class fires.
        AddHandler p.Exited, AddressOf p_Exited
    End Sub
 
    Public Sub Start()
        p.Start()
        p.WaitForExit()
    End Sub
 
    Public Sub p_Exited(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim output As String
        output = p.StandardOutput.ReadToEnd()
        HttpContext.Current.Response.Write(output)
    End Sub
End Class

 

When the process finishes executing, the Exited event will be raised and the standard output of the process will be written to the response stream for the current request.

Got a question? Send questions and comments to  webqa@microsoft.com.

Thanks to the following Microsoft developers for their technical expertise: Dimitri Artemov, Greg Bybee, Todd Carter, Jim Cheshire, Alex Chiang, Jeff Davis, Tamer Demir, Peter Foote, Andrew Goodsell, Robert Gruen, William Li, Eric Lippert, David Lovell, Will Martin, Herbert Mauerer, Jose Tomas Montelongo, David Qiu, Brian Roder, Zack Runner, Angel Saenz-Badillos, Luis Salazar, Ken Stanfield, Uma Subramanian, Stephen Toub, Michael Whalen, and Parker Zhang.