Sunday, December 12, 2010

Behaviour of disabled controls in Asp.net

How to disable controls:
When we are developing web applications we need to disable/enable controls on the form. Controls which supports disabled are BUTTON, INPUT, OPTGROUP, OPTION, SELECT, and TEXTAREA.
Please do not try to disable a control which doesn’t support this attribute it may have weird behaviour.
We can set attribute disabled="disabled" OR $('#ctrlID').attr('disabled','disabled') OR
document.getElementById(' ctrlID'').setAttribute("disabled",'disabled');
We can enable controls by removing disabled from the elements.
What will change in behaviour of controls when you disable them?
If you are working with dynamic web application and you are disabling/enabling controls then you should remember some key effect of disabling control.
1) Disabled controls will not be posted when you submit form.
Because of this if you have changed value in disabled control dynamically by JavaScript. Then new value will not be posted back on the server and your server control will behave like normal html control.
Is there any way to submit disabled control?
In Asp.Net server side form control have one property called submitdisabledcontrols.
Setting submitdisabledcontrols="true" will submit disabled control values on the server.
 
Never disable hidden field controls.
Even though we set disabled hidden fields will not be submitted. So please keep in mind that you are not disabling hidden fields by knowing or unknowingly. Otherwise your may behave weird.

Tuesday, November 30, 2010

jQuery autocomplete with Asp.Net WCF service

jQuery autocomplete is a very good tool to provide user selection from a number of choices. We can easily create jQuery autocomplete with static JavaScript array. In this article we will see how we can use jQuery autocomplete with ASP.Net and WCF service.

In this article below version of scripts are used

jQuery version 1.4.1

jQuery UI version 1.8.6

We will create 2 example with WCF service.

First of all we will create a WCF service and configure it to response as json format.

We will bind endpoint with webHttpBinding. We will create service with name “AutoComplete” and our interface will be IAutoComplete. We will create an endpoint behavior which uses webHttp behavior. So our web.config file will have configuration as below.

 

<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="jQueryExamples.Services.AutoComplete.AutoCompleteBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="webHttpEndpoint"> <webHttp /> </behavior> </endpointBehaviors> </behaviors> <services> <service behaviorConfiguration="jQueryExamples.Services.AutoComplete.AutoCompleteBehavior" name="jQueryExamples.Services.AutoComplete.AutoComplete"> <endpoint address="" binding="webHttpBinding" contract="jQueryExamples.Services.AutoComplete.IAutoComplete" behaviorConfiguration="webHttpEndpoint"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel>

Now we will add reference of System.ServiceModel.Web to our application, because we will be using some of its features.

Example 1

In our first example of jQuery autocomplete, we will create a WCF service method which will return simple string array.

In our interface we will create method GetTagString which will return us string array.

[OperationContract] [WebInvoke(Method = "GET", UriTemplate = "GetTagString?term={term}", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] string[] GetTagString(string term);

In above declaration you will be able to find that apart from OperationContract there are some more attributes are assigned to method. WebInvoke attribute is part of System.ServiceModel.Web. WebInvoke adds meta data to the service method, provide operation behavior and verb on which method will be invoked. Method parameter will define which method will be used for invocation, we will use GET. UriTemplate will define url template in the service and bind url parameter to method parameter. We will use RequestFormat and ResponseFormat as WebMessageFormat.Json.

We will implement the interface and write below method into AutoComplete.svc file.

public string[] GetTagString(string term) { string[] tags = //Your logic to retive tags return tags.Where(t => t.StartsWith(term, StringComparison.InvariantCultureIgnoreCase)).ToArray(); }

Currently I have used static array of tags and then filtered it with LINQ to response only those items which are starting with the term our autocomplete have provided.

Now on the aspx page, we will create a html input and then add a script to add auto complete to it.

<div class="ui-widget"> <label for="tags"> Tags: </label> <input id="tags" /> </div>

And our script to initialize autocomplete will be

<script type="text/javascript" language="javascript"> $(function () { $("#tags").autocomplete({ source: "Services/AutoComplete/AutoComplete.svc/GetTagString" }); }); </script>

In the JavaScript function we have created autocomplete with URL to our AutoComplete.svc as source and followed by our method name which will be requested each time user hit a key.

So it will give us output as below.

image

This output and method of autocomplete is not much different from the original jQuery example. The only difference is we have created autocomplete with a WCF service.

Example 2

In above example we have created autocomplete with only names. In real life scenario we have different requirements as well. One of the scenario is when we retrieve a tag name we need its id as well. So how we will achieve it with modification in our above example.

To achieve it we need to first change original jquery.ui.autocomplete.js file. We will add our function into this file so that our example works perfect.

As first item we will add a “normalize” option in the autocomplete widget options. Its declaration will be look like-

$.widget("ui.autocomplete", { options: { appendTo: "body", delay: 300, minLength: 1, position: { my: "left top", at: "left bottom", collision: "none" }, source: null, normalize: null } //Further code

Second step will be the use of normalize function in code. We will modify the call in _response method. Now this method will look like -

_response: function (content) { if (content && content.length) { content = (this.options.normalize != null) ? this.options.normalize(content) : this._normalize(content); this._suggest(content); this._trigger("open"); } else { this.close(); } this.element.removeClass("ui-autocomplete-loading"); }

We have put a check that if normalize function defined by us is not null then we will call it otherwise we will call default _normalize function. You must have question that what does this normalize function will do. Normalize function will parse our service response and pass it to autocomplete so that it can generate the output.

HTML for second example is as below -

<div class="ui-widget"> <label for="tags"> Tags object: </label> <input id="tags2" /> <label id="lblId"> </label> </div>

In html we have added a label as “lblId” and we require autocomplete to add id of the tag to this label. You can also use hidden field to store the id. We will modify our WCF method, JavaScript to initialize autocomplete

We will create a class named Tags which will have property of tag name and id.

[DataContract] public class Tags { [DataMember] public int id { get; set; } [DataMember] public string tagName { get; set; } }

We have applied DataContract attribute to our class so that it can be transferred with out WCF service.

Our WCF Service Method definition in interface will be as below

[OperationContract] [WebInvoke(Method = "GET", UriTemplate = "GetTagObject?term={term}", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] List<Objects.Tags> GetTagObject(string term);

In above method we have returned a list of our class Tags. Hence implementation of this method will be as follows

public List<Objects.Tags> GetTagObject(string term) { List<Objects.Tags> lstTags = new List<Objects.Tags>(); //Logic to retive list of tags return lstTags.Where(t => t.tagName .StartsWith(term, StringComparison.InvariantCultureIgnoreCase)) .ToList(); }

In above example I have added items manually to list and then filtered it with LINQ to return desired output.

now we will initialize autocomplete with script

$(function () { $("#tags2").autocomplete({ source: "Services/AutoComplete/AutoComplete.svc/GetTagObject", normalize: function (items) { if (items.length && items[0].label && items[0].value) { return items; } return $.map(items, function (item) { return $.extend({ label: item.tagName, value: item.id }, item); }); }, select: function (event, data) { $('#tags2').val(data.item.tagName); $('#lblId').text(data.item.id); return false; } }); });

In above script we have specified two functions in the options. One is normalize and another is select. I will first explain normalize (which I have created with reference from jQuery’s original _normalize function) it will have items as input. When jQuery request to our service it will parse the response as json and pass it to normalize function. In first if block we have checked that whether json output contains label and value as attribute then we will return same items as output to process further. We will note here that if we always want to use label and value as class member then we do not need to modify autocomplete.js file. Now after the if block we have mapped our data with assigning tagName and id to label and value respectively. So autocomplete can parse our item and display us the autocomplete menu.

In select function we will specify that when user select an item how should it be processed with the data. In our case we have assigned tagName to our textbox value and id to our label text.

When we run our code it will provide us output as below

image

With this logic you can create your own autocomplete and even you can convert your dropdowns into a nice autocomplete.

Let me know if you have any query over it.

Thanks

Nirav

del.icio.us Tags: ,,

Wednesday, November 24, 2010

BlogEngine.NET 2.0 Release Candidate download available now

Release Candidate of BlogEngine 2.0 is available for download now.

In BlogEngine 2.0 below are some of new features are listed

  • A completely new Control Panel
  • Syntax Highlighter
  • Anti spam comment filter
  • Captcha for reduce comment spam
  • Included jQuery
  • Media element extension for HTML5 video support
  • JS/CSS minimization

Most stable version for BlogEngine is 1.6 till now.

You can find more information for BlogEngine on blogengine.codeplex.com You can try new BlogEngine 2.0 by downloading it from BlogEngine 2.0 Release Candidate

Keep up the good work BlogEngine team.

Tuesday, November 9, 2010

How To: Extension Methods with C#, definition and implementation of Extension Methods in code

We all know that there are many types in .Net Framework. Each type contains value, property(ies) and Methods. We can create derived types to use existing type properties and methods and add our own custom methods and properties. But in some cases we do not need to add any properties but only need to add some method which can be used, Extension Method provides a functionality with which we can create a method and use it with existing type and there is no need to create a derived type, isn’t it interesting?

In this article we will see how to define an Extension Method and how to use it. An Extension Method is static method to specially work with an existing type, but it will be called like it is part of original type. In coding there is not any difference between call of an y method defined in type or an Extension Method of the type.

As a type we can consider string, int, arrays of any type and even List, Collection or a DateTime can be treated as a type and we can create extension method for that.

First of all we will take example of string and create an extension method for it. Most of the time we need to check length of the string and then we need to remove extra characters beyond certain limit, lets create an extension method for it.

public static class StringExtension
    {
        public static string TrimToLength(this string objString, int Length)
        {
            return objString.Length > Length ? objString.Substring(0, Length) : objString;
        }
    }

In above example we have created a static class which will contains extension methods for string. And we have created a static method containing 2 arguments. Now first argument defines on which type the method will work and this argument is preceded with modifier this. Second argument and onwards if any will be arguments in the client calls. Method return types define what output our method will return. Now lets see how we will use above extension method in our code.

string s = "This is a dummy string";
Console.WriteLine(s.TrimToLength(100));
Console.WriteLine(s.TrimToLength(6));

Above implementation will generate output as below

This is a dummy string

This i

Lets take an example of DataReader. When we use data reader and we are retrieving data from various method we are using dataReader.GetString(dataReader.GetOrdinal("fieldName")) this method will raise error if the field value is null so we will modify our code to check the whether field is null or not with dataReader.IsDBNull(dataReader.GetOrdinal("fieldName")). Generally there are many fields and we need to check null for all of them. Lets see if we create extension method for it how much easily we can do for all of the fields.

public static class DataReaderExtension
{
    public static string GetStringOrDefault(this IDataReader dataReader, string fieldName)
    {
        return dataReader.IsDBNull(dataReader.GetOrdinal(fieldName)) 
            ? string.Empty 
            : dataReader.GetString(dataReader.GetOrdinal(fieldName));
    }
}

Implementation of the above method will be as below (dr is a SqlDataReader)

dr.GetStringOrDefault("fieldName1");
dr.GetStringOrDefault("fieldName2");
dr.GetStringOrDefault("fieldName3");

So you can see that we do not need to repeat our code of check of db null and get ordinal and we can directly use our single method.

We can create extension method for DateTime to calculate difference between date instance and current date. We can also create extension method with all the types which are inherited from System.Object.

 

Yours,

Nirav

del.icio.us Tags: ,

Tuesday, September 21, 2010

How to check query performance without profiler.

If you don’t have profiler installed and you just want to find out execution statistics of procedures, you can take help of DMVs. You can write T-SQL queries using DMV to gather execution statistics of SQL procedures.

You can extract following information using DMV regarding Procedure.

· How many times your stored procedure executed.

· Total number of cached plans.

· Identify Missing Indexes Using.

· Buffer Cache hit ratio example.

· SQL CLR Memory Usage

· And many more information we can find from below references.

Here is the sample query using DMV which if found from some good sites.

SELECT OBJECT_NAME(st.objectid,dbid) StoredProcedure
      ,max(cp.usecounts) Execution_count
 FROM sys.dm_exec_cached_plans cp
         CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
 where DB_NAME(st.dbid) is not null and cp.objtype = 'proc'
   group by cp.plan_handle, DB_NAME(st.dbid),
            OBJECT_SCHEMA_NAME(objectid,st.dbid), 
   OBJECT_NAME(objectid,st.dbid) 
 order by Execution_count desc.

SELECT TOP ( 100 )
        p.name AS [SP Name] ,
        deps.total_logical_reads AS [TotalLogicalReads] ,
        deps.total_logical_reads / deps.execution_count AS [AvgLogicalReads],
        deps.execution_count,
        ISNULL(deps.execution_count / DATEDIFF(Second, deps.cached_time,
                                           GETDATE()), 0) AS [Calls/Second],
        deps.total_elapsed_time,
        deps.total_elapsed_time / deps.execution_count AS [avg_elapsed_time],
        deps.cached_time
FROM    sys.procedures AS p
        INNER JOIN sys.dm_exec_procedure_stats
                       AS deps ON p.[object_id] = deps.[object_id]
WHERE   deps.database_id = DB_ID()
ORDER BY  deps.execution_count DESC

References:

http://glennberrysqlperformance.spaces.live.com/blog/cns!45041418ECCAA960!828.entry

http://technet.microsoft.com/en-us/library/cc966540.aspx

http://www.databasejournal.com/features/mssql/article.php/3687186/Monitoring-Stored-Procedure-Usage.htm

http://blogs.msdn.com/b/sqlprogrammability/archive/2007/01/23/4-0-useful-queries-on-dmv-s-to-understand-plan-cache-behavior.aspx

http://www.simple-talk.com/sql/t-sql-programming/dmvs-for-query-plan-metadata/

Though DMV are very powerful and we can find out any information about query execution. we can’t spend time to change them as our requirement. The thing we can do is keep DMV for some test cases ready and just run them when it comes to performance testing.

Profiler:

SQL profiler provides GUI to gather same data, only good thing about using SQL profiler will give you all the information separated by events, let’s say If you want to know that which statement in procedure force recompilation of plan?.

Well, if you prefer DMV you have to write DMV to find out how many time plans have re-used, and if you are running SQL profiler it will just log all the events and will show all the data at all point of execution. Also SQL profiler has many pre-defined templates which come handy when we are running profiler for collection different types of data.

You can see http://support.microsoft.com/kb/243586 for more details about Troubleshooting stored procedure recompilation

But the point when I would like to Use DMV over Profiler is, when your application is in development mode you can use SQL profiler wisely running and seeing data. But once application is running on production server it is very time cumbersome to run profiler and then find which procedure have taken maximum time to execute.

In this case you can just run one Query and result will be in front of you….NICE….

Hope this will help you.

Any input always invited.

Thursday, September 2, 2010

CustomValidator validation in Repeater with RegisterExpandoAttribute and ClientValidationFunction JavaScript

Hi All,

ASP.Net comes with many validators, one of the validator is CustomValidator. We can use custom validator in 2 ways, either client side or server side validation.

In this post I will provide information specifically on client side validation. Client side validation is achieved with JavaScript function. JavaScript function sample is as below

function MyClientValidation(source, arguments) {
       if ( your validation condition ){
            arguments.IsValid = true;
       } else {
            arguments.IsValid = false;
       }
}

 

Now we will call above function with ClientValidationFunction property of custom validator mentioned as below.

   1:  <asp:CustomValidator ID="MyValidator" runat="server" ClientValidationFunction="MyClientValidation"></asp:CustomValidator>

 

It is simple to call client validation function with a custom validator.

Now you must have question, why I am writing this basic thing for a client validation. Client validation function is really simple when we write validator and control which we are validating both are on page directly. But there is a scenario where this simple method will not work.

In this post I will explain how to use CustomValidator with client side validation when validator is within a Repeater or a ListView control.

We will go through scenario when a CustomValidator is inside a Repeater control. We will have 3 items in Repeater.

  1. A CheckBox control
  2. A TextBox control
  3. And a CustomValidator

Now as per scenario we need to validate TextBox text when check box for same row is selected.

Below will be html for the Repeater:

<asp:Repeater ID="rptItem" runat="server" OnItemDataBound="rptItem_ItemDataBound">
      <HeaderTemplate>
          <table>
      </HeaderTemplate>
      <ItemTemplate>
          <tr>
              <td>
                  <asp:CheckBox ID="chkSelectItem" runat="server" />
              </td>
              <td>
                  <asp:TextBox ID="txtToValidate" runat="server"></asp:TextBox>
              </td>
              <td>
                  <asp:CustomValidator ID="cValidation" runat="server" ClientValidationFunction="MyClientValidation"
                      ErrorMessage="Invalid"></asp:CustomValidator>
              </td>
          </tr>
      </ItemTemplate>
      <FooterTemplate>
          </table>
      </FooterTemplate>
</asp:Repeater>

I have registered item data bound event over here to do some code.

We have set the html for our scenario, now custom validator need to validate only those textbox for which corresponding checkbox is selected. We will achieve it with ClientScript.RegisterExpandoAttribute method. ClientScript.RegisterExpandoAttribute is used to register custom attributes for your ASP.Net server controls on runtime. Below is the code to register custom attributes.

protected void rptItem_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
      {
          CheckBox chkSelectItem = e.Item.FindControl("chkSelectItem") as CheckBox;
          TextBox txtToValidate = e.Item.FindControl("txtToValidate") as TextBox;
          CustomValidator cValidation = e.Item.FindControl("cValidation") as CustomValidator;

          if (chkSelectItem != null && txtToValidate != null && cValidation != null)
          {
              ClientScript.RegisterExpandoAttribute(cValidation.ClientID, "chkId", chkSelectItem.ClientID);
              ClientScript.RegisterExpandoAttribute(cValidation.ClientID, "txtId", txtToValidate.ClientID);
          }
      }
}

 

Once we register above method in code behind of page and run the page, it will register some script dynamically as below.

var MainContent_rptItem_cValidation_0 = document.all ? document.all["MainContent_rptItem_cValidation_0"] : document.getElementById("MainContent_rptItem_cValidation_0");
MainContent_rptItem_cValidation_0.chkId = "MainContent_rptItem_chkSelectItem_0";
MainContent_rptItem_cValidation_0.txtId = "MainContent_rptItem_txtToValidate_0";
MainContent_rptItem_cValidation_0.errormessage = "Invalid";
MainContent_rptItem_cValidation_0.evaluationfunction = "CustomValidatorEvaluateIsValid";
MainContent_rptItem_cValidation_0.clientvalidationfunction = "MyClientValidation";

 

Now we need to modify our JavaScript function in such a way that will use our custom registered attributes to validate the control. Modification is as below.

 
function MyClientValidation(source, arguments) {
      var chkBox = document.getElementById(source.attributes["chkId"].value);
      var txtBox = document.getElementById(source.attributes["txtId"].value);
      if (chkBox.checked == true) {
          var re = new RegExp("[0-9]+");
          if (re.test(txtBox.value)) {
              arguments.IsValid = true;
          }
          else {
              arguments.IsValid = false;
          }
      } else {
          arguments.IsValid = true;
      }
}

 

Now we have set all, our validation function will validate textbox with numeric value and non empty and should only validate those textboxes for which checkbox is checked.

Here is the output of our code.

image

You can modify the JavaScript function as per your requirement. also you can register more expando attributes if you require. But note that it will rendered on the client side and will considerably increase your client script.

Now if you are binding your repeater in an UpdatePanel then you need to register the expando attribute somewhat differently as below

   1:  ScriptManager.RegisterExpandoAttribute(MyUpdatePanel, cValidation.ClientID, "chkId", chkSelectItem.ClientID);
   2:  ScriptManager.RegisterExpandoAttribute(MyUpdatePanel, cValidation.ClientID, "txtId", txtToValidate.ClientID);

Hope you liked this post and it helped you.

Any question or suggestion is welcome.

 

Thanks,

Nirav

Thursday, August 26, 2010

Manipulate Dynamic DOM elements in JavaScript with JQuery

JQuery have a huge set of selectors to manipulate DOM elements. But when it comes to manipulate dynamically generated elements it needs some logic to access all of them and perform operation.

Ex. Suppose you want to check all checkboxes inside GridView OR any DataBound control, you need to loop over them and perform operation.

To loop over them you need to access them by ID or by class, now because IDs are dynamically generated you can’t access them directly.  You can have two solutions in this scenario.

 

Case-1: You can give unique class to them and find them by class name.

 

Suppose you have a Grid having textboxes in one column. You want to change text of all of them to

‘Deleted’, when user check the checkbox in  Header.

   <div id="dvProducts">

        <asp:GridView ID="grvProducts" runat="server">

            <Columns>

                <asp:TemplateField>

                    <HeaderTemplate>

<asp:CheckBox ID="chkAllProduct" runat="server" onclick="chkSetStatus_Click(this.checked)" />

                    </HeaderTemplate>

                    <ItemTemplate>

<asp:TextBox ID="txtStatus" runat="server" CssClass="dummyForSelect"></asp:TextBox>

                    </ItemTemplate>

                </asp:TemplateField>

            </Columns>

        </asp:GridView>

    </div>

Here is the function which will perform this operation.

function chkSetStatus_Click(ischecked) {

            $('.dummyForSelect', $("#dvProducts")).each(

                                        function(d, obj) {

                                        if(ischecked)

                                            obj.value = 'Deleted';

                                            else

                                                obj.value = '';

                                        });

        }

 

Case-2: You can use pattern of generated IDs and find them using regular expression.

 

Suppose you have a Grid having Checkboxes in one column. You won’t to check all when checkbox in the header checked, and remove selection when user unselects it.

 

  <div id="dvProducts">

        <asp:GridView ID="grvProducts" runat="server">

            <Columns>

                <asp:TemplateField>

                    <HeaderTemplate>

         <asp:CheckBox ID="chkAllProduct" runat="server" onclick="chkAllProduct_Click(this.checked)" />

                    </HeaderTemplate>

                    <ItemTemplate>

                        <asp:CheckBox ID="chkProduct" runat="server"  />

                    </ItemTemplate>

                </asp:TemplateField>

            </Columns>

        </asp:GridView>

    </div>

You can’t use CssClass here because it will not work for you, you have to use pattern in which ID of checkboxes is generated.

ID generated by asp.net will be “grvProducts_ctl03_chkProduct”, we need to make RegEx to find out checkboxes with such pattern and make operation on them.

So our RegEx will look like this var rExp = /.*grvProducts.*chkProduct/;

Using this we can write JavaScript function below to finish task.

function chkAllProduct_Click(ischecked) {

            var rExp = /.*grvProducts.*chkProduct/;

            $('input:checkbox', $("#dvProducts")).each(

                                        function(d, obj) {

                                            if (rExp.test(obj.id)) {

                                                obj.checked = ischecked;

                                            }

                                        });

        }

 

This is the tasks becomes too easy because of the JQUERY. Please put your suggestion here if any.

 

Hope this will help you.

 

Thanks,

Haresh Dhameliya