Entries Tagged 'ASP.NET' ↓

CheckBoxList Select All or None Checkboxes

Here is an very easy client-side javascript to check or uncheck all your checkboxes from your CheckBoxList at once:

<script language="javascript" type="text/javascript">function Select(Select){
for (var n=0; n < document.forms[0].length; n++) if (document.forms[0].elements[n].type==’checkbox’)
document.forms[0].elements[n].checked=Select; return false; }</script>
Select <a href="#" onclick="javascript:Select(true)">All</a> | <a href="#" onclick="javascript:Select(false)">None</a>

Just put it at the top of your ASP.NET page and you’re set. It won’t get any easier than that 😉

Access Denied to a Folder created by ASP.NET on Vista

A pretty simple piece of code drove me into hell lately:

  270 if (!System.IO.Directory.Exists(Server.MapPath(“GamePics\\” + CatName + “\\” + URL)))

  271         {

  272             System.IO.Directory.CreateDirectory(Server.MapPath(“GamePics\\” + CatName + “\\” + URL));           

  273         }

Nothing special in fact. However, if you run Windows Vista this could result into a serious problem. The problem only occurs if the folders (in this case) “CatName” and “URL” didn’t exist before. Meaning, ASP.NET creates the CatName folder AND the URL folder in one go.

If that happens, you won’t have any access to the “URL” Folder – meaning the secondly created folder. You will not be able to delete or access it as it doesn’t have an owner and you will not be able to set an owner either.

I was able to get rid of the folder by logging into the Vista Administrator Account (you have to enable it first). I browsed to the location and the folder was already gone by then, maybe a restart will fix this problem, too.

A workaround:

– Never create more than one folder at the same time in one line.
– Create one folder and then make a seperate System.IO.File.Create call to create the second folder.

In my case this didn’t fire up the Access denied problem. I hope this post will help people facing the same weird problem someday.

Increase ASP.NET Authentication / Membership-Cookie Timeout

The default forms authentication timeout value is set on 30 minutes. Increasing the ASP.NET Membership-Cookie Timeout is most easily possible by setting the timeout attribute in the web.config:

<authentication mode="Forms">
<forms name="ApplicationLogin" loginUrl="Login.aspx" path="/" protection="All" timeout="10080">
</forms>

timeout=”10080″ is meassured in minutes, meaning we got a timeout of 10080 minutes here.

If you don’t want to set the forms timeout value that high you have to give up on the standard login controls supplied with ASP.NET 2.0. Here’s what you have to do:

1) Create a custom Login Page aka Login.aspx, this is just an example:

    4     <asp:Panel ID=”Panel1″ runat=”server” DefaultButton=”Button1″>

    5     <div align=”center”>

    6 User: <br />

    7     <asp:TextBox ID=”TextUser” runat=”server”></asp:TextBox>

    8 <br />

    9 Password:<br />

   10 <asp:TextBox ID=”TextPass” runat=”server” TextMode=”Password”></asp:TextBox>

   11 <br />

   12     <asp:CheckBox ID=”CheckBox1″ runat=”server” Checked=”True” />

   13     <asp:Button ID=”Button1″ runat=”server” Text=”Login” OnClick=”Button1_Click” /><br /><br />

   14     <asp:Literal ID=”Literal1″ runat=”server”></asp:Literal>

   15 </div>

   16 </asp:Panel>

2) Create a new class auth.cs and add the following:

   43     public static bool CheckLogins(string UserName, string Password)

   44     {

   45         if (Membership.ValidateUser(UserName, Password))

   46         {

   47             return true;

   48         }

   49         else

   50         {

   51             return false;

   52         }

   53 

   54         return false;

   55     }

   75     public static bool CreateTicket(string UserName, bool StayLoggedIn, string Type, DateTime CookieTime)

   76     {

   77         FormsAuthentication.Initialize();

   78 

   79         // Create a new ticket used for authentication

   80         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, UserName, DateTime.Now, CookieTime, StayLoggedIn, Type, FormsAuthentication.FormsCookiePath);

   81 

   82         string hash = FormsAuthentication.Encrypt(ticket);

   83         HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);

   84 

   85         if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;

   86 

   87         HttpContext.Current.Response.Cookies.Add(cookie);

   88 

   89         return true;

   90     }

3) Now insert this into the button click event routine of Login.aspx:

   43 public static bool CheckLogins(string UserName, string Password)

   44     {

   45         if (auth.CheckLogins(TextUser.Text, TextPass.Text))

   46         {

   47             auth.CreateTicket(TextUser.Text, CheckBox1.Checked, “Regged”, DateTime.Now.AddDays(350));

   48         }

   49     }

Note: “Regged” indicates the UserRole in this case. You just added a Cookie with a timeout of 350 days now. This was just a rough example, of course you still have to add some kind of notice if the login failed and so on.

WPF/E Video

Lester made a sweet WPF/E video carousel which looks pretty nice:

You can download the code on his blog: WPF/E video carousel

Show ASP.NET Membership Online Users

There are several ways to show who is currently online within your ASP.NET Application if you use the build in Membership Provider. I tested a few on performance and accuary which lead me to the following conclusion:

Using a stored procedure on LastActivityDate is the winner.

Here is how I did it, create this stored procedure:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
— =============================================
— Author: Andreas Kraus
— Create date: 2007-03-27
— Description: Who Is Online Box
— =============================================
CREATE PROCEDURE [dbo].[xx_WhoIsOnline]
@TimeWindow DATETIME
AS
BEGIN
— SET NOCOUNT ON added to prevent extra result sets from
— interfering with SELECT statements.
SET NOCOUNT ON;

— Insert statements for procedure here
SELECT UserName FROM aspnet_Users
WHERE IsAnonymous = ‘FALSE’ AND LastActivityDate > @TimeWindow
END
GO

and create a custom ASP.NET Control featuring this code:

   18         cn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[“LocalSqlServer”].ConnectionString);

   19 

   20         SqlCommand cmd = new SqlCommand();

   21         SqlDataReader dr;

   22 

   23         DateTime TimeWindow = DateTime.Now;

   24         TimeSpan TimeSpanWindow = new TimeSpan(0, 10, 0);

   25         TimeWindow = TimeWindow.Subtract(TimeSpanWindow);

   26 

   27         cmd.Connection = cn;

   28         cmd.CommandText = “battle_WhoIsOnline”;

   29         cmd.Parameters.AddWithValue(“@TimeWindow”, TimeWindow);       

   30         cmd.CommandType = System.Data.CommandType.StoredProcedure;

   31 

   32         cn.Open();

   33         dr = cmd.ExecuteReader();

   34 

   35         System.Text.StringBuilder sb = new System.Text.StringBuilder();

   36         while (dr.Read())

   37         {

   38             sb.Append(dr[“UserName”].ToString());           

   39         }       

   40         dr.Close();

   41         cn.Close();

   42 

   43         if (sb.Length > 0)

   44         {

   45             sb.Remove(sb.Length – 2, 2);

   46         }

   47 

   48         Literal1.Text = sb.ToString();

Include the control on any .aspx page and you are set.

ASP.NET 2.0 aka System.Net.Mail with GMail

We recently dropped one of our commercial libraries, the Rebex.Net.Mail Tool. Instead we are using the build in System.NET.Mail Class from ASP.NET 2.0. In ASP.NET 1.1 you were able to use the System.Web.Mail Class and you were able to send mail via GMail by adding those filters:

 

ASP.NET v1.1:

            SmtpClient smtp = new SmtpClient();
            smtp.Host = "smtp.gmail.com";
            // - smtp.gmail.com use smtp authentication
            mailMsg.Filters.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
            mailMsg.Filters.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "xx");
            mailMsg.Filters.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "xx");
            // - smtp.gmail.com use port 465 or 587
            mailMsg.FiltersAdd("http://schemas.microsoft.com/cdo/configuration/smtpserverport", "465");
            // - smtp.gmail.com use STARTTLS (some call this SSL)
            mailMsg.Filters.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "true");
            // try to send Mail

As I switched to the new ASP.NET 2.0 System.Net.Mail class the filters function was gone. Important: mailMsg.Headers.Add in the new class is not the equivalent class to that Filters.Add method, that’s what I thought, too, in the beginning.

In fact it got much easier now, but totally different:

ASP.NET v2.0:

 // Smtp configuration
        SmtpClient smtp = new SmtpClient();
        smtp.Host = "smtp.gmail.com";

        smtp.Credentials = new System.Net.NetworkCredential("xx", "xx");
        smtp.EnableSsl = true;   

I’d love to have more specific documentations on those changes, but thanks to Microsoft for making our code smaller once again ;).

Update LastActivityDate in aspnet_Users with Cookie Authentication

In case you are using the ASP.NET Membership Provider you probably noticed that LastActivityDate doesn’t update correctly whenever someone checked Remember me on his Login. I got a site running with a Cookie timeout of 10080 seconds, a pretty long time. I need to have an accurate LastActivityDate because I want to display whenever a user has actually been active.

So what now? I want to stick to my cookie timeout value and need to update the LastActivityDate manually. Here’s my approach (I love stored procedures).

First create a stored Procedure:

   31 set ANSI_NULLS ON

   32 set QUOTED_IDENTIFIER OFF

   33 GO

   34 — =============================================

   35 — Author:        Andreas Kraus (http:/www.andreas-kraus.net/blog)

   36 — Create date: 2007-02-10

   37 — Description:    Updates LastActivityDate

   38 — =============================================

   39 ALTER PROCEDURE [dbo].[aspnet_Membership_UpdateLastActivityDate]   

   40     @UserName            nvarchar(256),

   41     @LastActivityDate    datetime

   42 

   43 AS

   44 BEGIN

   45     IF (@UserName IS NULL)

   46     RETURN(1)

   47 

   48     IF (@LastActivityDate IS NULL)

   49     RETURN(1)

   50 

   51     UPDATE dbo.aspnet_Users WITH (ROWLOCK)

   52     SET

   53         LastActivityDate = @LastActivityDate

   54     WHERE

   55        @UserName = UserName

   56 END

Then use this code in your global.asax by hitting the Application_AuthenticateRequest Event:

   31     void Application_AuthenticateRequest(object sender, EventArgs e)

   32     {

   33         if (User.Identity.IsAuthenticated)

   34         {

   35             System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[“LocalSqlServer”].ConnectionString);

   36             System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();

   37             cmd.Connection = cn;

   38             cmd.CommandText = “aspnet_Membership_UpdateLastActivityDate”;

   39             cmd.Parameters.AddWithValue(“@UserName “, User.Identity.Name);

   40             cmd.Parameters.AddWithValue(“@LastActivityDate”, DateTime.Now);

   41             cmd.CommandType = System.Data.CommandType.StoredProcedure;

   42             cn.Open();

   43             cmd.ExecuteNonQuery();

   44             cn.Close();

   45         }

   46     }

That’s it, now you have a most accurate LastActivityDate value to work with.

ASP.NET Deployment Tool v1.9

Version 1.9 adds a little requested feature to my ASP.NET Deployment Tool. Whenever you hit Deploy Local a file called compilerlog.txt will be created now in the Application Folder which holds the compiler output.

So if you got lots of warnings and errors popping up it’s easier to investigate them by looking into compilerlog.txt. Of course using Visual Studio is still best for investigation but it appeared that many people do small fixes without firing up VS once again.

“Bin” is checked by default now: It only copies the content of the bin directory when you hit Copy to FTP.

Short overview for people who don’t know it yet:

An avanced and robust Deployment Tool for precompiling your ASP.NET Websites! Pre-Compilation gives your site a performance boost and secures it.

Precompile and deploy your Website: Specific Error Panel, FTP Support, Deploy to Network, Merge Assemblies, easy to use.

Download it here: ASP.NET Deployment Tool v1.9 (I didn’t update the version number on that page yet, don’t mind it, it’s v1.9)

Edit: I set the background color of the Toolstrip to a static color as many people use black for their desktops 🙂

ASP.NET Paging

I’ve dealt with custom ASP.NET Paging lately and wanted to share the fastest possible way to do that with you if you don’t use ADO.NET or any ASP.NET Controls.

Create a stored Procedure like this:

CREATE PROCEDURE [dbo].[usp_PageResults_NAI]
(
@startRowIndex int,
@maximumRows int
)
AS

DECLARE @first_id int, @startRow int

— A check can be added to make sure @startRowIndex isn’t > count(1)
— from employees before doing any actual work unless it is guaranteed
— the caller won’t do that

— Get the first employeeID for our page of records
SET ROWCOUNT @startRowIndex
SELECT @first_id = employeeID FROM employees ORDER BY employeeid

— Now, set the row count to MaximumRows and get
— all records >= @first_id
SET ROWCOUNT @maximumRows

SELECT e.*, d.name as DepartmentName
FROM employees e
INNER JOIN Departments D ON
e.DepartmentID = d.DepartmentID
WHERE employeeid >= @first_id
ORDER BY e.EmployeeID

SET ROWCOUNT 0

GO

And in ASP.NET you execute a DataReader against this piece of code:

   42         string SQL = “pics_Paging”;

   43 

   44         cmd.Connection = cn;

   45         cmd.CommandText = SQL;

   46         cmd.Parameters.AddWithValue(“@startRowIndex”, 6);

   47         cmd.Parameters.AddWithValue(“@maximumRows”, 4);

   48         cmd.CommandType = System.Data.CommandType.StoredProcedure;

That’s all and it’s pretty speedy, thanks to 4GuysFromRolla.com for the input! All you have to do now is to create the logic for startRowIndex and maximumRows which is a piece of cake 😉

ASP.NET: Secure and Low-Privileged File Operations

Hosting in a basic configuration can be a developer’s pain when it comes to file operations. Usually the webspace doesn’t allow files to be created which has a good reason in that configuration, though.

A very smart way to deal with that is to use Isolated Storages. That way all the files are saved in a virtual storage which also means that you can control the access level which is pretending conflicts with other applications. That’s how it could look like:

  176         // Filestore init

  177         IsolatedStorageFile isoStore = IsolatedStoargeFile.GetStore(IsolatedStorageScope.Assembly | IsolatedStorageScope.User, null, null);

  178 

  179         // Create dir

  180         isoStore.CreateDirectory(“myAppData”);

  181         isoStore.CreateDirectory(“myAppData/settings”);

  182 

  183         // Write File into Store

  184         IsolatedStoargeFileStream isoStream1 = new IsolatedStorageFileStream(“myAppdData/hello.txt”, System.IO.FileMode.Create, isoStore);

  185         byte[] content = Encoding.UTF8.GetBytes(“Hello!”);

  186         isoStream1.Write(content, 0, content.Length);

  187 

  188         // Read file

  189         IsolatedStorageFileStream isoStream2 = new IsolatedStorageFileStream(“myAppData/hello.txt”, System.IO.FileMode.Open, isoStore);

  190         byte[] content2 = new byte[isoStream2.Length];

  191         isoStream2.Read(content2, 0, content2.Length);

  192         isoStream2.Close();

  193 

  194         Response.Write(Encoding.UTF8.GetString(content2));

  195 

  196         // delete store

  197         isoStore.Remove();

That’s all, a pretty clean approach for dealing with files in ASP.NET due to hosting restrictions. Nevertheless it’s also interesting to use in Desktop Applications due to the customized privileges for that storage.

AJAX: Element ScriptManager is not a known element

If you moved from ATLAS to the new ASP.NET AJAX Beta1 you might encounter that kind of problem, all other controls are affected as well like Element ‘UpdatePanel’ is not a known element.

To get around this issue you have to change the tagPrefix in your web.config:
Old:

   <controls>
          <add tagPrefix="asp" namespace="Microsoft.Web.UI"
 assembly="Microsoft.Web.Extensions, Version=1.0.61025.0,
 Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
          <add tagPrefix="asp" namespace="Microsoft.Web.UI.Controls" 
assembly="Microsoft.Web.Extensions, Version=1.0.61025.0, 
Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        </controls>

New:

   <controls>
          <add tagPrefix="ajax" namespace="Microsoft.Web.UI" 
assembly="Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
 PublicKeyToken=31bf3856ad364e35"/>
          <add tagPrefix="ajax" namespace="Microsoft.Web.UI.Controls"
 assembly="Microsoft.Web.Extensions, Version=1.0.61025.0,
 Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        </controls>

This works as a temporary fix, this issue will be addressed in the next release of ASP.NET AJAX Beta.

hth

ASP.NET Performance through early binding

Microsoft said, ASP.NET applications contain 40 to 70 percent less code than ASP `applications`. My little test shows that it’s true, ASP.NET is really faster. However, an exact statement on speed is difficult because it’s depending on many factors.

The point of success isn’t the compiling but the early binding. That can be shown in an easy loop. I’ve used a Dual AMD Opteron, 2GHZ, 4GB RAM on Windows 2003 Server / IIS 6.0 for that test, here’s the code:

In ASP:

<%
Dim b, a, start, end, count
count = 50000000
Response.Write("Loops: " & count & "<hr>")
start = now
for a = 1 to count
b = b + a
next
end = now
Response.Write("Start: " & start & "<br>")
Response.Write("End: " & end & "<br>")
Response.Write("Execution length: " & DateDiff("s",start,end))
%>

In ASP.NET 2.0 with late binding:

private void Page_Load(object sender, System.EventArgs e)
{
object b = null;
object a = null;
object start = null;
object end = null;
object count = null;
count = 50000000;
Response.Write("Loops: " + count.ToString() + "<hr");
start = DateTime.Now;
object tempFor1 = ;
for (a = 1; a <= count; a++)
{
b = b + a;
}
end = DateTime.Now;
Response.Write("Start: " + start.ToString() + "<br>");
Response.Write("End: " + end.ToString() + "<br>");
Response.Write("Execution length:
 " +  Microsoft.VisualBasic.DateAndTime.DateDiff("s", start,
 end, Microsoft.VisualBasic.FirstDayOfWeek.Sunday,
 Microsoft.VisualBasic.FirstWeekOfYear.Jan1));
}

And now in ASP.NET 2.0 with early binding:

Same like above but:
Int64 b, Int64 a, DateTime start;
DateTime end;
Int64 count;

Here are the results:

  • The ASP Code: 26 seconds
  • The ASP.NET 2.0 Code with late binding: 16 seconds
  • The ASP.NET 2.0 Code with early binding: < 1 second!

The result speaks for itself.

kick it on DotNetKicks.com

Atlas goes ASP.NET AJAX

Too bad. Microsoft said goodbye to Atlas and comes up with a *new* framework called ASP.NET AJAX. There are lots of new features and bugfixes within that beta release which comes in 3 pars:

  • The ASP.NET AJAX v1.0 “Core” download. This redist contains the features that will be fully supported by Microsoft Product Support, and which will have a standard 10 year Microsoft support license (24 hours a day, 7 days a week, 365 days a year). The download includes support for the core AJAX type-system, networking stack, component model, extender base classes, and the server-side functionality to integrate within ASP.NET (including the super-popular ScriptManager, UpdatePanel, and Timer controls).
  • The ASP.NET AJAX “Value-Add” CTP download. This redist contains the additional higher-level features that were in previous CTPs of “Atlas,” but which won’t be in the fully-supported 1.0 “core” redist. These features will continue to be community supported as we refine them further and incorporate more feedback. Over time we’ll continue to move features into the “core” download as we finalize features in this value-add package more.
  • The ASP.NET AJAX Control Toolkit. This project contains 28 free, really cool, AJAX-enabled controls that are built on top of the ASP.NET AJAX 1.0 “Core” download. The project is collaborative shared source and built by a combination of Microsoft and non-Microsoft developers, and you can join the community or just download it on CodePlex today.

Sounds nice but the thing which makes me a little bit angry is.. the old Atlas code has to be migrated. It took me about 5 hours to migrate four of my existing ASP.NET Atlas applications. Here’s the migration guide: Atlas Migration guide.

Let’s hope we’re working with somewhat more stable bits now, ASP.NET Ajax.

Red Gate SQL Refactor Beta released

Red-Gate released a fantastic SQL Refactor Tool which helps you refactoring that horrible SQL Code you have to deal with on a daily basis.

SQL Refactor is an Add-In to Microsoft Management Studio. Therefore you must have Management Studio installed. SQL Refactor’s features are available from the Management Studio menus, which can access both SQL Server 2000 and SQL Server 2005. In this release of SQL Refactor you can use the following features:

  • SQL Lay Out reformats your T-SQL scripts. You can select this feature from the top level SQL Refactor menu. There are over 30 options to control this feature, these you can access from the top level SQL Refactor menu.
  • Smart Rename renames functions, views, stored procedures and tables, and updates all the references to these renamed objects. You can select this feature from the context menu in Management Studio’s Object Explorer.
  • Smart Rename parameters and columns renames parameters of stored procedures and functions, and columns of tables and views. You can select this feature from the context menu in Management Studio’s Object Explorer.
  • Table Split splits a table into two tables, and automatically rewrites the referencing stored procedures, views, and so on. You can also use this refactoring to introduce referential integrity tables. You can select this feature from the context menu in Management Studio’s Object Explorer.
  • Uppercase keywords turns keywords in your script or selection to uppercase.
  • Summarize Script provides you with an overview of your script. By highlighting items in this overview you can see the corresponding statements highlighted in your script.
  • Encapsulate as stored procedure turns your selection into a new stored procedure, and if requested, introduces a reference to it in your script.
  • Expand wildcards expands SELECT * statements to include a full list of columns in the select part.
  • Find unused variables and parameters shows you the variables and parameters in you script that are not used, or that are only assigned to.
  • Qualify Object Names modifies the script so that all object names are qualified. You can select this feature from the top level SQL Refactor menu.

Download it here: ftp://ftp.red-gate.com/sqlrefactorbeta/sqlrefactorsetup.exe

Great Job!

ASP.NET: Update one table from another

Here’s how to update one table by selecting the values from another:

UPDATE C
SET C.Phone = O.[Tel],
C.Fax = O.[Fax]
FROM output$ O
          JOIN Contacts C
                   ON C.MemberId = O.MemberId

Maybe this saves someone time..