Sunday, December 30, 2007

Enhance Data View Performance using Asynchronous Method

Currently I find a way how to enhance a performance to view 10.000 records which taken from Web service layer.

First of all, I can not using any caching because this data will change very often.
Every time the user change something, I need to refresh the data.

I can not use Sql Dependency because all the data are encapsulate on service layer.
I can not perform paging on service layer because it is not provided to me.


Finally, the only way is using Asynchronous Method.

The idea is to display the first page of the records and start retrieving others data asynchronously.

The next time the user want to perform, sorting, filtering or paging, It will force to finish all retreiving data.

This algorithm will force using user thinking time in retreiving huge records rather than forcing user to wait retrieving huge records every time even they just want to see the first page records.

Here is the Algorithm:
=================================
If ( ! IsPostback)
{
* Clear Data set from session
* Retrieve 1st page only and bind to data grid with next/previous paging style
* Create a delegate to retrieve the rest of data
* Start asynchronous call with BeginInvoke.
* Store that delegate and IAsynResult into session.
}
else
{ //( Postback) and user try to bind a data (Sorting, Paging, Filtering)
If (There still no data set in Session)
{
* Take delegate and IAsynResult
* Force delegate to finish by using EndInvoke(IAsynResult)
* Store the data set into Session.
* Bind to data grid with default paging style.
}
else
{
* directly use data set from session and bind to data grid with default paging style.
}
}
===============================

Note:
You may optimize this algorithm by getting a number of record first.
If the number of records is less or equal then the number of first page records, just store that data into session and bind it to data grid with default paging style.
You don't need to perform asynchronous call for this.


The only weakness of this methodology is it will be more thread in your application.

Sunday, December 16, 2007

Notify your custom application from CRM 3.0

This is one of the solution how you notify your application from Microsoft Dynamic CRM 3.0

1. Add Javascripts to notify your application from CRM Custom forms.
a. Open CRM 3.0

b. Go To Settings/ Customization

c. Select what entity you need ( Example phone, email, ...)

d. Go to forms and view on the left tab after you open your entity

e. Select the forms you want to add the scripts.

f. click add properties.

g. There is 2 available event handler (OnSave and OnLoad)

h. Put your javascript there
for example : window.opener('Notify on save');

i. Don't forget to check enable this event before you save it.

j. You may preview it before publish the changes.

g. Don't forget to publish - Action/Publish.

If you forget to publish, It will not take any changes you have made, even you have save it.

Friday, December 14, 2007

Better way to handle thread abort exception in Response.Redirect

private bool m_bIsTerminating = false;

protected void Page_Load(object sender, EventArgs e)
{
if (WeNeedToRedirect == true)
{
Response.Redirect(url, false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
m_bIsTerminating = true;
// remember to end the method here if
// there is more code in it

return;
}
}

protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
if (m_bIsTerminating == false)
base.RaisePostBackEvent(sourceControl, eventArgument);
}

protected override void Render(HtmlTextWriter writer)
{
if (m_bIsTerminating == false)
base.Render(writer);
}

Friday, November 16, 2007

Datagrid VS ViewState

This week, I try to optimized my web application which using 10 million record.

The first thing that I notice that EnableViewState by default is set to true.

So my datagrid will store all the view state into client. so every time there is postback or asyn postback, it will transfer heaps of data through networks. and It is not very efficient.

So I try to disable them by EnablingViewState = false.
However by disabling view state in the data , all the events in datagrid is not fired..


one of the solution is to disable view state on each item.
_dg.DataBind();
foreach (DataGridItem item in _dg.Items)
{
item.EnableViewState=false;
{


however, if your all commandArguments is not work,..

so the other solution is you need to bind every time in page back...

Tuesday, November 6, 2007

Resurrection

Just in case if you don't know.

Sometimes it is you may need to resurrects your object.
for example you want the object to clean itself gracefully everytime the object dies.

Here how to do resurrection....

public class MyBaseClass
{
Protected override void Finalize()
{
//TODO: Some Clean up....

GC.ReRegisterForFinalize(this);
}
}

By calling GC.ReRegisterForFinalize method, it will appends the address of the specified object to the end of the finalization queue. When GC detects that this object is unreadchable again, It will queue the object's pointer ob the freachable queue and Finalize method will get called again.

This is example show how to create an object that constantly resurrects itself and never dies...
which usually undesireable. It is far more common to conditionally set a root to a reference the object inside the finalize method.

Tuesday, October 30, 2007

Sys.WebForms.PageRequestManagerParserErrorException

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.


this is the most annoyed error , That I ever had.

It happens only the first time after I restart my web application / after change web.config.

I still keep getting that error even I have try to alter my code based on this
--------------------------------------------------------------------------------------
  1. Calls to Response.Write():
    Place an or similar control on your page and set its Text property. The added benefit is that your pages will be valid HTML. When using Response.Write() you typically end up with pages that contain invalid markup.
  2. Response filters:
    The fix might just be to not use the filter. They're not used very often anyway. If possible, filter things at the control level and not at the response level.
  3. HttpModules:
    Same as response filters.
  4. Server trace is enabled:
    Use some other form of tracing, such as writing to a log file, the Windows event log, or a custom mechanism.
  5. Calls to Server.Transfer():
    I'm not really sure why people use Server.Transfer() at all. Perhaps it's a legacy thing from Classic ASP. I'd suggest using Response.Redirect() with query string parameters or cross-page posting.

Another way to avoid the parse error is to do a regular postback instead of an asynchronous postback. For example, if you have a button that absolutely must do a Server.Transfer(), make it do regular postbacks. There are a number of ways of doing this:

  1. The easiest is to simply place the button outside of any UpdatePanels. Unfortunately the layout of your page might not allow for this.
  2. Add a PostBackTrigger to your UpdatePanel that points at the button. This works great if the button is declared statically through markup on the page.
  3. Call ScriptManager.RegisterPostBackControl() and pass in the button in question. This is the best solution for controls that are added dynamically, such as those inside a repeating template.

-------------------------------------------------------

After I give up... The only solution is to add enableEventValidation="false" in the Page attribute.

Probably it is not the best solution because the event validation mechanism reduces the risk of unauthorized postback requests and callbacks. When the EnableEventValidation property is set to true, ASP.NET allows only the specific events that can be raised on the control during a postback request or callback. In this model, a control registers its events during rendering and then validates the events during postback or callback handling.

However after debugging I relies that It throw that error after I write into a session which I never write anything in the beginning. which cause the event validation not valid

So another solution is if EnableEventValidation is so important then
put it back EnableEventValidation = true then
in your Page_Load Event,
put
----------------------
Session["something"] = true; in your page load event.

This will create the cookie needed for the session variable to work, and therefore anything using a session will also work without throwing the error.

---------------------

This solution needed if there is no session ha s been initialize but when there is asynchronous postback, you put a session and EnableEventValidation is true

Monday, October 29, 2007

The Simplest Javascript to convert to hexadecimal in Javascript

function toHexa(d) {return d.toString(16);}

function toDec(h) {return parseInt(h,16);}

Saturday, September 22, 2007

As Keyword in C#

The "as" keyword in C# attempts to cast an instance to a specific type and if it fails returns null.

What is the different between explicitly cast ?

string str = (string) Request["nullSession"];
string str = Request["nullSession"] as string;

Both of them return the same (NULL)...

However probably, I will stick with my casting style because
1. It confused me when I need to convert from C# to VB
2. I can not using as keyword to replace
(int) 123.23
where I expect to get 123 as integer

----
123.21 as int

//throws The as operator must be used with a reference type ('int' is a value type)

123.21 as int16
//throws The as operator must be used with a reference type ('short' is a value type)

123.21 as double
//throws The as operator must be used with a reference type ('double' is a value type)


Saturday, September 8, 2007

JSON AJAX Localization

It may be annoying when you need to have several languages in your web sites..

There is several way... to implement localization your web content in the client..

you either create a control and attached those assembly to your web site...
or just use... JSON object...

My preference is using JSON ( Javascipt Object Notation)....

* Create.. JSON Resource JS file for each.. languange...
Resource.js
MyReourceText={
"HeaderTitle":"Hello World",
"FooterText":"CopyRight By Kurniawan"
}

Resource.fr.js
MyReourceText={
"HeaderTitle":"Header Title in France",
"FooterText":"CopyRight By Kurniawan in france"
}


* Create.. UpdateResource js - this script will update your content use specific localize language.
Note:
-saperate this file from Resource.js...so you will not duplicate your code


UpdateResource.js

Sys.Application.add_load(SetupForm);
function SetupForm()
{
$get('HeaderTitle').innerText = MyReourceText.HeaderTitle;
$get('FooterText').innerText = MyReourceText.FooterText;
}



*
In your aspx... add enable EnableScriptLocalization="true" in your ScriptManager
This will enable the


*
Add those script reference into your script Manager
<asp:ScriptReference Path="Resource.js" ResourceUICulture="fr" />
<asp:ScriptReference Path="UpdateResource.js" />


**** THAT'S ALL ****

You may change your language from the browser or
from the your own control.... by using this...
System.Threading.Thread.CurrentThread.CurrentUICulture =
System.Globalization.CultureInfo.CreateSpecificCulture(cmbLang.SelectedValue);

and you can get the current language from your browser when not postback
cmbLang.Items.FindByValue(System.Threading.Thread.CurrentThread.
CurrentUICulture.TwoLetterISOLanguageName).Selected = true;

****

You may enable globalization.. to formating your date / currency into specific languange../ culture...

by activate EnableScriptGlobalization = "true" in Script Manager...
You can use
d.localeFormat("dddd, dd MMM yyyy");

****

Thursday, September 6, 2007

XAML ???

X A M L ??? (ZAMMEL) Yes, That's the correct spelling...

It extends for Extendsible Application Markup Language.
ZAMMEL is Xml based language to define object and their properties ...

It focused on UI for WPF/E (Windows Presentation Foundation/Everywhere)

You may check out Silverlight to begin with XAML.

Here is the Zammel Sample
<object>
<child property="x" property="y">
<child.property>
<class property="u" property="v"/>
</child.property>
</child>
<child>
</child>
</object>


Note:
* Xaml is different with WPF - Xaml is Xml based Markup
WPF is a graphics API

*
XAML also supports things like 3D and controls, which SVG does not. It's different from SVG

* Saparate Design and Development

F# ???

F# -
Functional language ???
Why do we need to learn that language ???

So far I know... this language is meant to be more mathematical at heart, and thus creates more separation between the lower level machine details and the developer's code.

functional programming is supposed to be a "higher level" of programming than Java or C.

#light
(* Sample Windows Forms Program *)

(* We need to open the Windows Forms library *)
open System.Windows.Forms

(* Create a window and set a few properties *)
let form = new Form(Visible=true, TopMost=true, Text="Welcome to F#")

(* Create a label to show some text in the form *)
let label =
let temp = new Label()
let x = 3 + (4 * 5)
(* Set the value of the Text*)
temp.Text <- x
(* Remember to return a value! *)
temp

(* Add the label to the form *)
do form.Controls.Add(label)

(* Finally, run the form *)
do Application.Run(form)

Generic.Dictionary Serializable ?

so far I know that Generic.Dictionary is not serializable by default in .Net 2.0

One of the implication is when you put your dictionary in the session of Asp.net...
You will get problem... You will get an error when serializer run and
try to get your session ship out of your web service....

Here is the code... to

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml.Serialization;

[XmlRoot("dictionary")]

public class DictionarySerializable

: Dictionary, IXmlSerializable

{

#region IXmlSerializable Members

public System.Xml.Schema.XmlSchema GetSchema()

{

return null;

}

public void ReadXml(System.Xml.XmlReader reader)

{

XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

if(reader.IsEmptyElement) return;

reader.Read();

while (reader.NodeType != System.Xml.XmlNodeType.EndElement)

{

reader.ReadStartElement("item");

reader.ReadStartElement("key");

TKey key = (TKey)keySerializer.Deserialize(reader);

reader.ReadEndElement();

reader.ReadStartElement("value");

TValue value = (TValue)valueSerializer.Deserialize(reader);

reader.ReadEndElement();

this.Add(key, value);

reader.ReadEndElement();

reader.MoveToContent();

}

reader.ReadEndElement();

}

public void WriteXml(System.Xml.XmlWriter writer)

{

XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

foreach (TKey key in this.Keys)

{

writer.WriteStartElement("item");

writer.WriteStartElement("key");

keySerializer.Serialize(writer, key);

writer.WriteEndElement();

writer.WriteStartElement("value");

TValue value = this[key];

valueSerializer.Serialize(writer, value);

writer.WriteEndElement();

writer.WriteEndElement();

}

}

#endregion

}

Get bored with Web Service ???

Are you get bored with Web Service Technology ?

Yeah... Probably... It has been too old for us....

Check it out Microsoft Astoria - Data Service....
http://astoria.mslivelabs.com


You may try to deploy your database into Web Data Service

It is also supported by ASP.NET Futures (May 2007)

Iron Phyton with ASP.Net Futures

Here is the example... how to nice it is using Iron phyton to filter your Grid View which generated from DynamicList

* Restrict your column...
def GetColumns() :
return ["Column1","Column2",....]

* Add your custom column
def GetColumns() :
return ["Column1","Column2",....
["My Custom Column", lambda: "%s (%s)" % (Column3, Column4)]
]

* Rule level formating for your view
From System.Drawing import Color
def InitRow(row):
if "myKeyword" in Column1 :
row.BackColor = Color.Green


How easy it is ????

Dynamic Data Component in ASP.NET Futures

These are the details of Dynamic Data Components , If you want to play around with the code...

* DynamicAutoData - It will build the presentantion of your tables
Master, Detail, Insert RSS Links

* DynamicList - Build Grid View for your table

* Dynamic Details - Build the details for your master tables...

* Dynamic Insert - Build the insert new data form for your table...

* Dynamic Rss Link - Burn your page into.. RSS feed

* Dynamic Filter - Filter.. your table...

Codeless in .Net Futures

Please Check out this...
It's amazing, You don't need to write anything to View all your database through .Net Futures...

* Create Web Site with DynamicDataWebSite Template...

* Add your Database into APP_Data

* Open your web.config

1. Enable showAllTables by change false into true
<dynamicDataControls showAllTables="true" >

2. and uncoment auto.axd inside httpHandlers


---- That's ALL --------------------------

All has been build for you
* List all of your tables
* Master Detais
* Insert Update Delete
* RSS Links....

What else do you need?

Wednesday, September 5, 2007

Embed your javascript file into single DLL

If you want your javascript hidden or secure inside the dll...

Please see this step... to embed your javascript file (*.js) into your dll.

  • Go to the property of the javascript file (Right Click in *.js file)
  • Change Build Action to Embeded Resource (Default is content)

  • Go To AssemblyInfo.vb (Turn on Show All file to see that file)
  • Add <AssemblyL System.Web.
    UI.WebResource("YourNameSpace.YourJSName.js", "application/x-Javascript")>

  • Register to Page control.Page.ClientScript.RegisterClientScriptResource
    (typeOf(yourClassName),"YourNameSpace.YourJSName.js");
OR if available
  • Register to AjaxToolkit.ScriptManager using Reflection

    System.Type
    _ScriptManager = Type.GetType
    ("System.Web.UI.ScriptManager , System.Web.Extension");

    if (_ScriptManager == null)
    throw new Exception(" Use... the other register above");

    System.Reflection.MethodInfo
    _RegisterClientScriptResourceMethod =
    _ScriptManager.GetMethod("RegisterClientScriptResource",new Type()
    {typeof(System.Web.UI.Control), typeof(Type), typeof(System.String)} );


    _RegisterClientScriptResourceMethod.Invoke(Nothing, new Object()
    (this,typeOf(yourClassName),"YourNameSpace.YourJSName.js");

Building your own Ajax

So far, I know there is 3 Tutorials which good to see before you build your own control...

The best one is using AjaxToolkitTemplate-Extender...
See - AjaxToolkit Documentation on the left bottom corner.
According to me.. this Ajax design is easy to use and very consistet with ajaxToolkit...

However.. there is another... Video Tutorial can be found in the www.asp.net/learn/ajax
  • "WinVideo-ASP-AjaxCustomAjaxControl" - Build User Control embeded into single dll
  • "WinVideo-ASP-AjaxEnableYourCustomControl" - Build Web UserControl in different DLL

Saturday, August 25, 2007

Ajax Service Method

1. Create web service with [System.Web.Script.Services.ScriptService()] attribute in class level

2. add Service Reference... in service manager
asp:ServiceReference Path="MyAjaxService.asmx"


3. Add javascript method

function Bt1_OnClick()
{
MyAjaxService.SayHello("Kurniawan",OnComplete,OnError);
}

function OnComplete(result)
{
alert("OnComplete : " + result);
}


function OnError(result)
{
alert("OnError : " + result._message);
}

Thursday, August 23, 2007

using AjaxPro2.dll from Michael Schwarz

*Add web Config configuration/configSections

section name="ajaxSettings" type="AjaxPro.AjaxSettingsSectionHandler, AjaxPro.2"



*Add web Config configuration/system.web/httpHandlers
add verb="*" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro.2"



*add reference AjaxPro2.dll into the bin folder
using AjaxPro;

* in page load (postback and not) - add
Utility.RegisterTypeForAjax(typeof(_Default));

*
On client ajax method add attribute
[AjaxMethod(HttpSessionStateRequirement.ReadWrite)]
public string MyAjaxMethod(string username)
{
return "Halo" + UserName;
}


*call in client javascript
_Default.MyAjaxMethod("Kurniawan").value