I am working on CI for my team,  new projects are using .net framework 4.5, our server 2008 also has framework4.5 installed, but My TFS2012 still got Error like this:
The application pool that you are trying to use has the 'managedRuntimeVersion' property set to 'v4.0'. This application requires 'v4.5'

There are two solutions I tried can fix this issue.
both need use a textpad edit the project file:
Add one of below before <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>:



Categories: Agile | Asp.net | Visual studio 10/up

this is a unsign saml response xml, the value need be change every submit was replaced by {time1} or {guid1}.
before sign the xml, those value will be update.  otherwise it will not pass the Saml validation.
If you got "Assertion was replayed" error. that because the time is not correct or AssertionId already be used.

After the Saml Xml build and signed, there is one more thing need change,
the RSA Saml Relay part only take the signature before the issuer, but the DotNet sign the xml and insert as the last Child, so we need additional code to make it work:

            SignXmlHelper.SignXml(xmlDoc, cert, "ID", guid1);
            //var item=  xmlDoc.GetElementsByTagName("Signature").Item(0);
            XmlElement xmlElement = xmlDoc.DocumentElement;
            var signatureNode = xmlElement.LastChild;
            xmlElement.InsertAfter(signatureNode, xmlElement.FirstChild);

            var outstr = xmlDoc.OuterXml;
Last notice:
 when you post the saml, in saml1, the target url is TargetUrl, but for saml2, it changed to relaystate

Categories: Asp.net | C# | Security


the download page only work under IE ;)

Available Source Code Components


Product NameVersionViewDownload
.NET8.0View EULADownload
dotnetfx1434_VistaWin2k8sp150727.1434View EULADownload
FXUpdate307450727.3074View EULADownload
ASP.NET_MVC1.0View EULADownload
WCF3.5SP1View EULADownload
WF3.5SP1View EULADownload
Dotnetfx_Vista_SP250727.4016View EULADownload
Dotnetfx_Win7_3. EULADownload
ASP.NET_MVC2.0View EULADownload
.Net4View EULADownload
.NET_3.5_sp1_redist50727.3053View EULADownload
Netfx_3.5.1_Win7SP13.5.1View EULADownload
NET4.5View EULADownload
Net4.5Update1View EULADownload

Categories: Asp.net | C# | MVC | Visual studio 10/up | WCF

Saml Response is Assertion xml with digital signature,
so , when get xml of Saml XML, and your x509 certificate,
you can use follow code to sign it.

Here is examples.

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class SignXML

    public static void Main(String[] args)
            // Create a new CspParameters object to specify 
            // a key container.
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

            // Create a new RSA signing key and save it in the container. 
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

            // Create a new XML document.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = true;

            // Sign the XML document. 
            SignXml(xmlDoc, rsaKey);

            Console.WriteLine("XML file signed.");

            // Save the document.

        catch (Exception e)

    // Sign an XML file.  
    // This document cannot be verified unless the verifying  
    // code has the key with which it was signed. 
    public static void SignXml(XmlDocument xmlDoc, RSA Key)
        // Check arguments. 
        if (xmlDoc == null)
            throw new ArgumentException("xmlDoc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = rsaKey;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

        // Add the reference to the SignedXml object.

        // Compute the signature.

        // Get the XML representation of the signature and save 
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));


public static XmlElement SignDoc(XmlDocument doc, X509Certificate2 cert2, 
              string referenceId, string referenceValue) {
    SamlSignedXml sig = new SamlSignedXml(doc, referenceId);
    // Add the key to the SignedXml xmlDocument. 
    sig.SigningKey = cert2.PrivateKey;

    // Create a reference to be signed. 
    Reference reference = new Reference();

    reference.Uri = String.Empty;
    reference.Uri = "#" + referenceValue;

    // Add an enveloped transformation to the reference. 
    XmlDsigEnvelopedSignatureTransform env = new
    XmlDsigC14NTransform env2 = new XmlDsigC14NTransform();


    // Add the reference to the SignedXml object. 

    // Add an RSAKeyValue KeyInfo
    // (optional; helps recipient find key to validate). 
    KeyInfo keyInfo = new KeyInfo();
    KeyInfoX509Data keyData = new KeyInfoX509Data(cert2);

    sig.KeyInfo = keyInfo;

    // Compute the signature. 

    // Get the XML representation of the signature
    // and save it to an XmlElement object. 
    XmlElement xmlDigitalSignature = sig.GetXml();

    return xmlDigitalSignature;

Signed xml sample:

Categories: Asp.net | C# | Security

if samlresponse is not encripted, it is very easy to decript it ans view it signature and data.

to Created the SamalResponse before submit the relaypart,  identity provider did
   string samlResponse = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(requestParameters["assertion"]));
after it recevied the samlREsponse, the Service provide do
 var samlResponse =
            XmlDocument SAMLXML = new XmlDocument();
so for more security, the assertion should also encripted by using public offer by service provider, just like below diabram

diagram come from:

some example with source code,

Categories: Asp.net | Security

Yesterday I test cross domain post against MVC successfully. So how about post to WebAPI?

But first try I failed and got error message like "Optional parameter 'user' is not supported by 'FormatterParameterBinding'.

after some research and test, I notice webapi [fromBody] parameters binding only take Model class as parameter.
//var data = "user=a" not owrk...string didn't have properties of user;
public string Test([FromBody] string user)
            return "user:" + user;

I have to change code like below:
public string Test([FromBody] User user)
            return "user:" + user;

  public class User
        public string Name { get; set; }

        public string Pwd { get; set; }
And test to post by jQuery
$.post('http://localhost:6660/api/task/test/0/t', { Name: 'a' ,Pwd:'b'});

and everything works

Categories: Asp.net | JQuery | MVC

I don't want to use jsonP because it only can use "GET" method and all the data can be viewed on url.
After many search and failed test code. Finally I got below solution:

1. Enable CORS on server,
  a. asp.net site said you can enable cors for webapi: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api . unfortunately, it require preview version of visual studio 2013.
  b. http://enable-cors.org/ site offer the methods to enable cors on IIS7, But it not works in my test.
  c. so I have to add the Access-Control-Allow-Origin=* to the response header by code myself.
    Simplest way is  adding this function in global.asax.cs
   protected void Application_BeginRequest(object sender, EventArgs e)
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

my test Action:
 public ContentResult Test(FormCollection formValues,string user="", string pwd="" )
            dynamic flexible = new ExpandoObject();
            flexible.UserName = user;

            var dictionary = (IDictionary<string, object>)flexible;
            dictionary.Add("IsSuccess", true);

            var re= JsonConvert.SerializeObject(dictionary); 
            return  Content(re);

2. It's not finish yet. you can see the correct response was return to the client in Fiddle or firebug, but the JQuery ajax call success not be fired. we have to do some more code on client side:
var loginUrl = 'http://localhost:6660/home/test';
        var data = "user=a&pwd=b";
            type: 'POST',
            url: loginUrl,         
            data: data,
            sucess:function(re) {
                //never reached here
            error: function (jqXHR, error, errorThrown) {
                //handle err
            complete: function (re, status) {
                if (status == 'success') {
                    var reObj = JSON.parse(re.responseText);

Yub!  date was get from cross domain server. this even working open html file directly.

Categories: Asp.net | C# | JQuery | MVC

Server side code in controller:
     public ContentResult TaskJsonP(string callback,int id)
            var model = service.GetTaskDetails(new TaskDetailRequest() { Id = id });
            //return Json(model, JsonRequestBehavior.AllowGet);
            return Content(String.Format("{0}({1});",
          new JavaScriptSerializer().Serialize(model)),          

Client side you can open any page and try below:
                       alert (value)              },

Categories: Asp.net | C# | Html5 | JQuery | MVC

October 2, 2012
@ 11:27 PM

Base on MVC definition from msdn http://msdn.microsoft.com/en-us/gg592073:

  • Models: Model objects are the parts of the application that implement the domain logic. Often, model objects also retrieve and store model state in a database.
  • Views: Views are the components that display the application's user interface (UI). Typically, this UI is created from the model data. An example would be the edit view of Albums that displays text boxes and a drop-down list based on the current state of an Album object.
  • Controllers: Controllers are the components that handle user interaction, manipulate the model, and ultimately select a view to render the UI. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction.

So Create a ViewModel for each Views, ViewModels should be a DTO or Plain Object.   and Models are Factories to Generate ViewModels.

The MVVMC should be like this:

for example UserContacts page:

UserContactsController ->UserContactsModel->UserContactsViewModel->UserContactsView

Controller ask UserContactModel for UserContactsViewModel and fill the UserContactsView and return it.

and there is another View Model or domain object UserContact.

UserContactsViewModel is Model of UserContactsView,

UserContactsViewModel has something like List<UserContact>

there should be couple of helpers can be called by UserContractsModel.

Categories: Asp.net | MVC

Custom Project Template with Wizard, create the new class with the name of custom value.
Categories: Asp.net | C# | Visual studio 10/up | VS 2008

September 10, 2011
@ 01:05 AM
I created a new MVC project, and test the remote validation in the about page.

1)Controller Home:
               public ActionResult ValidateTestName(string testName)
            return Json(!testName.Equals("test"),
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace MvcApplication1.Models
    public class AboutModel
        [Remote("ValidateTestName", "Home", ErrorMessage = "this Name already be used.")]
        public string TestName { get; set; }

        [Range(20, 44)]
        public int Age { get; set; }
In _Layout.cshtml:

In About.cshtml

@model MvcApplication1.Models.AboutModel
    ViewBag.Title = "About Us";


Put content here. @using (Html.BeginForm()) { @Html.EditorForModel(); "submit" value="Submit" /> }

It is working perfect under FireFox 6:

but not working in my IE9 :(...
I have downloaded Jquery.Validation 1.8.1 try to fix this issue, but looks still unlucky.
(Jquery.Validation site : http://bassistance.de/jquery-plugins/jquery-plugin-validation/)

but this post in stack overflow said it tested in
Chrome 10.0, IE9 and FireFox 4.0
Categories: Asp.net | MVC

1. you need create a web deploy project, if you didn't have that,please install the web deployment plug-in.

For Visual Studio 2005, the plug-in can be downloaded here.

For Visual Studio 2008, the plug-in can be downloaded here.

2. Configure your deploy project properties like below.

3. after build, you will get a single assembly CommonVoiceUC.dll,
in you new web site, add it to your reference.

4. in your aspx page, use it like regular Customer Controls.
<%@ Register Assembly="CommonVoiceUC" Namespace="CVUC" TagPrefix="cvuc" %>
<cvuc:CvDistributionGroupUpdateUC runat="server" ID="test" />

so this way you can very easy create a lot of customer controls with lots of Html tag or css in it. and it very easy for other application to use it.
the bad thing is if the control have other components, for example "Telerik.Web.UI.dll", and other site want to reuse this control was using a different version of Telerik control.
the conflicts will happen.

Categories: Asp.net | VS 2005 | VS 2008

I am working on a project that has page flow controlled by a Controller of the MVC framework. For some complcated pages I must use the Classic WebForm type, rather than a regular View page. 
When the page in Classic ASP.net WebForm has finished its job, the page needs to redirect back to the MVC controller and go to next page decided by the Business logic in the Controller

Here, I listed some redirect code that may be useful.

In classic Web Form page
  protected void btnContinue_Click(object sender, EventArgs e)
            BillingProcess process = CurrentProcess;//BillingmanagementService.GetProcess(Uid);
            process.CurrentStep = BillingManagementStep.TempCreditStart;//this is required, to make sure the current step
            Response.Redirect(ViewMapUti.GetProcessUrl("continue", process.CurrentStep, Uid));
           // Response.Redirect(string.Format("/BillingManage/Process/continue/{0}/{1}",process.CurrentStep, Uid));

In Controller
    protected ActionResult GoToPage(BillingProcess process)
            if (process != null)
                RedirectResult rUrl = CheckIfClassicPage(process);
                if (rUrl != null)
                    return rUrl;
                return View(ViewMapUti.GetMapPage(process.CurrentPage), process);
                return View("Index");
   protected RedirectResult CheckIfClassicPage(BillingProcess process)
            string url = ViewMapUti.GetClassicUrl(process.CurrentStep, process.UidCustomerId);
            if (url != null)
                return Redirect(url);
                return null;


   In Help class ViewMapUti.cs
    public class ViewMapUti

// this need put in MapHelper.cs in the root public static String GetMapPage(string key)
///TODO:we should have a map in xml do defined which current viwe will be used. ///for example, we have made the change of Page1, rename to page2, but want keep the page2, ///just need add the page1 page2 in the mapfile if(key.Equals("initial",StringComparison.CurrentCultureIgnoreCase))
return key;
public static string GetProcessUrl(string actionButton, BillingManagementStep step, long uid)
return GetProcessUrl("Process", actionButton, step, uid);
public static string GetProcessUrl(string view, string actionButton, BillingManagementStep step, long uid)
if (view == null )
return GetHomeUrl();
/// 1.{controller}/{step}/{uid}/{action}.aspx/{actionButton} // return string.Format("/{0}/{1}/{2}/{3}.aspx/{4}", "BillingManage", step,uid, view, actionButton); ///2. /BillingManage/Process.aspx?uid=121&actionButton=process&step=ProcessingRequest /// return GetVirtualPath() + string.Format("/{0}/{1}.aspx?uid={2}&actionButton={3}&step={4}", "BillingManage", view, uid, actionButton, step);
public static string GetHomeUrl()
return HttpRuntime.AppDomainAppVirtualPath+"BillingManage/Index.aspx";
public static string GetClassicUrl(BillingManagementStep step, long uid)
if (step == BillingManagementStep.StartProcess ||step==BillingManagementStep.Initial)
//if need classic //Don't use transfer, it will cause javascript error in Ajax sometime(not every time). //Server.Transfer("/Classic/startProcess.aspx?uid=" + uid); return (GetVirtualPath() + "/Classic/startProcess.aspx?uid=" + uid);

else if (step == BillingManagementStep.EcouponCredit)
return (GetVirtualPath() + "/Classic/EcouponCredit.aspx?uid=" + uid);
else if (step == BillingManagementStep.TempCreditStart)
return (GetVirtualPath() + "/Classic/TempCredit.aspx?uid=" + uid);
return null;
public static string GetVirtualPath()
return HttpRuntime.AppDomainAppVirtualPath.Equals("/") ? "" : HttpRuntime.AppDomainAppVirtualPath + "/";


Categories: Asp.net | MVC

When I try to export a complex page which has RadGrid Control to PDF file, it always returns an error message like
Script control '' is not a registered script control. 
Script controls must be registered using RegisterScriptControl() before calling RegisterScriptDescriptors().
Parameter name: scriptControl

After trying many different ways, I finally found the right solution to exporting the page without exception: Override the "Render" method in the page or the UserControl.
The code is below:

protected override void Render(HtmlTextWriter writer)

        if (_isExport)
            StringWriter stringWriter = new StringWriter(); //System.IO namespace should be used

            HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);

            Response.Clear(); //this clears the Response of any headers or previous output
            Response.Buffer = true; //make sure that the entire output is rendered simultaneously

            ///Set content type to MS Excel sheet
            ///Use "application/msword" for MS Word doc files
            ///"application/pdf" for PDF files
            Response.AddHeader("content-disposition", "attachment;filename=ShippingSheet.doc");

            Response.Charset = "";
            Response.ContentType = "application/msword";

            ///Render the entire Page control in the HtmlTextWriter object
            ///We can render individual controls also, like a DataGrid to be
            ///exported in custom format (excel, word etc)
            // PrintableShippingSheet1.RenderControl(htmlTextWriter);


Categories: Asp.net | C# | Telerik Controls

Currently I am working on a project are using ASP.NET MVC, and I need reuse some user controls with Telerik Controls,
As you know, many of those user controls for WebForm need enable ViewSate.
So I had combined both new MVC and old WebForm pages in this project.
and I had encountered and solved many issues both for integration and MVC
I write some key points here as my collections and want to share with my visitors.
Here is an article about adding MVC to regular website :link

 1. setup Route in Global.asax

public static void RegisterRoutes(RouteCollection routes)

// routes.IgnoreRoute("Classic/{resource}.aspx?{*requestUrl}"); //the ? is not allow in the route config
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}"); //All .aspx regard as webform.
routes.IgnoreRoute("{resource}.ash/{*pathInfo}"); //other type need escape
routes.IgnoreRoute("Classic/{resource}.aspx/{*pathInfo}"); //I put my webform files in classic folder


"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults

2. Make your old UserControls work

3. Fix those weird problems of Visual Studio 2008
After copy the Classes such as "BaseUserControl.cs" to MVC project, whatever how many times I clean and rebuild the project, Those classes always can't be found by other classes.
And another issue happen frequently is the Pages have using Telerik controls, always have error message 'Error Creating Control' at design time.
After some research, I found  those step will solve these issues like a magic.

   step 1. Close your Visual studio 2008 .
   step 2. Go to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\ folder, delete all sub directories.
   step 3. Go to C:\Documents and Settings\yourname\Local Settings\Application Data\Microsoft\VisualStudio\9.0\ProjectAssemblies\
              Delete all sub diretories.
   step 4. Restart.

And some people said, if copy the Telerik dlls to Global assembly will fix Telerik issue.

Categories: Asp.net | MVC | Telerik Controls | VS 2008

I have a application need authentication to access another application's API, but the API's password  stored in the database was encrypted by 3DES algorithm in Java code. I can access the Key for decrypt the password.
So I had tried some different to get the clear password,
1. Ask for Plain text password
   I got it, for security reason, It can not be used in production.
2. Ask Java team to build a Java WebService  offer the decode service.
   It looks good plan, but need wait for other team's work, I already wait for 1 month.
3. Try to decrypt the password from .net side. 
   I tried, and just proved it not works. So I come here write down what I found.

The reason is simple: the byte array in java and byte in C# are different.
In Java, the byte  is 8 bit signature, value is from -127 to 128.
but in C# the byte is 8 bit non-signature, the correspond Java byte  in C# is sbyte.
I hard code the Key byte array to force all value of key's byte between 0-128 so c# and Java can have same Key.
But unlucky, the same short string "Hello Wei", in Java, the byte array length is 8. but in C# it is 16.

That obviously tell me it is impossible to share key between java and .net application to do de/encryption.

Here are some of my Java  and C# code I wrote in this research.
Java code have BlowFish and 3sdes.

BlowFishAPI.zip (4.16 KB) 
TripleDesFixture.cs (11.38 KB)

Some reference links;
blowfish in .net: http://www.hotpixel.net/software.html
TripleDes Encryption:  click here

Categories: Asp.net | Java

June 9, 2009
@ 05:29 PM
Just spend some time to try the ASP.NET MVC framework.
MVC it self is not a new stuff,  there are many famous frameworks in JAVA like Struts.
In the .Net, you also can find some open source MVC framework, like monoRail in castle project.
I am just surprised why Microsoft release its MVC framework so late.

Them ASP.NET MVC solve the  problem that you can't do Unit Testing in the ASP.Net websites. it make the responsibility of each parts more clear.
And the Url rewrite can let you have User and SEO friendly url easily.
It get rid of viewstates in "post back", which will make the page size smaller and improve the performance.
And especially in AJAX post back, the response time will much faster, because it don't need load any other controls in that page and their viewstates.

but I just feel hesitated to use MVC in my new project for those reasons:

1. Not as easy and fast as the web form Page Control model. It may good for some complicate and big application. 
2. Don't have good support by IDE, I may missing some plug-in or starter kit, but I think do MVCp rogramming  in VisueStudio 2100 may be easier than current VS2005/2008.
3. Little bit complicate to build a simple page. write a View give me some trouble, and spend more time than I expect.
4. There is not controls and components available for us to using in the project to save developing time. But I know some components vendors will support MVC soon, will find that out when got chance.
5. It is not easy to find a good sample project and documents. Some books are in releasing or just published. I am still waiting it come out and want to check if them are worthy to buy.

The MVC is the first release from Microsoft. As well know the first product from Microsoft always looks ugly and silly. but it always have good chance to bet it competitor.

Though I said something bad to MVC, but I still think it is a good thing for ASP.net programmer.
I just think I may wait the next release of MVC and decide if to use it in my real projects.

Categories: Asp.net | MVC

I'm trying to expand my mind around dependency injection in .NET (beyond the two frameworks I've personally used) and an starting to put together a list of .NET Dependency Injection Containers and IOC resources.

Here's what I've got so far. What am I missing?

What projects have I forgotten? Thanks!

Related Links

  • Posted at 2008-03-13 10:14 PM by Scott

Categories: Asp.net

ASP.NET页面事件:顺序与回传详解2008-04-23 来自:java060515 


   ·当页面被提交请求第一个方法永远是构造函数。您可以在构造函数里面初始一些自定义属性或对象,不过这时候因为页面还没有被完全初始化所以多少会有些限 制。特别地,您需要使用HttpContext对象。当前可以使用的对象包括QueryString, Form以及Cookies集合,还有Cache对象。注意:在构造函数里是不允许使用Session的。

  ·下一个将执行的方法是 AddParsedSubObject方法,这个方法将添加所有独立的控件并把页面组成一个控件集合树,这个方法经常被一些高级的页面模板解决方案 (Page Template Solutions)重写以便添加页面内容到页面模板(Page Template)中一些特殊的控件中。这个方法递归应用到所有的页面控件及相应的的每个子控件,所有的控件都是在这个方法中开始最早的初始化。

   ·页面类中下一个将执行的方法是DeterminePostBackMode。这个方法允许您修改IsPostBack的值及相关的事件。如果您需要从 数据库中加载ViewState这个方法将特别有用,因为ViewState只有在IsPostBack为真的情况下才会进行恢复。返回空将会导致强制执 行非回传,返回Request.Form则强制执行一个回传。除非在特殊情况下,否则并不建议去操作这个,因为这个还会影响其他的事件。

   ·下一个将要执行的方法是OnInit方法,一般这是第一个真正被使用的方法。这个方法触发时,所有页面定义中的控件执行初始化,这意味着所有在页面中 定义的值应用到相应的控件上。不过,ViewState和传回的值还不会应用到控件上,因此,任何被代码或用户改变的值还没有被恢复到控件上。这个方法通 常是最好的创建、重创建动态控件的好地方。


  ·下一个方法, LoadPageStateFromPersistenceMedium只会在页面被回传的时候才会被执行。如果因为使用Session或自定义存储方 式,您修改了后面将要提到的影响ViewState保存方式的方法SavePageStateToPersistenceMedium,则这个方法需要被 重写。默认的实现中ViewState是一种Base64格式编码,并且被保存在页面的隐藏域中,您可以使用这篇文章中提及的方法修改ViewState 按以上两种方式保存。注意:这个方法并没有真正加载ViewState到页面或页面控件中。

  ·当得到ViewState后,下一个方 法LoadViewSate,将以递归的方式恢复ViewState到页面及各个页面控件或子控件中。这个方法执行后,每个控件都将恢复到上一次的状态, 但是用户提交的数据还没有应用到控件上,因为他们不是ViewState的一部分。这个方法主要用于恢复您在其他事件中动态生成的控件的值,他们的值是您 手动保存在ViewSate中,并且现在已经失效。

  ·下一个方法是ProcessPostData,这个方法也同样是回传的时候才会 被执行,并且不允许被重写,这个是页面基类的私有方法。这个方法通过匹配控件的名称恢复相应的用户提交的控件的值,到这一步意味着整个页面都已经被完全恢 复了。唯一要记住的是所有动态控件的创建必须在这个方法之前。这个方法也是记录后面的改变事件的方法。

  ·下一个方法是OnLoad方 法,通常这是用得最多的方法,因为这个方法是页面生存期第一个恢复了所有值的地方。大多数代码根据判断IsPostBack来决定是否重新设置控件状态。 您也可以在这个方法中调用Validate并且检查IsValid的值。也可以在这个方法中创建动态控件,并且该控件的所有的方法都会被执行以追上当前页 面的状态包括ViewSate,不过不包括回传的值。


  ·下一个方法还是 ProcessPostData,实际上就是前一个方法的另一次调用,它仍然是只在回传的时候执行并且由于是私有方法不可以被重写。如果您是第一次看页面 的运行轨迹也许会觉得这个方法有些多余。但实际上这个方法是必要的因为在OnLoad中创建的动态控件也需要他们回传的值。任何在这以后创建的控件将可以 得到他们的ViewState,但是不能再得到他们的回传的值,并且不会触发任何值改变事件(Change Event)。

  ·下一个 方法,RaiseChangedEvents,也是只在回传页面中执行,并且也因为是基类的私有方法所有不能被继承。在整个页面生存期中,是在这儿根据之 前的ProcessPostData记录的控件的值和提交的值是否不同来触发值改变事件。您也许需要调用Validate或者检查IsValid的值。这 里并没有特别的说明多个值改变事件的执行先后顺序。

  ·下一个方法,RaisePostBackEvent,同样是因为是基类的私有方 法不能被继承,同样也是只在回传页面中执行。除非使用了AutoPostBack,不然这是实际提交表单事件执行的地方,特别是按钮或者其实使用 javascript提交表单等。如果还没有被手动调用过并且使用了验证控件,那么Validate会被调用。注意IE中有个BUG有时会允许提交但却不 触发任何事件。

·下一个方法是OnPreRender,一般这是在客户端展现页面之前改变页面及其控件的最后一次机会。您也可以在这个方 法里面创建动态控件,并且所有的方法都会被执行以追上当前页面的状态包括ViewSate,但是私有方法将不会被执行,这意味着不会有回传的值并且不会有 事件触发。由于IE中的BUG,这是一个没有事件赶上PostBack的好地方。


  ·下一个方法是 SaveViewState,不论是否是回传页面,均会递归的执行以保存页面及其所有控件的ViewState。ViewState基本上保存所有与定义 在aspx中的原始值不同的值,不管是被代码还是用户所改变。注意控件值是根据他们在页面的控件树中的位置来保存的,所以如果动态控件后来加到了错误的位 置将会导致混乱。

  ·下一个方法是SavePageStateToPersistenceMedium真正的保存页面的 ViewSate。这个方法随同LoadPageStateFromPersistenceMediumg 一起被重写以便保存ViewState到Session或其它自定义数据,而不是用隐藏域。这对于低带宽的用户来说是很有帮助的。并且对于移动设备来说, Session是默认设置。下面这篇文章描述了使用以上两种方式保存ViewState的具体细节。注意在Asp.net中有个Bug:Asp.net要 求必须提交__viewstate字段,即使是空的。

  ·下一个方法是Render方法,该方法递归的创建并发送相应控件的html给 浏览器。这个方法被一些页面模板方案重写以添加一些通用的页面头与脚而不使用服务器控件,他们总是有一些额外的东西。注意这儿的修改只能使用纯HTML, 因为控件在这儿已经被生成了。您可以用StringBuilder,StringWriter,HtmlTextWriter捕获相应的HTML输出。

   · 最后的方法是OnUnload,这个方法会调用相应的Dispose方法。这个方法提供机会以便清空该页面中使用的非托管资源,如关闭打开的文件句柄,以 前打开的数据库连接等。注意这个方法是在页面已经发送到客户端以后执行的,所以它只有影响服务器对象,并且它不会显示在页面的显示轨迹中。这就是页面的生 存期,对于每一次请求都是这么运行的。



















Categories: Asp.net


Categories: Asp.net

March 30, 2008
@ 10:36 PM
Connecting to Diagnostic Listeners
Tracing in ASP.NET is somewhat orthogonal to tracing in the .NET Framework. The Systems.Diagnostics namespace defines two classes, Trace and Debug, whose methods are used to trace the code. The Trace and Debug classes are essentially identical and work on top of more specialized modules known as listeners. A listener collects and stores messages in the Windows event log, a text file, or some other similar file. Each application can have its own set of listeners; all registered listeners receive all emitted messages. The tracing subsystem of ASP.NET 2.0 has been enhanced to include support for forwarding ASP.NET tracing information to any registered .NET trace listeners. You enable this feature by turning on the writeToDiagnosticsTrace attribute in the <trace> section of the web.config file, like so:
<trace enabled="true" pageOutput="false" 
       writeToDiagnosticsTrace="true" />
Setting the writeToDiagnosticsTrace attribute is not enough, though. You also need to register one or more listeners for the Web application. Use the <trace> section under the <system.diagnostics> section to do that, as shown here:
  <trace autoflush="true">
      <add name="myListener" 
           initializeData="c:\myListener.log" />
There are two important things to note here. First, only text written through either Write or Warn is forwarded to the listeners. That is, the listener won't store a copy of the standard ASP.NET trace information; the information tracked is limited to the contents of the Trace Information section. The second thing is that you can write custom listeners to send trace information to the medium of your choice—for example, a SQL Server database. All you have to do is inherit a class from System.Diagnostics.TraceListener and override a few methods. Next, you register the new class with the web.config file of the Web application you plan to trace. (For more information on writing custom TraceListener types, see msdn.microsoft.com/msdnmag/issues/06/04/CLRInsideOut.) One interesting thing to note is that System.Web.dll now includes a TraceListener-derived type, WebPageTraceListener, whose job is to serve as the counterpart to writeToDiagnosticsTrace. When an instance of WebPageTraceListener is added to the trace listeners collection, messages written to the .NET diagnostics trace will also be written to the ASP.NET trace.
Finally, you should be aware that in ASP.NET 2.0 a new <deployment> section has been added to the Web configuration section related to tracing.

Categories: Asp.net | log4net


In this article, we will see the stages of execution of the ASP .NET Page.

Each request for an .aspx page that hits IIS is handed over to HTTP Pipeline. HTTP Pipeline is a chain of managed objects that sequentially process the request and convert it to plain HTML text content. The start point of HTTP Pipeline is the HttpRuntime class. The ASP.NET infrastructure creates each instance of this class per AppDomain hosted within the worker process. HttpRuntime class picks up an HttpApplication object from an internal pool and sets it to work on the request. It finds out what class has to handle the request. The association between the resources and handlers are stored in the configurable file of the application. In web.config and also in machine.config you will find these lines in <httpHandlers> section.

If you run through the following program, it will be much easier to follow

<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>

This extension can be associated with HandlerClass or HandlerFactory class. HttpApplication object gets the page object that implements the IHttpHandler Interface. The process of generating the output to the browser is started when the object calls ProcessRequest method.

Page Life Cycle

Once the HTTP page handler class is fully identified, the ASP.NET runtime calls the handler's ProcessRequest to start the process. This implementation begins by calling the method FrameworkInitialize(), which builds the control trees for the page. This is a protected and virtual member of TemplateControl class, class from which page itself derives.

Next the processRequest() makes page transits various phases: initialization, loading of viewstate and postback data, loading of page's user code and execution postback server-side events. Then page enters in render mode, the viewstate is updated and HTML generated is sent to the output console. Finally page is unloaded and request is considered completely served.

Stages and corresponding events in the life cycle of the ASP.NET page cycle:
Stage Events/Method
Page Initialization Page_Init
View State Loading LoadViewState
Postback data processing LoadPostData
Page Loading Page_Load
PostBack Change Notification RaisePostDataChangedEvent
PostBack Event Handling RaisePostBackEvent
Page Pre Rendering Phase Page_PreRender
View State Saving SaveViewState
Page Rendering Page_Render
Page Unloading Page_UnLoad

Some of the events listed above are not visible at the page level. It will be visible if you happen to write server controls and write a class that is derived from page.

Page Execution Stages

The first stage in the page life cycle is initialization. This is fired after the page's control tree has been successfully created. All the controls that are statically declared in the .aspx file will be initialized with the default values. Controls can use this event to initialize some of the settings that can be used throughout the lifetime of the incoming web request. Viewstate information will not be available at this stage.

After initialization, page framework loads the view state for the page. Viewstate is a collection of name/value pairs, where control's and page itself store information that is persistent among web requests. It contains the state of the controls the last time the page was processed on the server. By overriding LoadViewState() method, component developer can understand how viewstate is restored.

Once viewstate is restored, control will be updated with the client side changes. It loads the posted data values. The PostBackData event gives control a chance to update their state that reflects the state of the HTML element on the client.

At the end of the posted data changes event, controls will be reflected with changes done on the client. At this point, load event is fired.

Key event in the life cycle is when the server-side code associated with an event triggered on the client. When the user clicks on the button, the page posts back. Page framework calls the RaisePostBackEvent. This event looks up for the event handler and run the associated delegate.

After PostBack event, page prepares for rendering. PreRender event is called. This is the place where user can do the update operations before the viewstate is stored and output is rendered. Next stage is saving view state, all the values of the controls will be saved to their own viewstate collection. The resultant viewstate is serialized, hashed, base24 encoded and associated with the _viewstate hidden field.

Next the render method is called. This method takes the HtmlWriter object and uses it to accumulate all HTML text to be generated for the control. For each control the page calls the render method and caches the HTML output. The rendering mechanism for the control can be altered by overriding this render method.

The final stage of the life cycle is unload event. This is called just before the page object is dismissed. In this event, you can release critical resources you have such as database connections, files, graphical objects etc. After this event browser receives the HTTP response packet and displays the page.

Categories: Asp.net

Truly understanding Dynamic Controls

Truly understanding ViewState

Must read if you are an ASP.NET developer. Read them letter by letter every month, memorize them.

This is the third time I am linking to these articles. Every time I (re)read them I understand something new.


Categories: Asp.net

Page with Master Page,
Control Logo in Master Page,
Control UC1 in Page, UC2 in UC1.

The Order of Events is:

Page: Page_PreInit

Logo: Page_Init
UC2: Page_Init
UC1: Page_Init
Master: Page_Init
Page: Page_Init

Page: Page_PreLoad

Page: Page_Load
UC1: Page_Load

Page: Page_PreRender


UC2: Page_Unload
UC1: Page_Unload

Categories: Asp.net

September 1, 2006
@ 01:15 PM

protected void Btn_ExportClick(object sender, EventArgs e)


string style = @"<style> .text { mso-number-format:\@; } </style> ";


Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

Response.ContentType = "application/excel";

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);


// Style is added dynamically





Categories: Asp.net

    <asp:GridView ID="gvGraveOpening" runat="server" AutoGenerateColumns="False" DataKeyNames="Id"
        DataSourceID="GraveOpeningODS"  OnRowUpdating="grGraveOpening_rowUpdateing" SkinID="mocha"
            <asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="~/Funeral/GraveOpeningDetail.aspx?id={0}"
                Text="Detail" />
            <asp:BoundField DataField="Name" HeaderText="Name" ReadOnly="True" />
            <asp:BoundField DataField="Grave" HeaderText="Grave" ReadOnly="True" />
            <asp:BoundField DataField="DateTime" HeaderText="DateTime" ReadOnly=True />
            <asp:TemplateField HeaderText="Status">
                    &nbsp;<asp:DropDownList ID="ddlStatus" runat="server" >
                        <asp:ListItem Selected=True>Issued</asp:ListItem>
                    <asp:Label ID="Label1" runat="server" Text='<%# Bind("status") %>'></asp:Label>
            <asp:CommandField ShowEditButton="True" EditText="Update Status" ButtonType="Button" UpdateText="Save"  />
    <asp:ObjectDataSource ID="GraveOpeningODS" runat="server" SelectMethod="UnCompeltedGraveOpening"
        TypeName="GraveOpeningDs" UpdateMethod="SaveGraveOpeningStatus">


Code Behind:

protected void grGraveOpening_rowUpdateing(object sender, GridViewUpdateEventArgs e)
        DropDownList d= (DropDownList)gvGraveOpening.Rows[e.RowIndex].FindControl("ddlStatus");
        GraveOpeningDs ds = new GraveOpeningDs();
        ds.SaveGraveOpeningStatus(Convert.ToInt32(e.Keys[0]), d.SelectedValue);



Categories: Asp.net

step 1, Preparing Object Datasource:


public class UserDS
public ArrayList GetUsers(object login_user)
if user is admin return all users, otherwise return login_user in Arralist
return DBControl.GetDashboardUsers((User)login_user);
public void SaveUser(string username, string password, string group)
DBControl.UpdateUser(username, password, group);
public void InsertUser(string username, string password, string group)
//if username exsit, then throw excepton..
DBControl.InsertUser(username, password, group);

public void Deleteuser(string username)

step 2, Create Object Datasource In Asp page:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="Deleteuser"
SelectMethod="GetUsers" TypeName="UserDS" UpdateMethod="SaveUser">
<asp:Parameter Name="UserName" Type="String" />
<asp:Parameter Name="UserName" Type="String" />
<asp:Parameter Name="Password" Type="String" />
<asp:Parameter Name="Group" Type="String" />
<asp:SessionParameter Name="login_user" SessionField="Login_User" Type="Object" />


step 3, GridView:

<asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#E7E7FF"
BorderStyle="None" BorderWidth="1px" CellPadding="3" DataSourceID="ObjectDataSource1"
GridLines="Horizontal" AutoGenerateColumns=False DataKeyNames="UserName">
<FooterStyle BackColor="#B5C7DE" ForeColor="#4A3C8C" />
<asp:BoundField DataField="UserName" HeaderText="UserName" ReadOnly=true />
<asp:BoundField DataField="Password" AccessibleHeaderText="Password" HeaderText="Password" />
<asp:BoundField DataField="Group" HeaderText="Group" />
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<RowStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" />
<SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="#F7F7F7" />
<PagerStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" HorizontalAlign="Right" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
<AlternatingRowStyle BackColor="#F7F7F7" />

Categories: Asp.net | C#