David Kennedy’s Tech Ramblings

Just another WordPress.com weblog

Silverlight, WCF, and Linq to Sql September 18, 2008

Filed under: Silverlight Tutorials — dotnetdave @ 3:52 am

Whilst putting together the Silverlight datagrid sample from a few posts ago, I came across some odd behaviour with my LINQ entity ‘losing’ its schema definition on the client, resulting in the Grid not displaying the data. I’ll explain my approach by way of diagrams:

silverlinq1 silverlinq2

It seems as if the proxy classes for my LINQ entities were not being properly recognised on the client because of the nested WCF calls. I’m still unsure as to the exact cause of this issue, I verified that appropriate attributes added to my LINQ entity classes to support WCF were being propagated to the proxies built from them, however the only way I could get the Grid to successfully display data was by removing the additional tier.

 

POCO2HTML Form Generator September 11, 2008

Filed under: Uncategorized — dotnetdave @ 2:54 am

I sometimes wake up in the early hours of the morning with some idea running around in my head, and this morning it just happened to be this. I have had similar thoughts in the past, as would have most developers who become bored with the repetition of writing input HTML forms that directly match model classes for your data. Here is a working start to a command line utility that reflects on a given assembly and produces simple HTML forms to match.

When I have some more spare time after my 70-536 MS exam I’d like to tidy this up to make it more useable as well as generating c# code to populate an object from the form back on the server. As I’ve been experimenting with the new ASP.NET MVC this is generating a plain HTML form, however the output could easily be adapted to produce rich server controls for input.

Here’s the code so far:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using keithfletcher.org; // courtesy of http://sql.codeproject.com/KB/dialog/CmdLineParsing.aspx using System.IO; using System.Reflection; namespace DotNetDave.Tools.POCO2HTML { [Application( HelpOptions = new string[] { "?", "help" }, OptionPrefixes = new char[] { '/', '-' }, ThrowParsingExceptions = false)] [Option("ns", ShortDescription = "Namespace", LongDescription = "The Namespace which contains Model classes from which to generate HTML forms.", ValuePresence = OptionAttributeValuePresence.MustHaveValue, IsOptional = true)] [Option("class", ShortDescription = "Class", LongDescription = "The fully-qualified class from which to generate a HTML form.", ValuePresence = OptionAttributeValuePresence.MustHaveValue, IsOptional = true)] [Option("all", ShortDescription = "AllTypes", LongDescription = "Generates HTML forms for ALL types in the given Assembly", ValuePresence = OptionAttributeValuePresence.MustNotHaveValue, IsOptional = true)] [Option("SourceFile", IsAnonymous = true, ShortDescription = "FileName", LongDescription = "The Assembly containing the Model/s to generate HTML form/s for.", ValuePresence = OptionAttributeValuePresence.MustHaveValue, IsOptional = false)] public class Program : CommandLineBase { static void Main(string[] args) { new Program(args); } private Program(string[] args) : base(args) { if ((Options.Count == 0) && !ShowingHelp) ShowHelp(); if (ParseErrors && !ShowingHelp) { WriteLine("Errors occurred!"); ShowHelp(); } // verify that the assembly exists if (!ShowingHelp && !File.Exists(Options["SourceFile"].Value)) { WriteLine("Source file specified is invalid! Please check the path and try again"); ShowHelp(); } // continue unless there's a problem if (!ShowingHelp) { Assembly source = Assembly.LoadFrom(Options["SourceFile"].Value); // if a class is specified, use it if (Options["class"].HasValue) { Type t = source.GetType(Options["class"].Value, false, true); ClassHtmlGenerator.Process(t); } else if (Options["ns"].HasValue) WriteLine("Not Yet Implemented"); else { if (Options["all"].IsPresent) { Type[] Types = source.GetTypes(); // generate for all types foreach (Type t in Types) { ClassHtmlGenerator.Process(t); } } else // list all available types { WriteLine("Available Types in Assembly:"); Type[] Types = source.GetTypes(); // Display all the types contained in the specified assembly. foreach (Type t in Types) { Console.WriteLine(t.Name + " (" + t.FullName + ")"); } } } WriteLine("Processing Complete!"); } Console.ReadKey(); } } public class ClassHtmlGenerator { public static void Process(Type SourceClass) { PropertyInfo[] props = SourceClass.GetProperties(); if (props.Count() == 0) return; // ignore types with no properties // start a target file StreamWriter target = new StreamWriter(SourceClass.Name + "Form.html"); target.WriteLine("<form id=\"Form1\">"); target.WriteLine("<table width=\"90%\">"); foreach (PropertyInfo prop in props) { if (prop.CanWrite) { target.Write("<tr><td>" + prop.Name + "</td>"); if (prop.PropertyType == typeof(string)) target.WriteLine("<td><input type=\"text\" name=\"" + prop.Name + "\"></td></tr>"); else if (prop.PropertyType == typeof(bool)) target.WriteLine("<td><input type=\"checkbox\" name=\"" + prop.Name + "\"></td></tr>"); else if (prop.PropertyType == typeof(DateTime)) // include simple datetime picker target.WriteLine("<td><input type=\"text\" name=\"" + prop.Name + "\"></td></tr>"); else if (prop.PropertyType.IsEnum) // offer options { target.Write("<td><select name=\"" + prop.Name + "\">"); foreach (FieldInfo fInfo in prop.PropertyType.GetFields(BindingFlags.Public | BindingFlags.Static)) { target.Write("<option value=\"{0}\">{1}</option>", fInfo.GetRawConstantValue().ToString(), fInfo.Name); } target.WriteLine("</select></td></tr>"); } else if (prop.PropertyType.IsValueType) // default to text input for now target.WriteLine("<td><input type=\"text\" name=\"" + prop.Name + "\"></td></tr>"); } } target.WriteLine("</table></form>"); target.Flush(); target.Close(); } } }

 

You’ll need to include the CmdLineParsing project from:

 http://sql.codeproject.com/KB/dialog/CmdLineParsing.aspx

An example of the input and output is as follows:

public class TestClass { public enum StatusEnum { good, bad, ugly }; public string Title { get; set; } public StatusEnum Status { get; set; } public bool Active { get; set; } }

And this will produce the following form:

<form id="Form1"> <table width="90%"> <tr><td>Title</td><td><input type="text" name="Title"></td></tr> <tr><td>Status</td><td><select name="Status"><option value="0">good</option><option value="1">bad</option><option value="2">ugly</option> </select></td></tr> <tr><td>Active</td><td><input type="checkbox" name="Active"></td></tr> </table></form>
 

Good little Silverlight Tutorials September 2, 2008

Filed under: Silverlight Tutorials — dotnetdave @ 9:02 am

This has some good stuff on it, quick little introductions into various areas of the visual side of Silverlight

http://www.nibblestutorials.net/