torsdag 29 november 2007
DataContractSerializer requires alphabetic element order
Let says we have the following class:
[DataContract]public class auth
{
[DataMember]
public string username;
[DataMember]
public string password;
}
...and the following XML input:
<auth>
<username>ABC</username>
<password>DEF</password>
</auth>
Using this XML, the DataContractSerializer would deserialize the "Auth" class and Username property correctly - but the Password property would be null.
The reason is that the DataContractSerializer requires the element order in the XML to be in alphabetic order, ie:
<auth>
<password>DEF</password>
<username>ABC</username>
</auth>
The sort order can be set explicitly using the "Order" property on the "DataMember" attribute - however: it would still require the XML input to follow a specific order.
Example using the "Order" property and allowing the username element to appear before the password element:
[DataContract]
public class auth
{
[DataMember(Order=1)]
public string username;
[DataMember(Order=2)]
public string password;
}
WCF: Adding a behavior extension requires careful notation of the assembly path
An error occurred creating the configuration section handler for system.serviceModel/behaviors: Extension element 'myService' cannot be added to this element. Verify that the extension is registered in the extension collection at system.serviceModel/extensions/behaviorExtensions.Parameter name: element
This might be the case even if the syntax for the assembly/class is correct and even if the service host has access to the assembly.
The reason is that for this particular configuration, .NET requires you to:
1. Add the fully qualified name for the assembly
Example:
"MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
instead of:
"MyAssembly.MyClass, MyAssembly" - which normally does the job
2. Use the exact syntax for the assembly
You are not allowed to use any line break of white spaces at the wrong places.
Example:
"MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
instead of:
"MyAssembly.MyClass,MyAssembly,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" - note the missing white spaces between each attribute.
Microsoft has acknowledged this; yet not classified it as a bug:
https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=216431
torsdag 18 oktober 2007
ASP.NET Cache gets flushed, cleared or randomly disappear
1: <caching>
2: <cache disableMemoryCollection = "true"
3: disableExpiration = "false"
4: privateBytesLimit = "0"
5: percentagePhysicalMemoryUsedLimit = "90"
6: privateBytesPollTime = "00:02:00"/>
7: </caching>
There are a few tools that might be helpful when debugging cache.
- Visual Studio 2005 Cache Visualizer (note the changes you need to do the code in the comments)
- WebDevHelper (you need to add the httpModule to web.config and the nstuff.WebDevHelper.Server.dll as reference.)
Reference:
Thanks to Henrik for good google skills.
tisdag 16 oktober 2007
SQLQueryStress
Often after a trace you will find that only a couple of your queries ends up taking the majority of the cpu.
Sometimes it's as easy to solve the problems by just adding an index, and sometimes there will be other solutions.
Whatever solution you choose, it can be a good thing to test your query.
The SQLQueryStress tool written by Adam Machanic, can be downloaded here http://www.datamanipulation.net/SQLQueryStress/.
SQLQueryStress is very simple although very powerful. You can use parameter substitution so you can execute your queries with different parameters. You can set the number of iterations but also the number of threads (clients).
The output from this is "cpu seconds", "elapsed time", "client seconds", "logical reads", and more.
So when you compare two queries and booth queries takes the same time to execute, you can easily see in this program if one of them use less cpu or maybe less IO over several executions and with different parameters.
måndag 15 oktober 2007
Are you still using the repeater?
All the good functionality that came with the data binding controls also introduced performance problems. So – for example - instead of using the datagrid we started to use the repeater. However it’s easy to forget that even the repeaters data binding functionality comes with performance problems.
The repeater uses reflection internally, and for each object (text or image or whatever) in the itemtemplate it will create a new control, and if you have a rather complex repeater it will quickly add up and create a lot of controls. The creation of a control and all it’s rendering means extra cpu time, and also extra work for GC.
I have made some performance tests and found out that the repeater can be 30 times slower than using string concatenation with stringbuilder and then use response.write to ouput the result. And this is only the rendering time, we also have saved a lot of CPU time and therefore the application will scale better when we stress test it.
The problem with this solution is that it will give us headache when we need to add/edit the html or add an attribute of a control or something. What we can do is to create a usercontrol that has a public collection (of some sort), that we can set, and then use inline c# with other custom controls. This solution will still give us the same performance benefits.
Example
<%
for (int i = 0; i < myCollection.Count; i++){
myCustomControl.myAttribute = myCollection[i].SomeProperty;
%>
<div class="<%=myCollection[i].myDivClassProperty %>">some html</div>
<uc:myUc id="myCustomControl" runat="server" />
<%
}
%>
This way we will keep the rest of our code clean and use this optimized version of data rendering where you have a lot of posts to render or is one of the most viewed pages in your application.
fredag 5 oktober 2007
ASP.NET Ajax History control example
<cc1:History ID="History1" runat="server"></cc1:History>
<asp:UpdatePanel ID="updPnl" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:MultiView ID="multiView" runat="server">
<asp:View id="viewStep1" runat="server">
...
</asp:View>
<asp:View ID="viewStep1" runat="server">
...
</asp:View>
</asp:MultiView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="History1" EventName="Navigate" />
</Triggers>
</asp:UpdatePanel>
Event that is fired when you press the back button.
public void History1_Navigate(object sender, Microsoft.Web.Preview.UI.Controls.HistoryEventArgs args)
{
string viewId = "";
View historyView = viewStep1;
if (args.State.ContainsKey("BookingSteps"))
{
viewId = (string)args.State["BookingSteps"];
}
foreach (View v in multiView.Views)
{
if (v.ID == viewId)
historyView = v;
}
setActiveView(historyView);
}
Set history point each time you change the view.
private void setActiveView(View view)
{
multiView.SetActiveView(view);
History1.AddHistoryPoint("BookingSteps", view.ID);
}
onsdag 3 oktober 2007
List IIS App pool processes
The solution is to create one application pool for each web application in the IIS. IIS will then launch one individual "w3wp.exe" process with its own ID (PID - Process ID) for each application pool.
To list all running processes, Windows Server has a built in vbs-script to display all running application pools (w3wp processes) located in: "c:\windows\system32\iisapp.vbs".
You run this script from a command console using:
c:\windows\system32\cscript.exe iisapp.vbs
The output is a list of each running w3wp process together with its PID which can be matched to the PID in the task manager.
Using one application pool for each web application also has advantages when looking at performance counters as each counter can be selected for each application pool.
torsdag 20 september 2007
Using ToolkitScriptManager CombineScripts with url rewrite
To fix this you can add the CombineScriptsHandlerUrl and set this value to "/".
<ajaxtoolkit:toolkitscriptmanager id="ToolkitScriptManager1" runat="server" asyncpostbacktimeout="900" combinescripts="true" combinescriptshandlerurl="/" loadscriptsbeforeui="true">
AjaxControlToolkit: Events inside a Accordion
In this example we have the following structure.
- MasterPage
- Page
- MyAccordion
- MyUserControl
- MyButton
In the Page OnInit you simply put the following line:
LinkButton btn =(LinkButton)(MyAccordion.Panes[0].FindControl("MyUserControl").FindControl("MyButton"));This will make the Accordion to force to load the OnInit in MyUserControl and thus register the MyButton_Click event. It will also enable all other events inside the usercontrol
Hopefully a fix for this will come in a later version of the AjaxControlToolkit.
Reference: http://forums.asp.net/t/1047516.aspx