Friday, January 28, 2011

Documentation of C# Code with SandCastle and Visual Studio 2010

In this post I'll show you, how you can create a documention of your code. In the past ndoc was the tool to create code docus but the project seems to be dead. Therefore we use SandCastle, a freeware tool, that is also used by Microsoft to create Code-Documentations.

Here is the reference of the comments within visual studio:



First of all you need to install these things in the given order.

Before you can create the code documentation, you have to create the documentation XML in Visual Studio. Therefore open your solution. Open the properties of a project within the solution.

Open Properties

Now in the build tab check the "XML Documentation File". The xml is now generated in the \bin\Debug folder. Of couse you can enter your own path if necessary.



Now rebuild your solution and check if a xml file exists beside the newly created dll.



The next steps are to open the GUI (SandCastel Help File Builder) and create a new project. You should find the gui in your start menu > programs.


I don't want to reinvent the whell therefore, I forward you to some other sites. These sites can explain the next steps certainly better than I can. If you choose the Step by Step Tutorial, you can now start by step 4.

Thursday, January 27, 2011

HttpModule to check the performance of a (sharepoint) site

I want to share the code of a http module I made for checking the performance of the backend site creation process. The result indicates if the site will break down when its launched and used by tausends of people. You can leave this module in your solution and activate it everytime you have to check the performance of a webpart or control. The module is simply activated by inserting an entry in the web.config.

When you type perf=1 in the querystring (ex. http://mydomain.com/pages/default.aspx?perf=1) than a little yellow div will appear on the upper left corner, that displays the information.

Performance of the backend process


First we create a new class and implent the IHttpModule interface. We implement the init method, which is the starting point.There we have to create two delegates, that process the request.

In an other class we implement the PerformanceFilter to manipulate the outputstream of the request. Here we read the stream an place a div with the information when we find the </body> tag


1:  using System;  
2:  using System.Collections.Generic;  
3:  using System.Linq;  
4:  using System.Text;  
5:  using System.Web;  
6:  using System.Diagnostics;  
7:  using System.IO;  
8:  namespace MyProject.Intranet.SharePoint.CommonLib.HttpModules  
9:  {  
10:    /// <summary>  
11:    /// A http module to check the performance of a sharepoint site  
12:    /// The module is activated when you put perf=1 as parameter in the querystring  
13:    /// Autor: I.Bikmaz  
14:    /// </summary>  
15:    public class PerformanceMonitor : IHttpModule  
16:    {  
17:      /// <summary>  
18:      /// In this method the request is intercepted and the timer begins  
19:      /// </summary>  
20:      public void Init(HttpApplication context)  
21:      {  
22:        context.PreRequestHandlerExecute += delegate(object sender, EventArgs e)  
23:        {  
24:          //Set Page Timer Star  
25:          HttpContext requestContext = ((HttpApplication)sender).Context;  
26:          Stopwatch timer = new Stopwatch();  
27:          requestContext.Items["Timer"] = timer;  
28:          timer.Start();  
29:        };  
30:        context.PostRequestHandlerExecute += delegate(object sender, EventArgs e)  
31:        {  
32:          HttpContext httpContext = ((HttpApplication)sender).Context;  
33:          HttpResponse response = httpContext.Response;  
34:          Stopwatch timer = (Stopwatch)httpContext.Items["Timer"];  
35:          timer.Stop();          
36:          // Don't interfere with non-HTML responses  
37:          if (response.ContentType == "text/html")  
38:          {            
39:            bool addPerformanceHtml = httpContext.Request.Url.ToString().Contains("perf=1");  
40:            if (addPerformanceHtml)  
41:            {  
42:              double seconds = (double)timer.ElapsedTicks / Stopwatch.Frequency;  
43:              string result_time = string.Format("{0:F4} sec ", seconds);  
44:              response.Filter = new PerformanceFilter(response.Filter, result_time);              
45:            }  
46:          }  
47:        };  
48:      }  
49:      /// <summary>  
50:      /// Disposal  
51:      /// </summary>  
52:      public void Dispose()  
53:      {  
54:      }  
55:    }  
56:    /// <summary>  
57:    /// Filter to manipulate the output stream  
58:    /// </summary>  
59:    public class PerformanceFilter : MemoryStream  
60:    {  
61:      private Stream mStream;  
62:      private StreamWriter mStreamWriter;  
63:      private String mTime;  
64:      /// <summary>  
65:      /// Constructor  
66:      /// </summary>  
67:      /// <param name="stm">The stream to filter</param>  
68:      /// <param name="time">The time to display</param>  
69:      public PerformanceFilter(Stream stm, String time)  
70:      {  
71:        mStream = stm;  
72:        mStreamWriter = new StreamWriter(mStream, System.Text.Encoding.UTF8);  
73:        mTime = time;  
74:      }  
75:      /// <summary>  
76:      /// Writes the new stream  
77:      /// </summary>  
78:      /// <param name="buffer"></param>  
79:      /// <param name="offset"></param>  
80:      /// <param name="count"></param>  
81:      public override void Write(byte[] buffer, int offset, int count)  
82:      {  
83:        MemoryStream ms = new MemoryStream(buffer, offset, count, false);  
84:        StreamReader sr = new StreamReader(ms, System.Text.Encoding.UTF8);  
85:        String s;  
86:        while ((s = sr.ReadLine()) != null)  
87:        {  
88:          s = s.Trim();  
89:          if (s == "</body>")  
90:          {            
91:            mStreamWriter.Write(String.Format("<div style=\"padding:5px; background:yellow; width:110px; height:25px; position:absolute; left:0;top:0\">Page generated in {0}</div>", mTime));            
92:          }  
93:          mStreamWriter.WriteLine(s);  
94:        }  
95:        mStreamWriter.Flush();  
96:      }  
97:    }  
98:  }  

After adding code to your solution you have to activate the http module by adding a web.confog entry. In SharePoint 2010 you should add the entry at the bottom  of the modules tag:


 <modules runAllManagedModulesForAllRequests="true">  
  <remove name="AnonymousIdentification" />  
  <remove name="FileAuthorization" />  
  ....  
  <add name="PublishingHttpModule" ...  
  <add name="PerformanceHttpModule"   
   type="MyProject.Intranet.SharePoint.CommonLib.HttpModules.PerformanceMonitor, MyProject.Intranet.SharePoint.CommonLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxx" />  
 </modules>  

Tuesday, January 18, 2011

RegularExpressionValidator autocomplete enter key problem in firefox

I had some problems with the regularexpressionvalidator in firefox today. When I selected a value from the browsers autocomplete box, the field was validated to false.

Autocomplete in firefox

The validator throws an error

The RegularExpressionValidator checks if the insert email address has the right format. If not than the validator outputs an error. In my case when I hit the enter key in the autocomplete box for the field, the validator message appeared, but when I hit the tab key all was fine.

I digged a little into the javascript and found out that when I pressed Enter the value for the field to check in forefox was only the first character of the value entered. Therefore this was not a valid email address

Then I found this post, that describes that this is a firefox bug

The only solution for this problem seems to override the Microsoft core ValidateTextBoxOnKeyPress function somewhere in your page and check if the function is called in firefox. (I used here the JQuery browser method )

1:  function ValidatedTextBoxOnKeyPress(event) {  
2:    if (event.keyCode == 13 && !$.browser.mozilla) {  
3:      ValidatorOnChange(event);  
4:      var vals;  
5:      if ((typeof(event.srcElement) != "undefined") && (event.srcElement != null)) {  
6:        vals = event.srcElement.Validators;  
7:      }  
8:      else {  
9:        vals = event.target.Validators;  
10:      }  
11:      return AllValidatorsValid(vals);  
12:    }  
13:    return true;  
14:  }  


The probably easier variant is to force Firefox to hide the AutoComplete popup by adding the property autocomplete="off" to the input field.


<input type="text" autocomplete="off" value=".." name=".." />


or in ASP


<asp:TextBox runat="server" autocomplete="off" Text"..." />