Here is a very nice list with the main differences between WPF and XBAP.
Contract between ASPX and ASCX
In the last versions of ASP.NET where not exist the compilation equals ASP.NET 2.0, easily we can invoke an ASPX method inside an User Control (ASCX), casting Page property to a Page type that would be a container but, this can cause a problem when an ASPX not provides a respective method.
With a new compilation in ASP.NET 2.0, it's dificult casting to a Page type because the name is resolved in compilation-time, so, in design-time we don't know this type. If you aren't using the Web Application Project (WAP) and want invoke a Page's method, you will need to create a contract through Interface. This Interface should be only implemented in ASPX where you want the User Control invoke a method. Below is an example:
public interface IConnection
{
void ExecuteProcedure();
}
public partial class _Default : System.Web.UI.Page, IConnection
public partial class Default2 : System.Web.UI.Page
[ ASCX ]
IConnection connection = this.Page as IConnection;
if (connection != null)
connection.ExecuteProcedure();
else
Response.Write("The Page container isn't a IConnection type!");
How you can note, the Default.aspx Page implements a Interface IConnection and Default2.aspx doesn't. Finally, inside an User Control, casting the Page Property to IConnection through as operator that, if isn't a compatible type, it will return null. If you have been using Visual Basic 2005, use the TryCast operator instead.
A typical WTF :)
Public Sub New(ByVal str As String)
If (str = String.Empty Or str = Nothing Or String.IsNullOrEmpty(str) Or Len(str) = 0) Then
str = ""
End If
Me._str = str
End Sub
Reading my blog list, I found a great post where the author show how to install Visual Studio .NET 2005 templates for WPF/E. Look the installation details, because it requires additional add-ins.
Finishing reading the Luis Abreu´s book, in last chapter he speaks about the page life-cycle and I remembered of performance detail that we can use in ASP.NET applications around HttpModules and I implemented it in Projetando.NET website.
In machine.config file there is a section called httpModules where we have several modules that, for default, are related and will be performed during request; here is some examples: OutputCache, Session, FormsAuthentication, etc. But, in some applications, these modules aren't used and, in this case, we can remove them of the application through the following Web.Config configuration:
<httpModules>
<remove name="Session" />
<remove name="WindowsAuthentication" />
<remove name="FormsAuthentication" />
<remove name="PassportAuthentication" />
<remove name="UrlAuthorization" />
<remove name="FileAuthorization" />
</httpModules>
The BCL Team work in a new type collection called (temporary) HashSet that is a collection containing unique elements. Your own Add method returns a boolean value indicating if item was added or not.
While we haven't this collection, you can use Wintellect's PowerCollections.Set<T>.
In ASP.NET application or any application, is common to verify if the user has permission for a resource, like page, button, command, etc. In last days, I received an e-mail where a guy had performance problems.
In his page, there is a delete button in each line of GridView control. So, in RowDataBound event, he checks if the current user is in a specific role or not. But the problem is that he calls the IsUserInRole method for each line/record. In hundreds of lines/records in GridView, this method will always be called and, for each call, all code in this method will be performed. The example is showed below:
[ The old RowDataBound event ]
if(e.Row.RowType == DataControlRowType.DataRow) {
e.Row.FindControl(“btnDelete”).Visible = Roles.IsUserInRole(“Administrator”);
}
[ The new RowDataBound event ]
private bool _isInAdministratorRole;
//….
this._isInAdministratorRole = Roles.IsUserInRole(“Administrator”);
//….
if(e.Row.RowType == DataControlRowType.DataRow) {
e.Row.FindControl(“btnDelete”).Visible = this._isInAdministratorRole;
}
Small techniques like this can improve the application performance. “Caching code” is explained in Code Complete Book - Second Edition, at Chapter 26, pages 628 and 629.
There are other techniques related with roles in ASP.NET WebApplication. These techniques allow role caching in client cookies through cacheRolesInCookie attribute. It prevents in each request, to make a new query in database (or other repository), to find specific roles for current logged user and attach in HttpContext object.
Caching roles in client-side cookies can improve the performance if your application has a slow data access or a large number of roles. But this technique has security problems and you need to be careful:
- Persistent authorization cookies will be stored in a user's profile and can be stolen if an attacker gets physical access to the machine. This will also help prevent problems for users who access your application from public or shared machines and forget to log out.
- Sending cookies out exclusively over SSL makes it much harder for an attacker to sniff the cookie values off the wire. If an attacker can get a copy of an authorization cookie, they can potentially emulate that role, allowing them to elevate their privilege in the system.
If caching of roles in client-side is necessary, so enable the cookieRequireSSL attribute in roleManager element for security reasons. But, SSL requires a certificate (if you don’t have, it’s necessary to buy it) and performance can be harmed. It’s very important to analyze the scenario and adopt the better strategy.
Many people ask me how they can change or add a new connectionstring in Web.Config's connectionstring section. Basically you only need import the System.Web.Configuration namespace, open the Web.Config file where is connectionstrings section and change or add a new connectionstring. An example is:
Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~");
ConnectionStringsSection dbConnString = webConfig.ConnectionStrings;
//Changing
dbConnString.ConnectionStrings["DBOrders"].ConnectionString = "YOUR NEW CONNSTRING HERE";
//Adding
dbConnString.ConnectionStrings.Add(
new ConnectionStringSettings("MDBTest", "MDB ConnString", "System.Data.OleDb"));
webConfig.Save();
Those that already worked with Client-Side Callbacks know that when add the reference in control client events; we can to define an error client function that will be gone off if the server-side method throws an exception.
So, there is a problem in this scene: if the server-side method throws an exception and the mode attribute of customErrors section will be with On or RemoteOnly (this is default), your callback never work correctly and the following message will pass as argument for the error client function:
There was an error in the callback.
This error occurs when an exception is throwing, the page is changed and customErrors intercept the process, so the above message is returned for client instead Exception message.
If you define the customErrors as Off, the process will work, but depending of your error handling strategy, this configuration will be able to disclose important details about the error, because it displays for all clients. To resolve this, maybe it’s necessary isolate the page that use the callback in a different directory, add a new Web.Config file, override the customErrors section to Off and involve page’s code in Try.Catch.Finally statement.
I'm working at ASP.NET Web Application project and I created a handler, that obviously implement an IHttpHandler Interface, for process and generate a binary file to force a download it.
After config the Web.Config file, the request for "*.abc" file extension will be now intercepted for this handler. But, there is a big problem here, because I'm using the Server.Transfer method, so I cannot send a handler instance for overload of this method or call the "virtual path" directly, like "Page.abc". You can confirm this information decompiling the Transfer method using the Reflector tool:
[ --- Supress --- ]
else if (!(handler is Page))
{
error = new HttpException(0x194, string.Empty);
}
[ --- Supress --- ]
if (error != null)
{
[ --- Supress --- ]
throw new HttpException(SR.GetString("Error_executing_child_request_for_handler",
new object[] { handler.GetType().ToString() }), error);
}
Independently of Transfer method overload that you use, the error message is the same: "Error executing child request for [handler | Page.abc].". So, the reason why I cannot use the Response.Redirect is that I need to send parameters through Context.Items collection for security intentions.
The temporary solution is to inherit the Page class instead implements IHttpHandler Interface in my handler, but I believe that "solution" isn't elegant.
More Posts
Next page »