Enjoy!
Type type = typeof(StringBuilder); //can be any type
ConstructorInfo ci = type.GetConstructor(new Type [ 0 ]);
Stopwatch watch = new Stopwatch();
watch.Start();
for (Int32 i = 0; i < 100; ++i)
{
StringBuilder obj = Activator.CreateInstance(type) as StringBuilder;
}
Int64 time1 = watch.ElapsedTicks;
watch.Reset();
watch.Start();
for (Int32 i = 0; i < 100; ++i)
{
StringBuilder obj = ci.Invoke(null) as StringBuilder;
}
Int64 time2 = watch.ElapsedTicks;
DynamicMethod m = new DynamicMethod(String.Empty, typeof(Object), null, type, true);
ILGenerator il = m.GetILGenerator();
Func<Object> creator = m.CreateDelegate(typeof(Func<Object>)) as Func<Object>;
il.Emit(OpCodes.Newobj, ci);
il.Emit(OpCodes.Ret);
watch.Reset();
watch.Start();
for (Int32 i = 0; i < 100; ++i)
{
StringBuilder obj = creator() as StringBuilder;
}
Int64 time3 = watch.ElapsedTicks;
Sometimes there is the need to find the control that caused the postback from outside the event handler. The following code gives you just that:
public static class PageExtensions
{
public static Control FindFiredControl(this Page page)
{
Control control = page;
Boolean asyncPost = (page.Request.Form [ "__ASYNCPOST" ] == "true");
String eventTarget = page.Request.Form [ "__EVENTTARGET" ];
if (page.IsPostBack == true)
{
//check if the postback control is not a button
if (String.IsNullOrEmpty(eventTarget) == false)
{
//all naming containers
String [] parts = eventTarget.Split('$');
foreach (String part in parts)
{
//find control on its naming container
control = control.FindControl(part);
}
}
else
{
//search all submitted form keys
foreach (String key in page.Request.Form.AllKeys.Where(k => Char.IsLetter(k [ 0 ])).ToArray())
{
//all naming containers
String [] parts = key.Split('$');
//initialize control to page on each iteration
control = page;
foreach (String part in parts)
{
//find control on its naming container
if ((part.EndsWith(".x")) || (part.EndsWith(".y")))
{
//ImageButton
control = control.FindControl(part.Substring(0, part.Length - 2));
}
else
{
//other button type
control = control.FindControl(part);
}
}
if (control is IPostBackEventHandler)
{
if (((control is ScriptManager) || (control is ScriptManagerProxy)) && (asyncPost == true))
{
//ScriptManager/ScriptManagerProxy themselves never fire postback events
continue;
}
else
{
//found firing event
break;
}
}
//clear control for next iteration
control = null;
}
}
}
return (control);
}
}
Here is the full list of all events that occur in an ASP.NET application, from the standard modules, to the page, master page, page controls and master page controls.
I have not included the IIS 7 specific events (Log, for example).
| What |
| When |
| HttpApplication.BeginRequest |
|
| HttpApplication.AuthenticateRequest |
|
| HttpApplication.PostAuthenticateRequest |
|
| HttpApplication.AuthorizeRequest |
|
| HttpApplication.PostAuthorizeRequest |
|
| HttpApplication.ResolveRequestCache |
|
| HttpApplication.PostResolveRequestCache |
|
| HttpApplication.PostMapRequestHandler |
|
| HttpApplication.AcquireRequestState |
|
| HttpApplication.PostAcquireRequestState |
|
| HttpApplication.PreRequestHandlerExecute |
|
| Page.FrameworkInitialize |
|
| Page.InitializeCulture |
|
| Page.OnPreInit |
|
| MasterPage.FrameworkInitialize |
|
| MasterPageControl.FrameworkInitialize |
|
| PageControl.FrameworkInitialize |
|
| MasterPageControl.OnInit |
|
| PageControl.OnInit |
|
| MasterPage.OnInit |
|
| Page.OnInit |
|
| Page.OnInitComplete |
|
| Page.LoadPageStateFromPersistenceMedium |
If IsPostBack |
| MasterPageControl.LoadControlState |
If IsPostBack, RegisterRequiresControlState was called and control state contains elements |
| PageControl.LoadControlState |
If IsPostBack, RegisterRequiresControlState was called and control state contains elements |
| MasterPageControl.LoadViewState |
If IsPostBack and ViewState contains elements |
| PageControl.LoadViewState |
If IsPostBack and ViewState contains elements |
| Page.OnPreLoad |
|
| Page.OnLoad |
|
| MasterPage.OnLoad |
|
| MasterPageControl.OnLoad |
|
| PageControl.OnLoad |
|
| {PageControl|MasterPageControl}.OnCustomEvent |
If a custom event was fired on a control declared on the page/master page |
| {PageControl|MasterPageControl}.OnBubbleEvent |
If a custom event was fired on a control declared on the page/master page |
| {Page|MasterPage}.OnBubbleEvent |
If a custom event was fired on a control declared on the page/master page |
| Page.OnBubbleEvent |
If a custom event was fired |
| Page.OnLoadComplete |
|
| Page.OnPreRender |
|
| MasterPage.OnPreRender |
|
| MasterPageControl.OnPreRender |
If Visible |
| PageControl.OnPreRender |
If Visible |
| Page.OnPreRenderComplete |
|
| MasterPageControl.SaveControlState |
|
| PageControl.SaveControlState |
|
| Page.SaveViewState |
|
| MasterPage.SaveViewState |
|
| MasterPageControl.SaveViewState |
|
| PageControl.SaveViewState |
|
| Page.SavePageStateToPersistenceMedium |
|
| Page.OnSaveStateComplete |
|
| Page.Render |
|
| MasterPage.Render |
|
| MasterPageControl.Render |
If Visible |
| PageControl.Render |
If Visible |
| Page.OnCommitTransaction |
If Transaction = Required or RequiresNew and a transaction was committed or no transaction was created |
| Page.OnAbortTransaction |
If Transaction = Required or RequiresNew and a transaction was rolled back |
| MasterPageControl.OnUnload |
|
| MasterPageControl.Dispose |
|
| PageControl.OnUnload |
|
| PageControl.Dispose |
|
| MasterPage.OnUnload |
|
| MasterPage.Dispose |
|
| Page.OnUnload |
|
| Page.Dispose |
|
| HttpApplication.PostRequestHandlerExecute |
|
| HttpApplication.ReleaseRequestState |
|
| HttpApplication.PostReleaseRequestState |
|
| HttpApplication.UpdateRequestCache |
|
| HttpApplication.PostUpdateRequestCache |
|
| HttpApplication.EndRequest |
|
| HttpApplication.PreSendRequestHeaders |
|
| HttpApplication.PreSendRequestContent |
|
My NHibernateDataSource was just a necessary step in order to build an ASP.NET Dynamic Data provider for NHibernate. I am pleased to say that it is now working! Like the NHibernateDataSource, it is only - for now - merely a proof of concept, it needs cleaning up and still misses the association metadata part, which means no links to associated entities, but list, edit, delete and insert are working fine.
If you want to try it, please download it and send me your feedback.
In order to use it, create a Dynamic Data Web Application project and change the name of the context class on the Global.asax.cs file:
model.RegisterContext(new NHibernateDataModelProvider(typeof(MyNHibernateContext)), new ContextConfiguration() { ScaffoldAllTables = true });
Then, on all of the ASPX files under the DynamicData folder, replace the EntityDataSource declaration for the NHibernateDataSource, keeping all of the properties. Add the NHibernateDataSource files to your project and add references to NHibernate and LINQ to NHibernate, from the NHContrib project, and that's it!
I wrote a NHibernateDataSource, which can be used in ASP.NET web forms applications just like their counterparts EntityDataSource and LinqDataSource.
It requires a LINQ to NHibernate NHibernateContext-derived class which specifies the queryable entities. You can get it from the NHContrib site.
I have used code from Microsoft's LINQ samples, of which I talked about on a previous post, and you can get a precompiled assembly from there.
I have not implemented the InsertParameters, DeleteParameters and UpdateParameters properties, only the WhereParameters, but it shouldn't be too difficult.
Please note that this code is merely a proof of concept, it may have problems, and it is not optimized. If you find anything in it that should be improved, drop me a line. As usual, hope you find it useful!
In order to use the new functionalities (count, projections, server paging, for instance) supplied by version 1.5 of ADO.NET Data Services (see my previous post), you must explicitly enable them on the service side.
public static void InitializeService(DataServiceConfiguration config)
{
config.EnableTypeConversion = true;
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.UseVerboseErrors = true;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
}
Note that you need to use the DataServiceConfiguration instead of the IDataServiceConfiguration interface, which was the one that the wizard previously declared.
A new version of the ADO.NET Data Services API was released, and you can get it from here, for the Windows 2000, Windows Server 2003, Windows XP, Windows Vista and Windows Server 2008, and from here, for Windows 7 and Windows Server 2008 R2.
Overview
The ADO.NET Data Services framework consists of patterns and libraries that enable the creation and consumption of REST-based data services for the web. This update to the Microsoft .NET Framework 3.5 SP1 provides additional features which extend the functionality provided in version 1.0 of the ADO.NET Data Services framework.
The ADO.NET Data Services Update for .NET Framework 3.5 SP1 provides the following new features and improvements:
- Built-in integration in Microsoft Office 2010 now makes it simple to expose Microsoft Office SharePoint Server data as a data service and access that data using the ADO.NET Data Services client library.
- Custom Data Service Provider support now makes it easier to build an ADO.NET Data Service over any data source.
- A new DataServiceCollection class has been added that supports rich two-way data binding. The new collection implements automatic change tracking on client side objects created using the ADO.NET Data Services client library.
- Feed customization, provides a rich and flexible way to shape and modify the structure of ATOM feeds produced by an ADO.NET Data Service. Modifying the structure of the ATOM feed produced by the ADO.NET Data Services makes it possible for third-party clients that can consume an ATOM feed in a custom format to consume feeds from an ADO.NET Data Service.
- Enhanced blob support for streaming large binary objects to/from a data service. Support has also been added to the ADO.NET Data Services client library to provide the ability to upload and download binary objects (such as: images, videos, documents, etc.) from an application created using the library.
- Server-driven paging allows a service author to limit the size of the result set returned by a query; this gives the service author a new level of control over the network bandwidth and computation time required to process any request.
- A new select query option allows the result of a query to be projected into an arbitrary type; projecting gives the client the ability to request a specific set of properties of an entity. Reducing the number of properties requested in a query reduces processing time and network bandwidth for the request.
- The option to request a count of the number of entities in a set and the option to include the total count of the number of entities in the set when a query returns a partial result.
- Request pipeline improvements give the service author greater control and customization ability over various stages of query processing.
You can get more information from the
Astoria blog.
In ASP.NET 2.0+ you can have nested master pages. In Visual Studio 2008, the editor even knows how to handle them properly.
Nested master pages allows specializing the original master page, for example, entering Contents for some of the ContentPlaceHolders. The problem is, when we are using a nested master page, we can no longer access the original master page's ContentPlaceHolders. The trick is, on the nested master page, to create additional Contents and inside them create new ContentPlaceHolders with the same names as the parent master page's.
<%@ Master Language="C#" CodeBehind="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="title" runat="server"/>
</title>
</head>
<body>
<form runat="server">
<asp:ContentPlaceHolder ID="content" runat="server"/>
</
</body>
</html>
<%@ Master Language="C#" MasterPageFile="~/Site.Master" CodeBehind="Admin.master.cs" Inherits="Admin" %>
<asp:Content runat="server" ContentPlaceHolderID="title">
<asp:ContentPlaceHolder runat="server" ID="title" />
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="content">
<span>Some content</span>
<asp:ContentPlaceHolder runat="server" ID="content" />
</asp:Content>
Following my previous post on the ForeignKeyBoundField, here are some more templates for your GridView or DetailsView controls: ListBoundField and ResourceBoundField.
ListBoundField converts a value coming from a data source in a string, supplied in a list in the markup. ResourceBoundField translates a value by using a resource file, in a way identical to the one used by the <%$ Resource > expression builder.
Using these two templates, you can change the value displayed on the grid or details without any trouble.
If you like them, want to change them, or need an additional feature, drop me a line.
More Posts
Next page »