Archive for the ‘ASP.NET’ Category

To “refresh” a SqlDataSource.

Sunday, July 27th, 2008

I am trying to “refresh” a SqlDataSource in a postback action.  The basic idea is, user change some setting (which passed as paramters to the SqlDataSource) and need to “refresh” the query result. I was though to call some method in SqlDataSource but eventually I found the simplest way (maybe not that efficient) is call the object who have databinding with SqlDataSource’s DataBin() again.

e.g.

protected void Button1_Click(object sender, EventArgs e)
{
RadChart1.DataBind();
}

asp:ControlParameter vs asp:FormParameter

Sunday, July 27th, 2008

I got stucked on ASP.Net’s SqlDataSource’s parameters for quite a long time.  The problem is I am always trying to use aspFormParamter in a postback, there are quite a few samples in the Internet, but most of them are simple aspx page without masterpage. In my project I used masterpage, it looks like for some reason it doesn’t work well.

Fortunately, after I changed to asp:ControlParameter, it works great.

ASP.NET MVC Preview 3 just released

Tuesday, May 27th, 2008

Scott’s introduction: http://www.microsoft.com/downloads/details.aspx?FamilyId=92F2A8F0-9243-4697-8F9A-FCF6BC9F66AB&displaylang=en

download: http://www.microsoft.com/downloads/details.aspx?FamilyId=92F2A8F0-9243-4697-8F9A-FCF6BC9F66AB&displaylang=en

 

It looks much neater than the previous version. Looking forward the official launch.

Some ASP.NET Benchmark data

Sunday, January 13th, 2008

This is just a very simple and rough benchmark test, I use my own desktop computer running Windows XP professional and many process (including the heavy weight Visual Studio 2008) and ASP.NET’s development server which comes with Visual Studio. I believe after deploy it on IIS under Windows Server box will archive much better performance.

I use Apache bench to test, the parameter I used is “-n 1000 -c 100″, means send 1000 requests and concurrent number is 100.

Quick view of results:

  Test Request per second [#/sec] (mean)
1 Simple aspx view (same as below MVC’s view aspx file) 285.71
2 Simple asp.net MVC 232.73
3 ASP.net MVC with another MVC request from inside 174.39
4 ASP.net MVC with a simple user control rendered by RenderUserControl() 218.43
5 ASP.net MVC with a simple user control rendered by user control tag 235.29

Of course a simple .aspx page archive the best performance, MVC add very minimal overhead to it.

Use tag to render user control have almost no overhead ( I believe it has been complied inside, like source level include),  RenderUserControl() have a small overhead.

shinakuma’s RenderComponent() have some overhead in performance since he use “ProcessRequest()” which actually initialize a whole server side MVC cycle.  (Java’s jsp:include have same heavy weight behavior as I tested before.) If we can find out a better solution to archive a much lighter weight performance it would be great.

Details outputs:

Test #1: Simple aspx view (same as below MVC’s view aspx file)

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http://localhost:64701/views/Home/Index.aspx
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /views/Home/Index.aspx
Document Length:        1176 bytes

Concurrency Level:      100
Time taken for tests:   3.500000 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1410000 bytes
HTML transferred:       1176000 bytes
Requests per second:    285.71 [#/sec] (mean)
Time per request:       350.000 [ms] (mean)
Time per request:       3.500 [ms] (mean, across all concurrent requests)
Transfer rate:          393.14 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.3      0      15
Processing:    78  331  71.5    343     515
Waiting:       78  328  71.2    328     484
Total:         78  331  71.4    343     515

Percentage of the requests served within a certain time (ms)
  50%    343
  66%    343
  75%    343
  80%    343
  90%    406
  95%    468
  98%    484
  99%    484
100%    515 (longest request)

Test #2:  Simple ASP.NET MVC (empty controller, simple asp.net view page with default master page)

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        1168 bytes

Concurrency Level:      100
Time taken for tests:   4.296875 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1402000 bytes
HTML transferred:       1168000 bytes
Requests per second:    232.73 [#/sec] (mean)
Time per request:       429.688 [ms] (mean)
Time per request:       4.297 [ms] (mean, across all concurrent requests)
Transfer rate:          318.60 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.6      0      46
Processing:    62  408  71.4    421     531
Waiting:       62  403  71.1    421     515
Total:         62  408  71.5    421     546

Percentage of the requests served within a certain time (ms)
  50%    421
  66%    437
  75%    437
  80%    437
  90%    453
  95%    468
  98%    484
  99%    500
100%    546 (longest request)

 

Test#3: ASP.NET MVC with another MVC request from inside of the view (refer to RenderComponent in this posts)

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        2133 bytes

Concurrency Level:      100
Time taken for tests:   5.734375 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      2367000 bytes
HTML transferred:       2133000 bytes
Requests per second:    174.39 [#/sec] (mean)
Time per request:       573.438 [ms] (mean)
Time per request:       5.734 [ms] (mean, across all concurrent requests)
Transfer rate:          403.01 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.9      0      31
Processing:    62  543  96.6    562     640
Waiting:       46  539  96.6    562     640
Total:         62  543  96.7    562     640

Percentage of the requests served within a certain time (ms)
  50%    562
  66%    578
  75%    578
  80%    578
  90%    593
  95%    593
  98%    625
  99%    625
100%    640 (longest request)

Test #4: ASP.NET MVC with a simple user control rendered by html.RenderUserControl() from MVCToolKit

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        1212 bytes

Concurrency Level:      100
Time taken for tests:   4.578125 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1446000 bytes
HTML transferred:       1212000 bytes
Requests per second:    218.43 [#/sec] (mean)
Time per request:       457.813 [ms] (mean)
Time per request:       4.578 [ms] (mean, across all concurrent requests)
Transfer rate:          308.42 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.2      0      31
Processing:   140  426  85.3    453     531
Waiting:      109  423  87.7    453     515
Total:        140  427  85.1    453     531

Percentage of the requests served within a certain time (ms)
  50%    453
  66%    468
  75%    468
  80%    468
  90%    484
  95%    484
  98%    500
  99%    500
100%    531 (longest request)

 

Test #5: ASP.NET MVC with same user control rendered by tag

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        1212 bytes

Concurrency Level:      100
Time taken for tests:   4.250000 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1446000 bytes
HTML transferred:       1212000 bytes
Requests per second:    235.29 [#/sec] (mean)
Time per request:       425.000 [ms] (mean)
Time per request:       4.250 [ms] (mean, across all concurrent requests)
Transfer rate:          332.24 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.2      0      31
Processing:    78  401  69.5    421     468
Waiting:       78  398  69.5    421     453
Total:         78  401  69.5    421     468

Percentage of the requests served within a certain time (ms)
  50%    421
  66%    421
  75%    437
  80%    437
  90%    437
  95%    437
  98%    453
  99%    453
100%    468 (longest request)

How about a very complex page which need many "MVC modules/parts" ?

Sunday, January 13th, 2008

I discussed this question in ASP.NET MVC forums and get many feedbacks and discussion:

http://forums.asp.net/t/1196142.aspx

Co-exist of ASP.NET MVC and Web forms

Sunday, January 13th, 2008

MVC makes a web application’s architect quite clear, however in my point of view, MVC is not a great for all solution.

One of MVC’s pain points is handling the form submission. For a simple form submission, generally you need 2 action: ActionShowForm and ActionUpdateForm, the first action show a web form interface to let user edit the form, the second action is for submission. If you use server side form validation, it will be a little bit more complicated (depends on how you display those validation information to users).

Traditional ASP.Net web form can handle above form submission in very simple and straight forward way, with just one .aspx file and one code behind .cs file, complex web form handling is a easy and enjoyable work. It’s also very easy and without too much code to use ASP.NET ajax’s update panel to get fancy update free ajax form effect.

MVC frameworks has been used in Java web developing for a long time, look at what’s Java’s new movement?   It’s JSF(Java Server Face), something really like ASP.NET, it also have something similar to “view state” and “post back”. What a interesting thing it is:  after so many years working with MVC, Java guys are looking to web form alike “new” technology,  and after using web forms for so many years, ASP guys are so exciting about MVC. :)

In one of my experiment project, I used ASP.NET MVC together with the web form.  MVC is used as the major part of the web site, Web forms are used for all those form handling, they co-exist pretty well.

I create a folder named “forms”, and put all web forms files (aspx and cs) inside this folder. Though it’s ok to put them inside the “view” folder, I separated them because they are different  in modeling. The web forms share the same “Model” part (if it require to access the “model”), I use session data object to pass data in/out the  web forms.

Conventional Controller

Sunday, December 16th, 2007

ASP.NET MVC action method we need to call RenderView(”viewname”), ASP.NET MVC will look the viewname.aspx under “view/action/” and “view/shared”.  In Ruby On Rails, this step is not required, Rails will try to find same name view under view directory. 

Can we do that in ASP.NET MVC, Phil Haack has done this:

http://haacked.com/archive/2007/12/09/extending-asp.net-mvc-to-add-conventions.aspx

So instead of writing your controller like this:

public class HomeController : Controller
{
  [ControllerAction]
  public void Index()
  {
    //Your action logic
    RenderView("Index");
  }
}

Using my class you could write it like this

public class HomeController : ConventionController
{
  public void Index()
  {
    //Your action logic
  }
}

RenderView() into a buffer.

Sunday, December 16th, 2007

RenderView into a buffer and then we can do something on the result before output.

via: http://forums.asp.net/t/1193898.aspx

[ControllerAction]public void About(){	StringWriter interceptingWriter = new StringWriter();	TextWriter originalWriter = this.ControllerContext.HttpContext.Response.SwitchWriter(interceptingWriter);	RenderView("About");

	originalWriter.Write("The text written was: " + interceptingWriter.ToString());}
This is still raw, but we can have a customized controller class handle all those better. 
 

ASP.NET MVC Authentication links

Sunday, December 16th, 2007

Some links on learning ASP.NET MVC:

http://weblogs.asp.net/fredriknormen/archive/2007/11/25/asp-net-mvc-framework-security.aspx

[ControllerAction]
public void Edit(int? id)
{
if (!Roles.IsUserInRole(”Admin”))
throw new SecurityException(”Access denied”);
  …
}

To avoid writing this check in the Action methods we can instead use the PrincipalPermissionAttributes shipped with .Net:

[ControllerAction]
[PrincipalPermission(SecurityAction.Demand, Role="Admin"]
public void Edit(int? id)
{
   …
}

If we want to make sure all Action methods in a Controller have the check, we can add the PrincipalPermissionAttribute to the Controller class:

[PrincipalPermission(SecurityAction.Demand, Role="Admin")]
public class HomeController : Controller

If we want to handle the SecurityException we can use the ExceptionHandlerAttribute I wrote about in my previous post. This can catch the SecurityException and Render a View that will display the exception message.

[ControllerAction]
[PrincipalPermission(SecurityAction.Demand, Role="Admin"]
[ExceptionHandler("Error", typeof(SecurityException))]
public void Edit(int? id)
{
   …
}

If we don’t want to use the PrincipalPermissionAttribute and instead write our own Security handler, we can override the OnPreAction method and implement the security check. The OnPreAction method will be executed before any Action methods are executed.

protected override void OnPreAction(string actionName, System.Reflection.MethodInfo methodInfo)
{
if (actionName == “Edit”)
   {
if (!Roles.IsUserInRole(”Admin”) || !User.Identity.IsAuthenticated || !User.Identity.Name = “Administrator”)
throw SecurityException(”Access denied!”);
   }
}

http://forums.asp.net/t/1192300.aspx

You could always make a base controller and have your other controllers you want to secure extend it.

Example

public class SecureController : Controller

{

    public SecureController()

    {

        HttpContext context = HttpContext.Current;

        if (context.User == null || !context.User.Identity.IsAuthenticated)

        {

            // redirect to login.

      } 

    }

}

public class MemberController : SecureController

{

}

Implement Java servlet filter alike function in ASP.NET MVC

Saturday, December 15th, 2007

As a Java guys who turn to .NET, I always look for some nice stuff in Java inside .Net’s. 

Java’s Servlet filter is something good, I think in ASP.NET the similar concept is httpmodule (correct me if I am wrong). Filter is a great place to implement authentication, logging, auditing, data compression, transcoding, data transforming (e.g. XSLT), …etc.

When I am planning to add OpenID into ASP.NET MVC application, I couldn’t find a good enough place to put the OpenID authentication codes.

ASP.NET’s form authentication mode should be able to work together with ASP.NET MVC, I already see a blog article talk about this. The only change is configure an action URL in the form action loginUrl . Monorails also suggested its user to use this way.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    ...
    <system.web>
        <authentication mode="Forms">
            <forms name="auth" loginUrl="auth/login">
            ...
            </forms>
        </authentication>

I wish ASP.NET MVC could also support something like MonoRails’ filter. MonoRails filters are executed before and|or after actions. It is useful for security, dynamic content and to keep away repetitive code.

Fortunately, on Controller class there are some virtual functions which enable we do something before, after the action:

protected virtual bool OnError(string actionName, MethodInfo methodInfo, Exception exception);
protected virtual void OnPostAction(string actionName, MethodInfo methodInfo);
protected virtual bool OnPreAction(string actionName, MethodInfo methodInfo);

We can the implement some of our own controller class, so we can make it easier to implement something like Java servlet filters (and its chain).

Still learning… so maybe I am not that right…