Do ASP.NET forms authentication cookies provide any protection against replay attacks? Do they, for example, include the client's IP address or anything else that would distinguish the real client from an attacker?
No. If an authentication cookie is stolen, it can be used by an attacker. It's up to you to prevent this from happening by using an encrypted communications channel (HTTPS). Authentication cookies issued as session cookies, do, however, include a time-out valid that limits their lifetime. So a stolen session cookie can only be used in replay attacks as long as the ticket inside the cookie is valid. The default time-out interval is 30 minutes. You can change that by modifying the timeout attribute accompanying the
By default, a persistent forms authentication cookie issued by ASP.NET is valid for 50 years. Is it possible to shorten that?
Yes. Unfortunately, there is no configuration setting you can tweak to customize the lifetime of a persistent authentication cookie, but you can customize it programmatically. Here's a snippet of code that returns a persistent authentication cookie from a forms login page and limits the cookie's lifetime to 7 days:
string url = FormsAuthentication.GetRedirectUrl ("Elmo", true);
FormsAuthentication.SetAuthCookie ("Elmo", true);
HttpCookie cookie = Response.Cookies[FormsAuthentication.FormsCookieName];
cookie.Expires = DateTime.Now + new TimeSpan (7, 0, 0, 0);
Response.Redirect (url);
To set the cookie's lifetime to something other than 7 days, simply modify the TimeSpan value.
I wrote an HTTP handler and registered it in the
In addition to being mapped to a file type (or specific file name) in a CONFIG file, an HTTP handler has to be registered in the IIS metabase. For example, if you register an HTTP handler with the Web.config file shown below, you also have to map *.igen to Aspnet_isapi.dll in the IIS metabase. Otherwise, ASP.NET doesn't see the request and can't forward it to the handler.
MailMessage message = new MailMessage ();
message.From = "webmaster@wintellect.com";
message.To = "Everyone@wintellect.com";
message.Subject = "Scheduled Power Outage";
message.Body = "Our servers will be down tonight.";
SmtpMail.SmtpServer = "localhost";
SmtpMail.Send (message);
MailMessage and SmtpMail are classes defined in the .NET Framework Class Library's System.Web.Mail namespace. Due to a security change made to ASP.NET just before it shipped, you need to set SmtpMail's SmtpServer property to "localhost" even though "localhost" is the default. In addition, you must use the IIS configuration applet to enable localhost (127.0.0.1) to relay messages through the local SMTP service.
How do I read an image from a database using ADO.NET and display it in a Web page?
The following ASPX file reads and displays an image from the Pubs database that comes with Microsoft SQL Server.
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.IO" %>
Some Web service classes derive from System.Web.WebServices; others do not. What's the deal?
WebService contributes properties named Application, Session, Context, Server, and User to derived classes enabling Web services to access the ASP.NET objects of the same name. If you don't use these objects in your Web service-for example, if you don't use application state or session state-then you don't have to derive from WebService, either. Incidentally, if you want to use ASP.NET session state in a Web method, use the following WebMethod attribute to enable session state for that method:
[WebMethod (EnableSession="true")]
What are VSDISCO files?
VSDISCO files are DISCO files that support dynamic discovery of Web services. If you place the following VSDISCO file in a directory on your Web server, for example, it returns references to all ASMX and DISCO files in the host directory and any subdirectories not noted in
Note that VSDISCO files are disabled in the release version of ASP.NET. You can reenable them by uncommenting the line in the
How does a Web service client call Web methods asynchronously?
Web service proxy classes generated by Wsdl.exe contain asynchronous as well as synchronous versions of the Web service's methods. Suppose a Web service implements the following Add method:
[WebMethod]
public int Add (int a, int b)
{
return a + b;
}
A proxy generated by Wsdl.exe has BeginAdd and EndAdd methods for calling Add asynchronously. Assuming calc is an instance of the proxy class, here's how a client calls Add asynchronously:
// Initiate an async call
IAsyncResult res = calc.BeginAdd (2, 2, null, null);
.
.
.
// Get the results
int sum = calc.EndAdd (res);
If the call hasn't completed when EndAdd is called, EndAdd blocks until it does. If desired, a client can ask to be notified when an asynchronous call returns by providing a reference to an AsyncCallback delegate wrapping a callback method. In the next example, EndAdd won't block because it isn't called until the client is certain the method call has returned:
AsyncCallback cb = new
AsyncCallback (AddCompleted);
IAsyncResult res = calc.BeginAdd (2, 2, cb, null);
.
.
.
public void AddCompleted (IAsyncResult res)
{
int sum = calc.EndAdd (res);
}
Another option is to use the IsCompleted property of the IAsyncResult interface returned by BeginAdd to determine whether the call has completed and avoid calling EndAdd until it does:
IAsyncResult res = calc.BeginAdd (2, 2, null, null);
.
.
.
if (res.IsCompleted) {
int sum = calc.EndAdd (res);
}
else {
// Try again later
}
I wrote code that uses the SmtpMail and MailMessage classes to send e-mail from an ASP.NET application. The code worked fine in beta 2, but it throws an exception in the release version of ASP.NET. What's wrong?
Please see FAQ "How do I send e-mail from an ASP.NET application?" (http://www.wintellect.com/resources/faqs/default.aspx?faq_id=1&page=4#4)
How do I upload files to Web pages in ASP.NET?
Use the HtmlInputFile class, which you can declare an instance of with an tag. The following example is a complete ASPX file that lets a user upload an image file and a comment descibing the image. The OnUpload method writes the image and the comment to a table named Pictures in a SQL Server database named MyPictures.
<%@ Import Namespace="System.Data.SqlClient" %>
Top of Form
File name
|
Comment
|
|
How do I create an ASPX page that periodically refreshes itself?
Most browsers recognize the following
Here's an ASPX file that displays the current time of day. Once displayed, it automatically refreshes every 5 seconds:
<%@ Page Language="C#" %>
<% Response.Write (DateTime.Now.ToLongTimeString ()); %>
How can an ASP.NET application determine whether cookies are enabled in a browser?
Determining whether cookies are enabled requires a round trip to the browser and back. If you can live with an extra round trip, the basic strategy is to return a cookie in an HTTP response and redirect to a page that checks for the cookie. Here's a page that does just that:
And here's the page that it redirects to (OtherPage.aspx). This page uses the presence or absence of the cookie to determine whether cookies are enabled and displays the result:
<%@ Page Language="C#" %>
<% HttpCookie cookie = Request.Cookies["Foo"]; if (cookie != null && cookie.Value == "Bar") Response.Write ("Cookies are enabled"); else Response.Write ("Cookies are not enabled"); %>
Is it possible to prevent a browser from caching an ASPX page?
You bet. Just call SetNoStore on the HttpCachePolicy object exposed through the Response object's Cache property, as demonstrated here:
<%@ Page Language="C#" %>
<% Response.Cache.SetNoStore (); Response.Write (DateTime.Now.ToLongTimeString ()); %>
SetNoStore works by returning a Cache-Control: private, no-store header in the HTTP response. In this example, it prevents caching of a Web page that shows the current time.
How do I create a DataGrid with Delete buttons and pop up a message box asking the user for confirmation before deleting a record?
The ASPX file below demonstrates the proper technique. It populates a DataGrid with content from the Titles table of the Pubs database that comes with Microsoft SQL Server. The DataGrid's leftmost column contains a row of Delete buttons. The OnDeleteRecord method simulates a record deletion by writing the Title field of the record to be deleted to a Label control. The OnAttachScript method, which is called once for each row in the DataGrid in response to ItemCreated events, attaches to each button an OnClick attribute that activates a bit of client-side JavaScript. That script displays a confirmation dialog and prevents the page from posting back to the server (thus preventing OnDeleteRecord from being called) if the user clicks Cancel rather than OK.
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
How do I localize an ASP.NET application so that it formats dates and times based on the requestor's locale?
Deploy the following Global.asax file in the application's virtual root:
<%@ Import Namespace="System.Threading" %>
<%@ Import Namespace="System.Globalization" %>
Application_BeginRequest executes at the beginning of each and every request. This example reads the requestor's preferred language from the Request object's UserLanguage property (which is populated with information found in the request's Accept-Language header), creates a CultureInfo object from it, and assigns the CultureInfo object to the CurrentCulture property of the thread that's processing the request. FCL methods that are culture-aware (such as DateTime.ToShortDateString) will format dates, times, currency values, and numbers accordingly.
What does AspCompat="true" mean and when should I use it?
AspCompat is an aid in migrating ASP pages to ASPX pages. It defaults to false but should be set to true in any ASPX file that creates apartment-threaded COM objects--that is, COM objects registered ThreadingModel=Apartment. That includes all COM objects written with Visual Basic 6.0. AspCompat should also be set to true (regardless of threading model) if the page creates COM objects that access intrinsic ASP objects such as Request and Response. The following directive sets AspCompat to true:
<%@ Page AspCompat="true" %>
Setting AspCompat to true does two things. First, it makes intrinsic ASP objects available to the COM components by placing unmanaged wrappers around the equivalent ASP.NET objects. Second, it improves the performance of calls that the page places to apartment-threaded COM objects by ensuring that the page (actually, the thread that processes the request for the page) and the COM objects it creates share an apartment. AspCompat="true" forces ASP.NET request threads into single-threaded apartments (STAs). If those threads create COM objects marked ThreadingModel=Apartment, then the objects are created in the same STAs as the threads that created them. Without AspCompat="true," request threads run in a multithreaded apartment (MTA) and each call to an STA-based COM object incurs a performance hit when it's marshaled across apartment boundaries.
Do not set AspCompat to true if your page uses no COM objects or if it uses COM objects that don't access ASP intrinsic objects and that are registered ThreadingModel=Free or ThreadingModel=Both.
I've developed a custom Windows Forms control that I'd like to use in a Web Form. I've heard that ASP.NET can use Windows Forms controls. Is that true? If so, how do I create a Windows Forms control in a Web Form?
You can embed Windows Forms controls in Web pages using
<% Response.Write ("You typed \"" + Request["Input"] + "\""); %>
Another way to pass data from one page to another--a technique that has the added benefit of keeping the data on the server and not exposing it to the user--is to pass the data in session state, as demonstrated here:
<%@ Page Language="C#" %>
<% Response.Write ("You typed \"" + Session["Input"] + "\""); %>
If you use Server.Transfer rather than Response.Redirect to transfer control to another page, you can use public fields in the sending page's code-behind class to transmit data. The following example demonstrates how:
<%@ Page Inherits="PageOneClass" %>
// PageOneClass.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class PageOneClass : Page
{
public string _Input;
protected TextBox Input;
public void OnNextPage (Object sender, EventArgs e)
{
_Input = Input.Text;
Server.Transfer ("PageTwo.aspx");
}
}
<%@ Page Language="C#" %><% PageOneClass prevpage = (PageOneClass) Context.Handler; Response.Write ("You typed \"" + prevpage._Input + "\""); %>
How do I display an ASPX or HTML page in a new browser window in ASP.NET?
The following tag creates a hyperlink that, when clicked, opens an ASPX file in a new window:
How do I initialize a TextBox whose TextMode is "password" with a password? Initializing the TextBox's Text property doesn't seem to work.
This won't work:
But this will:
The latter code fragment manually adds a value="imbatman" attribute to the tag output by the TextBox control, causing the specified text to appear in the TextBox.
You can also initialize a password TextBox by including a Value attribute in the control tag, as demonstrated below:
I know I can write custom server controls by deriving from Control or WebControl. But can I modify the behavior of existing controls by deriving from them and modifying their output?
You bet. Here's a custom control named NumTextBox that derives from TextBox and adds an onkeydown attribute to the tag that TextBox outputs. That attribute references a local JavaScript function that filters out non-numeric keys, producing a TextBox that accepts only numbers. For good measure, NumTextBox senses the browser type and renders differently to Internet Explorer and Netscape Navigator, enabling it to work in either browser. It also overrides TextBox's Text property and implements a set accessor that throws an exception if a non-numeric string is written to it.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Wintellect
{
public class NumTextBox : TextBox
{
string IEClientScriptBlock =
"";
string NetscapeClientScriptBlock =
"";
public override string Text
{
get { return base.Text; }
set
{
// Make sure value is numeric before storing it
Convert.ToInt64 (value);
base.Text = value;
}
}
protected override void OnPreRender (EventArgs e)
{
string browser = Context.Request.Browser.Type.ToUpper ();
int version = Context.Request.Browser.MajorVersion;
if (browser.IndexOf ("IE") > -1 && version >= 4)
Page.RegisterClientScriptBlock ("NumTextBoxScript",
IEClientScriptBlock);
else if (browser.IndexOf ("NETSCAPE") > -1 && version >= 4)
Page.RegisterClientScriptBlock ("NumTextBoxScript",
NetscapeClientScriptBlock);
}
protected override void Render (HtmlTextWriter writer)
{
string browser = Context.Request.Browser.Type.ToUpper ();
int version = Context.Request.Browser.MajorVersion;
if (browser.IndexOf ("IE") > -1 && version >= 4)
writer.AddAttribute ("onkeydown",
"javascript:return isKeyValid (window.event.keyCode)");
else if (browser.IndexOf ("NETSCAPE") > -1 && version >= 4)
writer.AddAttribute ("onkeydown",
"javascript:return isKeyValid (event.which)");
base.Render (writer);
}
}
}
Here's an ASPX file you can use to test the control. It assumes that the control is compiled into an assembly named NumTextBoxControl.
<%@ Register TagPrefix="win" Namespace="Wintellect" Assembly="NumTextBoxControl" %>
Is it possible to associate hidden values--say, values from an identity field in a database table--with items in a DataGrid?
You bet. Just declare a BoundColumn in the DataGrid and set its Visible property to false, like so:
The column won't show up in the DataGrid, but you'll be able to read data from it following a postback just as if it were visible.
How do I configure a DataGrid to show a column of row numbers: 1, 2, 3, 4, and so on?
The easiest way to do it is to use a TemplateColumn. The following ASPX file demonstrates how. The TemplateColumn displays the value of a rownum field that is incremented each time a row is output.
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%# rownum++ %>
Is it possible to call Fill on a DataAdapter and fill two DataTables in a DataSet with a single call?
You bet. Here's a sample that demonstrates how by performing a double query and binding each of the resulting DataTables to a different DataGrid.
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
I'm trying to use Server.CreateObject to instantiate a legacy COM component in an ASPX page. If I use VB.NET, I can create and call the COM object just fine. But the same code written in C# doesn't compile. The compiler complains that the method I'm calling isn't a member of Object. What gives?
You've discovered an interesting feature of VB.NET--namely, that it trades type safety for simplicity when late binding to COM objects. Check out the following VB.NET code sample, which instantiates a COM object (ProgID="Wintellect.Math") and calls its Add method to add 2 and 2:
Dim Sum As Integer
Dim WinMath As Object
WinMath = Server.CreateObject ("Wintellect.Math")
Sum = WinMath.Add (2, 2)
This code works just fine, despite that fact that Add is not a member of System.Object. The VB.NET compiler relaxes its type-checking rules to simplify your code. The C# compiler, however, does not. The following code won't compile:
Object math = Server.CreateObject ("Wintellect.Math")
int sum = WinMath.Add (2, 2)
The solution for C# programmers is to late-bind to the COM object using System.Type.InvokeMember. Here's the C# equivalent of the VB.NET code above:
Type t = Type.GetTypeFromProgID ("Wintellect.Math");
Object math = Server.CreateObject (t);
Object[] args = { 2, 2 };
int sum = (int) t.InvokeMember ("Add", BindingFlags.InvokeMethod, null, math, args);
It's not pretty, but it works, and it perfectly illustrates the extra effort required to accomplish late binding in C#.
I'm trying to use ASP.NET's HtmlInputFile control to upload files to a Web server, but the control's PostedFile property is always null—even after I select a file and post back to the server. What am I doing wrong?
Most likely you forgot to include an enctype="multipart/form-data" attribute in your tag. The following HTML form doesn't support file uploads:
But the next one does. Decorate the tag as shown here and file uploads will work just fine:
No comments:
Post a Comment