Tuesday, April 15, 2008

List.FindAll - C# .Net 3.5

In my recent blog post Generics List.FindAll (to filter), I wrote about how I use the FindAll method with anonymous delegates to filter a list. Well, that was C# 2 way. Framework 3.5 onwards with Linq, we could use the power of lambda expressions to even simplify this concept.

using System.Linq;

public IEnumerable<Product> GetProductsNamedLike(List<Product> productList, string nameLike)

{

return productList.Where(p => p.Name.Contains(nameLike));

}

// Not using lambda:

public IEnumerable<Product> GetProductsNamedLike(List<Product> productList, string nameLike)

{

IEnumerable<Product> products = from Product p in productList

where p.Name.Contains(nameLike)

select p;

return products;

}


Love coding!

Friday, April 11, 2008

SharePoint: User Profile and Picture url from Active Directory

I was trying to import Active Directory to MOSS 2007 and was looking at how to import pictures (employee photos) from AD. A little bit of googling landed me on a nice blog by Henry Ong - Importing user pictures from AD to MOSS 2007.

However, in SSP profile properties I didn't get the choice to map the extensionAttribute; didn't see the Data Source mapping option at all. To resolve that, figured that I needed the domain account that has access to AD to be the SSP's service account. Went to Central Administration > Operations > Service Accounts and modified the App Pool account running SSP to use the domain account. Restart IIS and it shows up!

Love coding!

Thursday, April 3, 2008

Serialize objects with no xml decoration and no namespaces

I posted couple of blogs earlier that shows how to Serialize/Deserialize objects and serialize using SOAP formatter. Few times we would like to serialize just the pure xml part of the object with no namespaces and/or no xml declaration tag at the top. Take a look, here's how we can do it in memory (without writing to a file):


/// <summary>
/// Serializes object with no namespace and no <?xml ... > tag. Returns pure xml of the object
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal string SerializeObjectPureXML(Object obj)
{
string serialXML = "";

//Empty namespace
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
//Serialize the passed object
XmlSerializer xs = new XmlSerializer(obj.GetType());
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
// set XML writer settings
XmlWriterSettings xwSettings = new XmlWriterSettings();
xwSettings.OmitXmlDeclaration = true;
xwSettings.Indent = true;
xwSettings.CloseOutput = true;
// create xml using the settings
using (XmlWriter xw = XmlWriter.Create(sw, xwSettings))
{
xs.Serialize(xw, obj, ns);
// get the xml and clean up
serialXML = sb.ToString();
xw.Flush();
}
sw.Flush();
}
//
return serialXML;
}

Love coding!

Wednesday, April 2, 2008

Replace invalid XML characters in a string

May be some of us try to write custom replace methods to clean any invalid XML characters from our xml strings. Well, System.Security namespace has the Escape method built-in which does the same for us. Check it out at MSDN - Escape method. The code would look like:

tagText = SecurityElement.Escape(tagText);

Love coding!

Tuesday, April 1, 2008

Generics List<T>.FindAll (to filter)

Since 2.0, generics were one of my favorites. Use them quite a bit in my object models. And with that comes the need for iterative operations. One such being using FindAll to get filtered results using some sort of criteria. While generic predicates is one way to do it (for well defined filters), I also use anonymous delegate to do filtering dynamically (like based on name, for example). Let's look at either one.

Say we have a Product class and we get a List as available products to be shown to the user. Say we have an attribute (enumeration) for each product that determines its category. In a simple scenario, I have a well defined set of limited categories and I define predicates to do the filtering. And for some dynamic filtering, I'm using anonymous delegate to do the filtering. Take a look:

/// <summary>

/// An example to show generic predicates

/// </summary>

[Serializable]

public class myProduct

{

/// <summary>

/// ProductCategory

/// </summary>

public enum ProductCategory

{

General = 1,

Speciality = 2

}

private string _Name = string.Empty,

_ProductID = string.Empty;

private ProductCategory _Category;

public string Name

{

get { return _Name; }

set { _Name = value; }

}

public string ProductID

{

get { return _ProductID; }

set { _ProductID = value; }

}

public ProductCategory Category

{

get { return _Category; }

set { _Category = value; }

}

public myProduct() { }

#region "Predicate for Filters"

/// <summary>

/// Predicate for General Products

/// </summary>

/// <param name="p"></param>

/// <returns></returns>

private static bool GeneralProducts(myProduct p)

{

return (p.Category == myProduct.ProductCategory.General);

}

/// <summary>

/// Predicate for Speciality Products

/// </summary>

/// <param name="p"></param>

/// <returns></returns>

private static bool SpecialityProducts(myProduct p)

{

return (p.Category == myProduct.ProductCategory.Speciality);

}

/// <summary>

/// Filter and return General Products

/// </summary>

/// <param name="productList"></param>

/// <returns></returns>

public static List<myProduct> GetGeneralProducts(List<myProduct> productList)

{

return productList.FindAll(GeneralProducts);

}

/// <summary>

/// Filter and return Speciality Products

/// </summary>

/// <param name="productList"></param>

/// <returns></returns>

public static List<myProduct> GetSpecialityProducts(List<myProduct> productList)

{

return productList.FindAll(SpecialityProducts);

}

#endregion "Predicate for Filters"

/// <summary>

/// Anonymous delegate to filter

/// </summary>

/// <param name="productList"></param>

/// <param name="nameLike"></param>

/// <returns></returns>

public static List<myProduct> GetProductsNamedLike(List<myProduct> productList, string nameLike)

{

return productList.FindAll(delegate(myProduct p) { return p.Name.Contains(nameLike); });

}

}


We will find a lot of discussion and explanation about this topic, but this is my simplified case to show the usage.

Love coding!

Warn when javascript is disabled

Though there are many ways to determine whether users browser disabled javascript or not, I'm used to go with the simple solution of using <noscript> tag to get the purpose done. It works for all my apps and most popular browsers; and I'm fine with that.

In my master page, I simply add this section as first thing in the body:

<noscript>

<div style="background-color: BlanchedAlmond; border-bottom: 1px solid #E4D199; padding: 10px;

font-size: 10px;" align="center">

Your browser settings are limiting the site functionality. Please enable scripting to get the site's full functionality.

</div>

</noscript>

Love coding!

Wednesday, March 26, 2008

Loose coupling

We all know about the benefits of loose coupling and agree that tight coupling is not our intention. Still we see that happening a lot. This month's MSDN magazine carried a very nice article by James Kovacs about this topic and I would recommend this to all to know or refresh ourselves and our thought process. The article is Loosen Up: Tame your software dependencies for more flexible Apps. Go ahead and read it.

Love coding!

Friday, March 21, 2008

Switching to Oracle's SQL Developer from TOAD

For the past few years I have been using TOAD for Oracle and researched a bit on alternative tools to switch to. Having used TOAD for long, got used to it and any tool I looked at naturally tried to compare if it can do the developer job that TOAD can do.

I liked the free SQL Developer from Oracle as a good alternative. It doesn't take long to know what and how to do our tasks using this tool. So far didn't find any problem using it.

The only difference I found so far is to refresh a materialized view graphically. In TOAD, we can right click the materialized view (development, of course) and click refresh. However, in SQL Developer I'm yet to find how this could be done. For now, I'm using the DBMS package to refresh the view and here's how I do it:

EXECUTE dbms_mview.refresh('myMateralizedViewName');

If I come across any more or find improvements, will update here.

Love coding!

Updates:
03/25/2008 - Found out this tool takes a little excessive memory and crashes when exporting large datasets.

Thursday, March 20, 2008

Selecting top rows or random rows

We all come across the need to select top rows and/or random rows from our tables. I wrote a blog about Dynamic Paging in the past and in that showed a way of selecting a range of rows both in SQL Server and Oracle. Let's extend the thought and select either top rows or random rows. Take a look:

--SQL Server: Top 10 of SomeColumn

Select Top 10 * From myTable Where MyColumn = 'MyCondition' Order By SomeColumn Desc

--Oracle: Top 10 of SomeColumn

Select *

From (Select Row_Number() Over (Partition By 'kigo' Order By SomeColumn Desc) myTops,

Column1, Column2, Column3

From myTable Where MyColumn = 'MyCondition')

Where myTops < 10

--Oracle: Gets you 1% records

Select * From myTable Sample(1)

--SQL Server: Random 10

Select Top 10 * From myTable Where MyColumn = 'MyCondition' order by NewID()

--Oracle: Random 10

Select *

From (Select Row_Number() Over (Partition By 'kigo' Order By dbms_random.Value()) myTops,

Column1, Column2, Column3

From myTable Where MyColumn = 'MyCondition')

Where myTops < 10

Love coding!

Wednesday, March 12, 2008

Asp.Net - Memory & Performance

There has been a lot of discussion and information about performance of Asp.Net applications and any possible leaks. First, I would like to point to couple of MSDN articles related to this topic (though they are bit old articles still a good read).

The first one is 10 tips for high-performance web applications.

And the second one, which all of us must read and track, is Performance monitoring Asp.Net applications.

We all consider these points (and more) during architecture and design/development phases. However, we still might find our apps either showing poor performance (especially during peak loads) or, worse, memory leaks. Obviously there is no single best model that fits every design. Any measure we take must be evaluated for its possible counter effects on the environment.

For example, consider caching. Overly caching, for example huge datasets, might seem to work fine in testing but shows overall performance problem in a production environment. The amount and levels of caching should be considered very carefully during our initial design. Also, remember to set our app pool memory limits (IIS 6) if we notice any out-of-memory exceptions.

Memory leaks - this is not a good thing to happen in our apps. But let's admit it, we have seen this in many apps, though .Net handles memory very efficiently. A little bit of googling on this topic pulls a lot of information but wanted to point to an article by Mike Bloise about Tracing memory leaks with ANTS Profiler. I had used this tool and think its really worth the investment if we are determined in getting to the bottom of the problem.

In summary, it's an ongoing challenge and battle to keep our apps tuned. Reliability, modularity, performance and efficiency are some of the key factors for a good design.

Love coding!

Monday, March 10, 2008

Windows Explorer type folder explorer in a web app

I had built windows explorer style folder and file browsers using Asp.Net in the past. Recently, I had to put together a reusable module to do that across multiple websites. While doing so, was researching on the topic and came across a very nice blog that Matt Berseth had built on that concept. Many thanks to Matt for his contributions and I'm sure it helped many. Here's a link to Matt's blog.

Love coding!

Monday, February 18, 2008

Cross-Site Request Forgery – Also an interesting side problem viewstate MAC failed

Cross-site request forgery, also known as one-click attack or session riding and abbreviated as CSRF or XSRF, is a type of malicious exploit of a website whereby unauthorized commands are transmitted from a user that the website trusts. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser.

There are many things we could possible do to prevent/minimize such attacks. One of my techniques to handle this problem is by requiring a secret, user-specific token in all form submissions; that way the attacker's site can't put the right token in its submissions. I do this by using Session ID as ViewStateUserKey and I will make sure my master base has it covered.

Sample code snippet could look like:



protected void Page_Init(object sender, EventArgs e)

{

Page.ViewStateUserKey = Session.SessionID;

}

The idea was to generate a unique view state key to each session and thus preventing the attacking sites from hijacking the session.

An interesting side problem:

The above technique has been my standard for all my projects. However, one small site threw an error: Validation of viewstate MAC failed. There's a whole lot of discussions, documents and scenarios why this error occurs. Typically this is an error that's common in load balanced environments where the encryption/decryption among servers use different keys. Read my knol about basic check list on load-balancing with IIS. On a side note, never disable ViewState encryption by setting EnableViewStateMac="false"; it's a bad idea.

Coming back to our XSRF, a little investigation showed my error was due to the new session id being generated for every post back. This particular site doesn't use sessoins and Asp.Net being stateless never initializes a session unless being used. In my case, a new session id was being generated every time and leading to the view state key being different for each postback. A simple fix is to make sure to initialize the session. The above code snippet in such case was changed to:



protected void Page_Init(object sender, EventArgs e)

{

Session["NeedThisToInitialize"] = "Yes";

Page.ViewStateUserKey = Session.SessionID;

}

Love coding!

Tuesday, January 8, 2008

Batch program to copy file with Date & Time - Archiving

Recently was looking for a simple batch file to archive some of my file with date and time stamp added to it. Compiled a simple script to do the job and it looks like:

d:

Set Source="D:\mySourcePath"
Set Target="D:\myTargetPath"
Set Date=%date:~10,4%%date:~4,2%%date:~7,2%
Set Time=%time:~0,2%%time:~3,2%

REM myFile.log
copy /y %Source%\myFile.log %Target%\myFile_%Date%_%Time%.log
Del /q %Source%\myFile.log

Love coding!