Tuesday, April 19, 2011

ClientIDMode = “Predictable” broke my dropdown list auto partial postback

In my previous post, I try to upgrade my recent .NET web apps to use recent .NET for capabilities by doing this

<pages controlRenderingCompatibilityVersion="4.0">






But unfortunately, I find couple of my control inside UPDATE PANEL – does not do Partial Postback anymore. (It is doing FULL postback now)

This only happen to a control outside button which I have set as autoPostback = true.





After looking around and test which part that I need to put it back, I found clientIDMode.

I need to set clientIDMode=“AutoID” because the default value is “Predictable”.





<pages controlRenderingCompatibilityVersion="4.0" clientIDMode="Predictable">






The weird things is I try to compare the id and html which generated by both “predictable and “AutoID”. And the result is the SAME but the different is one of them can do partial postback and one of them not.





<!-- Generated when I set "clientIDMode='Predictable'" -->
<select class="ddlPostback" id="ContentPlaceHolderDefault_MainContainerPlaceHolder_ucProductDetail_rptVariationChoiceGroup_ddlChoiceGroup_0" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup\',\'\')', 0)" name="ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup">
<option value="">Please select</option>
<option value="2" selected="selected">Green</option>
<option value="3">Yellow</option>
<option value="4">Blue</option>
<option value="5">Brown</option>
</select>


<!-- Generated when I set "clientIDMode='AutoID'" -->
<select class="ddlPostback" id="ContentPlaceHolderDefault_MainContainerPlaceHolder_ucProductDetail_rptVariationChoiceGroup_ddlChoiceGroup_0" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup\',\'\')', 0)" name="ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup">
<option value="">Please select</option>
<option value="2" selected="selected">Green</option>
<option value="3">Yellow</option>
<option value="4">Blue</option>
<option value="5">Brown</option>
</select>



Friday, April 15, 2011

Grab asp.net 4.0 benefits

When you upgrade asp.net 2.0/3.5 project using Visual studio.
VS will automatically add a configuration which prevent you from breaking the results of the projects.

Here is couple example of the configuration which preserve the behaviour of .net 2.0/3.5

<pages controlRenderingCompatibilityVersion="3.5" enableEventValidation="false" clientIDMode="AutoID">





ControlRenderingCompatibilityVersion Setting in the Web.config File



ASP.NET controls have been modified in the .NET Framework version 4 in order to let you specify more precisely how they render markup. In previous versions of the .NET Framework, some controls emitted markup that you had no way to disable. By default, ASP.NET 4 this type of markup is no longer generated.



If you use Visual Studio 2010 to upgrade your application from ASP.NET 2.0 or ASP.NET 3.5, the tool automatically adds a setting to the Web.config file that preserves legacy rendering. However, if you upgrade an application by changing the application pool in IIS to target the .NET Framework 4, ASP.NET uses the new rendering mode by default.



 



ClientIDMode Changes



The ClientIDMode setting in ASP.NET 4 lets you specify how ASP.NET generates the id attribute for HTML elements. In previous versions of ASP.NET, the default behavior was equivalent to the AutoID setting of ClientIDMode. However, the default setting is now Predictable.



If you use Visual Studio 2010 to upgrade your application from ASP.NET 2.0 or ASP.NET 3.5, the tool automatically adds a setting to the Web.config file that preserves the behavior of earlier versions of the .NET Framework. However, if you upgrade an application by changing the application pool in IIS to target the .NET Framework 4, ASP.NET uses the new mode by default.




<httpRuntime requestValidationMode="2.0"/>        





ASP.NET Request Validation



The request validation feature in ASP.NET provides a certain level of default protection against cross-site scripting (XSS) attacks. In previous versions of ASP.NET, request validation was enabled by default. However, it applied only to ASP.NET pages (.aspx files and their class files) and only when those pages were executing.



In ASP.NET 4, by default, request validation is enabled for all requests, because it is enabled before the BeginRequest phase of an HTTP request. As a result, request validation applies to requests for all ASP.NET resources, not just .aspx page requests. This includes requests such as Web service calls and custom HTTP handlers. Request validation is also active when custom HTTP modules are reading the contents of an HTTP request.



As a result, request validation errors might now occur for requests that previously did not trigger errors.



==================================



To get asp.net 4.0 benefits including smaller viewstate, you need to clean that configuration or change that into this.


<pages controlRenderingCompatibilityVersion="4.0">



Tuesday, April 12, 2011

Reference By Value for integer doesn’t work in entity framework / LINQ query

 

Just find an interesting bugs, where I thought reference by value (int) can be used in entity framework or linq query.

Here is the code



lst = new List<IQueryable<tblProduct>>();
int choiceID = 30;
lst.Add(from t in originalQuery
where t.tblProductChoiceTag.Any(c => c.ChoiceID == choiceID)
select t);
choiceID = 31;
lst.Add(from t in originalQuery
where t.tblProductChoiceTag.Any(c => c.ChoiceID == choiceID)
select t);


IQueryable<tblProduct> q = null;

bool first = true;
foreach (var tquery in lst)
{
if (first)
{
q = tquery;
first = false;
}
else
{ //the next one combine it
q = q.Union(tquery);
}

}











When it executed, linq query will use the last choiceID (31) and override (30).

This really weird, because I thought It is saved to use the same (int) variable because it will pass by value.




Here is another example


var q = (from t in DBHelper.Instance.tblProductVariation
where t.ProductID == pid
&& t.tblChoice.Count == choices.Count
select t);

foreach (var c in choices)
{
q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == c.ChoiceID)
select t);
}
a
return q.FirstOrDefault();




See on this query which the value will be iterating from the choice object



q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == c.ChoiceID)
select t);




this code will pass the same value of choiceID.


To fix this you need to change it into local variable.


var cid = c.ChoiceID;

q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == cid)
select t);







Anyone can explain this ?

Friday, April 08, 2011

Firefox Update panel after 2 mins idle time

Recently, I fight with firefox bug which aborting my partial postback from update panel after 2 mins idle time.

Here was my step to investigate this problem

  • check other browsers (IE, IE6, Chrome) – and the result, only firefox does this weird behaviour
  • create simple update panel and tested on FF. – unfortunately this work perfectly
    and then I wonder why my actual code does not work.
  • Apply more content on Update Panel – It is not work again (oh my be it’s I need to make my content on update panel smaller)
  • After trying to make my update panel content smaller, it still not work.
  • Then I use my previous simple update panel to test if it is content outside update panel is matter. – (Yes, it is the content outside update panel is matter)
  • Confuse how I solve this, we still need to use update panel for particular reason because of the due date, etc. so we can’t change anything (we have to keep the update panel but has to work in FF)

After looking around the solutions, luckily I found on the other section of my project work perfectly after 2 mins idle in FF.

I try to investigate why that section work but not this. Finally I figure out that the different is that part is calling ajax call on other page before call partial postback.

Then here is my simple solutions to fix this.

  • Register Begin Request
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(microsoftAJAX_BeginRequest);
  • check the browser if it is mozilla and the time difference is 2 mins then request to other server page (ASPX page) first synchonously before continue the process.

    Here is the code, hopefully it will help your problem as well.
    //check availability for partial postback for FF fixed. FF will abort the partial postback call after 2 mins unless it call ajax to other page first
    var checkConnectionForPartialPostback = function ()
    {
    $.ajax({
    url: "/usercontrols/testconnection.aspx",
    async: false
    });
    };

    //check availability for partial postback for FF fixed. FF will abort the partial postback call after 2 mins unless it call ajax to other page first
    var checkAvailabilityForPartialPostback = function ()
    {
    //firefox fix for time diff
    if ($.browser.mozilla && GetTimeDiff(new Date(), lastLoadTime).getMinutes() >= 2)
    {
    //refresh this page
    checkConnectionForPartialPostback();
    }
    else
    {
    lastLoadTime = new Date();
    }
    };







Wednesday, April 06, 2011

IE9–Fastest Browser ?

Some people said that IE9 aim to be the fastest browser in the world.

Is that true ? Check this out and compare it with other browser

http://ie.microsoft.com/testdrive/Performance/KungFu/Default.html

Basic Geolocation example

Here is some basic geolocation example and display it to google maps.

<!DOCTYPE html>
<html>

<head>
<script src="js/jquery-1.4.2.min.js"></script>
<script src="js/yqlgeo.js"></script>
<script>
jQuery(window).ready(function(){
jQuery("#btnInit").click(initiate_geolocation);
})

function initiate_geolocation() {
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_errors);
}
else
{
yqlgeo.get('visitor', normalize_yql_response);
}
}

function handle_errors(error)
{
switch(error.code)
{
case error.PERMISSION_DENIED: alert("user did not share geolocation data");
break;

case error.POSITION_UNAVAILABLE: alert("could not detect current position");
break;

case error.TIMEOUT: alert("retrieving position timedout");
break;

default: alert("unknown error");
break;
}
}

function normalize_yql_response(response)
{
if (response.error)
{
var error = { code : 0 };
handle_error(error);
return;
}

var position = {
coords :
{
latitude: response.place.centroid.latitude,
longitude: response.place.centroid.longitude
},
address :
{
city: response.place.locality2.content,
region: response.place.admin1.content,
country: response.place.country.content
}
};

handle_geolocation_query(position);
}

function handle_geolocation_query(position){
alert('Lat: ' + position.coords.latitude + ' ' +
'Lon: ' + position.coords.latitude);
}
</script>

</head>
<body>
<div>
<button id="btnInit" >Find my location</button>
</div>

</body>
</html>function handle_geolocation_query(position)
{
var image_url = "http://maps.google.com/maps/api/staticmap?sensor=false&center=" + position.coords.latitude + "," +
position.coords.longitude + "&zoom=14&size=300x400&markers=color:blue|label:S|" +
position.coords.latitude + ',' + position.coords.longitude;

jQuery("#map").remove();
jQuery(document.body).append(
jQuery(document.createElement("img")).attr("src", image_url).attr('id','map')
);
}



JQuery Intellisense in VS 2010

 

If you want  jquery intellisense in your visual studio like this the you can get the vsdoc file generator which hosted by damo

http://damianedwards.com/vsdoc/

image