LINQ: Convert Anonymous Type

I wanted to use an anonymous type with a report viewer control in ASP.NET... of course that doesn't work unless you have a strongly typed object. And here's how I did it:
/// <summary>
/// The class of object I want to return
/// </summary>
public class MyClass
{
public int id { get; set; }
public string text { get; set; }
}

/// <summary>
/// The class used as the data source
/// </summary>
public class SourceClass
{
public int source_id { get; set; }
public string source_text { get; set; }
public string source_unused { get; set; }
}

/// <summary>
/// The method that queries the data source
/// </summary>
/// <returns></returns>
public IEnumerable<MyClass> Get()
{
// strongly typed datasource
var list = new List<SourceClass>();
list.Add(new SourceClass { source_id = 1, source_text = "test 1", source_unused = "" });
list.Add(new SourceClass { source_id = 2, source_text = "test 2", source_unused = "" });
list.Add(new SourceClass { source_id = 3, source_text = "test 3", source_unused = "" });
list.Add(new SourceClass { source_id = 4, source_text = "test 4", source_unused = "" });

// query the list, map fields as new anonymous type
var results = from x in list
select new { id = x.source_id, text = x.source_text };

// pass into the method as array of objects (can't cast an anonymous type to anything else)
return ConvertAnonymousType<MyClass>(results.ToArray());
}

/// <summary>
/// Converts a list of objects into a list of strongly typed objects.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="anonymouslyTypedList"></param>
/// <returns></returns>
public static IEnumerable<T> ConvertAnonymousType<T>(IEnumerable<object> list)
{
var stronglyTypedList = (List<T>) Activator.CreateInstance(typeof(List<T>), null);

foreach (var item in list)
{
var obj = (T) Activator.CreateInstance(typeof(T), null);
foreach (System.Reflection.PropertyInfo pi in typeof(T).GetProperties())
{
var value = typeof(T).GetProperty(pi.Name).GetValue(item, null);
typeof(T).GetProperty(pi.Name).SetValue(obj, value, null);
}
stronglyTypedList.Add(obj);
}

return stronglyTypedList;
}

SharePoint: Search Not Indexing

At some point SharePoint 3.0 stopped indexing sites. That point must have been when updates were applied to the server, including one for .NET 3.5 SP1. At that point some vulnerability was patched, enabling this loop back check. The search service could no longer see the sites. Once the above entry was added the sites were suddenly available again without rebooting.

The Error:
Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content.
The Solution:
Disable the loopback check

  1. Click Start, click Run, type regedit, and then click OK.

  2. In Registry Editor, locate and then click the following registry key:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

  3. Right-click Lsa, point to New, and then click DWORD Value.

  4. Type DisableLoopbackCheck, and then press ENTER.

  5. Right-click DisableLoopbackCheck, and then click Modify.

  6. In the Value data box, type 1, and then click OK.

  7. Quit Registry Editor, and then restart your computer.

Misc Troubleshooting


  • Check the logs: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS

  • Check the database (server/WSS_Search):
    select DisplayURl, l.ErrorDesc, el.ErrorMsg, LastTouchStart, HostID, StartAddressID from MSSCrawlUrlLog l
    left outer join MSSCrawlErrorList el on l.ErrorID = el.ErrorID order by LastTouchStart


Windows Server 2003: IIS not running aspx pages

Usually indicated by a "page not found" error even though you can get at static files like images, stylesheets, etc.

  1. Open IIS

  2. Expand Web Service Extensions

  3. Make sure ASP.NET v1.1.4322 and ASP.NET v2.0.50727 are both allowed

  4. If v2.0 is missing, run:aspnet_regiis -i from the command line to add it

XCOPY: Exclude .CS and not .CSS

Add the following to your exclude text file:
.cs\
Example:

From the command line...
xcopy c:\from.path c:\to.path /D /E /Y /EXCLUDE:exclude.txt
With the following exclude.txt file (relative to the working directory):
.config
.sln
.suo
.csproj
.vbproj
.cs\
.vb
.pdb
.refresh
Note: I know robocopy exists, I just haven't messed with it.
Note: "XCOPY /D /E /Y" copies all files and directories recursively without prompting

SQL 2005: CTE Example

WITH MyCTE (Col1, Col2) (
SELECT Col1, Col2 FROM MyTable
UNION
SELECT Col1, Col2 FROM MyOtherTable
)
SELECT * FROM MyCTE

Rant: My Upgrade to .NET 3.5

I've made the leap to ASP.NET 3.5 from 2.0. I'm sure that I'm not completely out of the 2.0 woods yet but I'm really liking the added dynamic features like Automatic Properties, Object Initializers, and Collection Initializers, Extension Methods, Lambda Expressions, and some helpful info on Query Syntax with LINQ. With the culmination of those technologies and the new ASP.NET MVC framework, I'm seeing Microsoft in a whole new light.



Now, if I can memorize the syntax...


Automatic Properties
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}

Object Initializers
Person person = new Person { FirstName="Scott", LastName="Guthrie", Age=32 };
Collection Initializers
List people = new List();
people.Add( new Person { FirstName = "Scott", LastName = "Guthrie", Age = 32 } );

Rant: Freedom vs Safety

The following explains why I regret my descent into programming over the last 12 years:

Code Craft: Freedom vs Safety Languages
Coding Horror: A Scripter at Heart

So I hate Microsoft, both because they only allow safety languages at their core, and because they are in a constant state of change. The use of safety languages in a realm where freedom languages should reign is unacceptable to me. It is a backward methodology, making client side interaction more complicated than I ever thought possible. To reverse the trend, and make my life more tolerable, I have tried to circumvent Microsoft's best practices by implementing the following:
  1. Generate a data access layer (MyGeneration was recommended to me)
  2. Define Views for the data in the code behind in an aspx/asmx that acts as an API
  3. Implement StringTemplate to render any dynamic web pages using data provided by Views.
  4. Implement Mootools and/or JQuery for the user interface.
I have spent roughly nine months working on this architecture and have nearly reached step 4, the fun part. Data access with caching, views that expose data, and virtualized pages using templates have all been completed. So now I'm almost functionally equivalent to where I was 1.5 years ago working with Django and Python. Thanks Microsoft!