- Posted by Justin on September 29, 2008
I just spent a bit of time trying to figure out why my GridView was randomly doing a double postback when deleting rows. When I hooked up the debugger and put a break point on in the Page_Load, I would see that it was being called twice. It turns out that there is a bug with the GridView that causes this behavior. If you use either a LinkButton or regular Button, the GridView works as expected. There is also a workaround @ http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105123
- Posted by Justin on July 24, 2008
This is a book that should be in your library if you are going to be doing development with ASP.NET AJAX.
Typically when you start learning ASP.NET Ajax all of the material centers around UpdatePanels and leaves out anything to do with the client-side scripts. This book will make you realize how much functionality you are missing by only using UpdatePanels.
Also, this book not only covers learning the ASP.NET AJAX client scripts but how to do object oriented javascript development.
- Posted by Justin on July 24, 2008
I am big fan of using keystrokes over using the mouse. The two blogs below have some great post on visual studio shortcuts.
Sara Ford's Weblog : Daily post of a Visual Studio Tip.
Chris Craft's Blog : Currently running a 31 days of Visual Studio Tips and Tricks
- Posted by justin on June 27, 2008
Several times I have had the need to take a collection and convert it to a delimited string for displaying in the UI. I have been using the code below that I found on a blog that I have since lost the link to. However, while at the SEVDNUG meeting tonight Rob showed me an easier way to get the same output using LINQ.
Original Code:
public class CollectionUtilities
{
public string Join<T>(string delimiter, IEnumerable<T> items, Converter<T, string> converter)
{
StringBuilder builder = new StringBuilder();
foreach (T item in items)
{
string converted = converter(item);
if (string.IsNullOrEmpty(converted) == false)
{
builder.Append(converted);
builder.Append(delimiter);
}
}
if (builder.Length > 0)
{
builder.Length = builder.Length - delimiter.Length;
}
return builder.ToString();
}
}
New Code:
public class CollectionUtilities
{
public string Join<T>(string delimiter, IEnumerable<T> items, Converter<T, string> converter)
{
return string.Join(delimiter, (items.Where(i => string.IsNullOrEmpty(converter(i)) == false).Select(i => converter(i))).ToArray());
}
}
NUnit Test:
[Test]
public void JoinTest()
{
string[] joins = new string[]{"1", "2", "3", "4"};
string joinTest = new.Join(",", joins, item => item);
Assert.AreEqual("1,2,3,4", joinTest);
joins = new string[] { "1", "", "3", "4" };
joinTest = new CollectionUtilities().Join(",", joins, item => item);
Assert.AreEqual("1,3,4", joinTest);
joins = new string[] { "1"};
joinTest = new CollectionUtilities().Join(",", joins, item => item);
Assert.AreEqual("1", joinTest);
}
- Posted by justin on February 26, 2008
Updated 4/25/2008: Add sample source code
Problem: How to efficiently implement paging in GridView using an ObjectDataSource
For small amounts of data the built-in paging for the GridView worked fairly well and takes practically no work to do it. However, once you get to a decent amount of data, it becomes incredible slow and provide for a horrible user experience. The problem is that basically the GridView and ObjectDataSource are returning all of the records each time from the database and only showing the ones for the current page. This is a very inefficient use of bandwidth.
Solution:
To get around this problem, you can implement paging with the ObjectDataSource. When you implement paging with the ObjectDataSource, it automatically passes in the values for the startIndex and maximumRows to your select statement and needs to have a SelectCount method defined so that it can get the total number.
Sounds really easy right? Once you figure out how to get the RowCount for the query it is. For simple queries you can use the CountQuery class in ActiveRecord. However for more complicated queries that use a DetachedCriteria, there is currently no overload for CountQuery that take a DetachedCriteria. Hopefully this will be in a future release since there was a patch submitted on March 5th for this feature.
Luckily both NHibernate and ActiveRecord are open source so I was able to look thru their code and tests. In ActiveRecord it is well structure with a directory in their ActiveRecord Framework project called Queries.
In my research it became clear that a Projection query was what I needed but I still was not sure
So I finally found a ScalarProjectionQuery class that took a DetachCriteria. Below is an example call to the method. query is a DetachedCriteria
ScalarProjectionQuery<WorkOrder, int> proj = new ScalarProjectionQuery<WorkOrder, int>(Projections.RowCount(), query);
Int count = proj.Execute();
To implement the actual paging for the ObjectDataSource , I used the ActiveRecord SlicedFindAll method for my model along with the Sql 2005 Dialect.
Gotcha:
With turning on paging for the ObjectDataSource is that it automatically passes the startIndex and maximumRows parameters into your defined Select method as the last 2 parameters and if you use the designer to configure the ObjectDataSource, it adds those parameters to the parameter collection defined in the html code. This in turn causes the startIndex and maximumRows to be passed twice into the SelectMethod .
Sample Code:
ObjectDataSource Definition:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="FindUserBlogs"
TypeName="MyClassThatMyFindMethodIsIn" OldValuesParameterFormatString="original_{0}"
OnSelecting="ObjectDataSource1_Selecting" EnableViewState="False" EnablePaging="True"
SelectCountMethod=" FindUserBlogsCount">
<SelectParameters>
<asp:Parameter Name="userID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
ActiveRecord Method Definition:
public static Blog[] FindUserBlogs (int userID, int startRowIndex, int maximumRows) {
// use SlicedFindAll to start at a specific row and limit the results }
public static int FindUserBlogsCount (int userID) {
//query is a DetachCriteria
ScalarProjectionQuery<Blog, int> proj =
new ScalarProjectionQuery<Blog,
int>(Projections.RowCount(), query);
return proj.Execute();
}
- Posted by justin on September 27, 2007
I have had a problem for ages with when a build fails in CCNET is runs the file merge tasks that are part of my publishers to include the nunit test results. I finally got around to implementing something to delete those results xml files before the build runs. Originally I was just going to add it to nant but I found in the CCNET docs that there is now a prebuild section. One of the tasks included with the CCNET is an exec but it is not very clear on how to use CMD instead of creating a separate batch file. Luckily someone else figured this out at posted it to the mailing list @ http://groups.google.com.ag/group/ccnet-user/browse_thread/thread/d3f19074845bacf7/f58fa4bf7e221b3d?lnk=gst&q=prebuild+&rnum=9#f58fa4bf7e221b3d
Just in case the link goes away, below is how to do it.
<prebuild>
<exec>
<baseDirectory>C:\Temp</baseDirectory>
<executable>CMD</executable>
<buildArgs>/C RD "%ccnetworkingdirectory%" /S /Q</buildArgs>
</exec>
</prebuild>
- Posted by justin on September 26, 2007
Pretty good article on different concepts for implementing load balancing in asp.net.
http://www.c-sharpcorner.com/UploadFile/gopenath/Page107182007032219AM/Page1.aspx
- Posted by justin on April 16, 2007
Today I started working on my cruise control setup and added my Team Edition for Database Professionals project into the build. Everything went well except that the warning messages from it were taking up a good portion of my log file.
Most of the warnings are coming from the TDS3006 error which basically means that it cannot figure out where a column comes from. To me this error is just about worthless to me since having an alias on my tables/columns seems to cause the problem even though the statement is technically valid.
Luckily enough you can suppress this message. To suppress warning messages for the Team Edition for Database Professional you need to add the error number without the TDS to the suppress warning textbox on the project properties\build.
A complete list of error messages for Team Edition for Database Professionals, http://msdn2.microsoft.com/en-us/library/bb203958(VS.80).aspx
- Posted by justin on March 8, 2007
I had a need to set some of the ObjectDataSource parameters for my select statement at runtime. Sometimes the parameters are set from a cookie, other times from a querystring and sometimes from a form field.
To set the parameters at runtime, you need to implement the Selecting Event for the ObjectDataSource and then use the InputParameter for the ObjectDataSourceSelectingEventArgs to set the value.
Example:
protected void ObjectDataSource1_Selecting(object sender,ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["MyParameterName"] = ParameterValue;
}
- Posted by justin on March 8, 2007
Interesting post on Webforms and testability. There is also a great comment by Scott Gunthrie (ScottGu) that has a lot of great information in it.
http://codebetter.com/blogs/jeremy.miller/archive/2007/03/07/Jay_2700_s-TDD-QuickStart_2C00_-and-the-underlying-problems-he-stumbled-into.aspx?CommentPosted=true#commentmessage