The importance of name giving

by Mikael Henriksson 31. January 2009 14:49

Don’t remember who wrote it but I experienced it first hand tonight. I got it from Clean Code or some other great book I read. I can’t remember the exact frase but it goes something like this –“You give the name of your methods the same thought process as you would a child”. Something like that. For me it was not the name of a method but rather a user control. You see I have just started working with MVC (love it by the way) and I was trying to do a simple

<% Html.RenderPartial("Login"); %>
This worked very well until I tried to visit the actual ActionResult View. For some reason I got a StackOverFlowException and while debugging it it looked like Html.RenderPartial is taking the name of the ActionResult and get stuck in an infinite loop. A simple renaming the user control Login to LoginControl and do the following solved my problems:
<% Html.RenderPartial("LoginControl"); %>
It is an extremely silly problem really but it still got me thinking that name giving is one of the most important aspects of programming!

Tags:

MVC

Html.DropDownList Not Working?

by Mikael Henriksson 31. January 2009 14:17

It’s actually pretty though not very easy to grasp and I couldn’t really find any information about my little problem but here is my explanation on how to get it working! :)

All you need to do is:

<%= Html.DropDownList("CustomerID") %>

And this is why. I know it says that the DropDownList takes a SelectList as a second parameter but you actually supposed to solve this issue in the controller (And this is a very good solution since it makes the presentation layer way less cluttered (logic should NOT be in the Views)!

public ActionResult Edit(int id)
{
    var invoiceRepository = new InvoiceRepository(1);
    var invoice = invoiceRepository.GetSingle(id);

    IList<Product> products = invoiceRepository.GetProducts(id);
    IList<Workday> workdays = invoiceRepository.GetWorkdays(id);

    invoice.CompanyReference.Load();
    int companyId = invoice.Company.ID;
    ICriterion<Customer> criterion = 
		new Criterion<Customer>(c => c.Company.ID == companyId);
    var repository = new Repository();
    IList<Customer> customers = repository.GetAll(criterion);
    ViewData["Products"] = products;
    ViewData["Workdays"] = workdays;

    ViewData["CustomerID"] = new SelectList(customers, "ID", "Name");
    ViewData["Invoice"] = invoice;

    return View(invoice);
}

What I do here is to tell the the presentation layer that the CustomerID contains a SelectList of Customer and that the value field is ID and the display field is Name. Then MVC handles this for you!

Tags:

MVC

Getting started with MVC

by Mikael Henriksson 28. January 2009 23:19

There has been ALOT of improvement in the new version of MVC. I have just gotten started but so far I love it. It is expressive and feels much more intuitive that regular asp.net. You can pretty much extend the existing functionally as much as you like and only the sky is the limit. Wait, stars is the limit.. no there is no limit!

The new feature with sending a file straight to the browser is great. Basically you just create a “dummy” holder class (if you want) for file information like:

   1: public class Image
   2: {    
   3:     public int ImageId { get; set; }    
   4:     public string FileName { get; set; }    
   5:     public byte[] Content { get; set; }    
   6:     public string Mime { get; set; }
   7: }

Now you can easily choose how to send this to the browser. Question is what do you want to do with the file? You can force download or let the browser render it.

To download a file (image, pdf etc.) do the following

   1: public ActionResult DownloadImage(int id)
   2: {
   3:     ICriterion<Image> criterion = new Criterion<Image>(i => i.ID == id);
   4:     Repository repository = new Repository();
   5:     var image = repository.GetSingle(criterion);
   6:     return File(image.Content, image.MimeType, image.FileName);
   7: }

 

The only thing you have to do differently to render the image in the browser instead is to leave the file name out of the return statement. The third parameter just tells MVC to send the file as an attachment. The code to display the image:

   1: public ActionResult DisplayImage(int id)
   2: {
   3:     ICriterion<Image> criterion = new Criterion<Image>(i => i.ID == id);
   4:     Repository repository = new Repository();
   5:     var image = repository.GetSingle(criterion);
   6:     return File(image.Content, image.MimeType);
   7: }
 
The next thing I learned today and this is something I think everyone needs to learn is how to successfully render and display data from different views. Let’s take an invoice as example. The rows (invoice lines) belongs to the aggregate root Invoice and should not be accessible anywhere else. There for I wont create a view for invoice lines. But how do I display the invoice lines when I view the Invoice Details?
It’s real easy, kudos to everyone at the MVC team for making it so easy :) Create a UserControl like InvoiceLinesUserControl (Have a problem with long descriptive names? Read this blog post).

Since the release candidate of MVC the code behind of the view pages is gone. To tell the view what type of data is expected we now do that with Inherits:

   1: <%@ Page Title="" Language="C#" 
   2:     MasterPageFile="~/Views/Shared/Site.Master" 
   3:     Inherits="System.Web.Mvc.ViewPage<Core.Invoice>" %>

Then we need an action result to get some useful data to display in the view Invoice.Details.

   1: public ActionResult Details(long id)
   2: {
   3:     var invoiceRepository = new InvoiceRepository(companyId);
   4:     var invoice = invoiceRepository.GetSingle(id);
   5:     ViewData["Message"] = "Details for invoice : #" + invoice.InvoiceNumber;
   6:  
   7:     IList<InvoiceLines> invoiceLines = invoiceRepository.GetInvoiceLines(id);
   8:     ViewData["InvoiceLines"] = invoiceLines;
   9:     return View(invoice);
  10: }
From here on out it’s a walk in the park. To display the invoice details data I can just do 
   1: <%= Html.Encode(Model.InvoiceTotal) %>

and to render the user control with the quantity and unit price I just Render Partial and tell that method which view data to use like this:

   1: <% Html.RenderPartial("InvoiceLinesUserControl", ViewData["InvoiceLines"]); %>

Tags:

MVC

How do I log from asp.net to Event Log?

by Mikael Henriksson 27. January 2009 19:00

This has been bugging me for quite some time with throwing exceptions when I try to log from an asp.net page to Event Log. The solution is quite simple but it eludes me why nothing has been written about. At least not anywhere I have looked.

  1. Go to run (win+r) type in regedt32.
  2. Navigate to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog
  3. Right click, select permissions and Add the ASPNET account (IUSR as well????) with full rights
  4. Make sure that all child objects get the same rights

Done, now you can start logging to the event log.

Tags:

Windows Server

Handle enums gracefully...

by Mikael Henriksson 27. January 2009 18:59

As of lately I have been trying to use Enums wherever I can. In the project I just finished I had a bunch of buggy code and wanted more detailed descriptions so I began writing a grand class to handle all the exceptions. I decided to use and Enum for describing all the different logging routines but when I needed to actually do something based on more than one LogType I ran in to patrol. I wanted to iterate through the declared enum type for the class and log to all types in a sweep. First I got kind of confused looking at my code and since I wanted the others in the team to be able to use it easily I had to rethink. First thing was to refactor the class to something really simple, then begin adding my "normalized" methods but I got stuck at not being able to gracefully looping through my enum.

Let's say I have an enum like this:

[Flags()]   
public enum LogType   
{
	/// <summary>Exception will be logged to a text file</summary>  
	TextFile = 1,
	/// <summary>Exception will be logged to the application event log</summary>
	EventLog = 2,
	/// <summary>Exception will be logged via email</summary>
	Email = 4,
	/// <summary>Log to a website</summary>
	WebSite = 8,
	/// <summary>Log to a database of your choice</summary>
	Database = 16,
	/// <summary>A summary of all LogSources</summary
	All = TextFile | EventLog | Email | WebSite
}

The above code should be a no-brainer, if you don't understand it you should probably buy a book! :)

I found a great tool for making my work extremely readable for my college by the way, it's called Ghost Doc and if you have not tried it yet I urge you to! The project can be found over at http://www.roland-weigelt.de/ghostdoc/
If you are stronger in the code than my granny was I believe you should have no problems reading the following code either, and making good use of it!

public static Collection<T> ConvertEnumValuesToCollection<T>(T enumInputValue) 
where T : struct { Type enumType = typeof(T); if (!enumType.IsEnum) { throw new ArgumentException(enumType.ToString()
+ " Is not an Enum.", "T", null); } Array enumValues = Enum.GetValues(enumType); long inputValueLong = Convert.ToInt64(enumInputValue); Collection<T> enumOutputCollection = new Collection<T>(); foreach (T enumValue in enumValues) { long enumValueLong = Convert.ToInt64(enumValue); if ((enumValueLong&inputValueLong)==enumValueLong&&enumValueLong!=0) { enumOutputCollection.Add(enumValue); } } if (enumOutputCollection.Count == 0 && enumValues.GetLength(0) > 1) { T enumNoneValue = (T)enumValues.GetValue(0); if (Convert.ToInt64(enumNoneValue) == 0) { enumOutputCollection.Add(enumNoneValue); } } return enumOutputCollection; }

No credits at all to me for this one though, I stumbled upon it by mistake but since having computer crashes etc I cannot give my credits to the right webby unfortunately. Hugs and kisses for this though and definately worth sharing. If you have any questions what so ever about enums, flags or .net the myth the legend and the framework I recommend contacting Krzystof Cwalina. One of the chief architects over at Microsoft. If you just want to learn some more about enums I recommend you checking his extremely extensive do's and don'ts out over at http://blogs.msdn.com/kcwalina/archive/2004/05/18/134208.aspx

Tags:

C#

Generics, a bed time story...

by Mikael Henriksson 27. January 2009 18:59

Good evening,

Since I was totally struggeling with this I thought I'd better offer my expertice in this topic. I'll give a short story about the problems I faced and share the code that solved the problem at the very end.

The problem originated with not being able to bind a list of simple structs to a DataGridView in a WinForm application. Me and my colleague where about to actually pull our hairs of our heads one by one. We examined the return list and sure it contained items. It was all there but nothing would show up in the DataGridView.

Later it turns out none of the items were added as new meaning the DataGridView can't hmm wrong word maybe but index it. I could do nothing about the Struct we used for generating the data since this is done by an ocx connection so I asked around and was told to create a holder class that took the list of structs in an recreated it as a bindable list. Simple huh?

Now to the real stupid part. The perfectionist in me completely took over! I really wish I didn't have this obsession with reusable code. I really wanted to reuse the method for converting the non-bindable list to a bindable list :)

When I created the general conversion method I added two types let's call them HolderType and OriginType. First I got the silly message:

-"does not have a new constraint"
which I had to look up. Stupid thing was really messing with me so I added:

where HolderType : new()

Should do the trick right? Well no! No it said I could not use parameter when adding new. Some more reading and 3 hours later I finally found the solution!

First lets take a simple struct with an id and a value. There is actually 600 structs * 3.

 

public struct SimpleStruct
{
    public int Id;
    public string Value;
}

 

Then I need to wrap this struct in a class:

 

public class StructHolder
{
    private SimpleStruct _simpleStruct;

    public StructHolder(SimpleStruct simpleStruct)
    {
        _simpleStruct = simpleStruct;
    }

    public StructHolder()
    {
        _simpleStruct = new SimpleStruct();
    }

    public SimpleStruct SimpleStruct
    {
        get { return _simpleStruct; }
    }
    public int Id
    {
        get { return _simpleStruct.Id; }
    }

    public string Value
    {
        get { return _simpleStruct.Value; }
    }
}

 

 

And then I need a method to work on a collection of a struct and convert it to a collection of class :)

// Method to convert a list of structs to a bindable list
private IList<HolderType> GenerateUsableList<HolderType, OriginType>(List<OriginType> originlist) 
	where HolderType : new()
{    // Create the usable list    
	var holderlist = new List<HolderType>();

	originlist.ForEach(origintype => 
		holderlist.Add((HolderType) 
		Activator.CreateInstance(typeof (HolderType), origintype)));    
	
	return holderlist;
}

Tags:

C#

How do I configure Windows 2003 Server for Remote Applications?

by Mikael Henriksson 27. January 2009 18:59

My first try at this was to just let the user run a program set from "environement" under Users & Computers. It works ok, but the users where not satisfied with having to relogin if my application crashed. Second try was today and it's not completely finished but I'm getting there. Since the users are logging on to the server from thin clients I dont want them to be able to change anything on the server. Thats why I only allowed a program to be run in the remote desktop session. As soon as the application ended the remote desktop session ended.

Now this is how you do it!

  1. Download and install FC81887&displaylang=en" title="Group Policy Management Console">Group Policy Management Console
  2. Create a new security group in "Users & Computers"
  3. Open up gpmc.mmc and create a new policy, preferably named like the the security group so that I may easily be able to distinguish it.
  4. Add the newly created security group to the policy and make sure the group has read and apply rights to the policy.
  5. Remove most things from Start Menu, Windows Explorer and desktop. I might also like now want to remove access to control panel and task manager.
  6. Make sure that I hide the system drive (C:\) and have the users run their applications from let's say the D: drive with full access to a particular folder.
  7. Create a .vbs script to launch the application
  8. Place a shortcut to the application should it crash
  9. Do a policy update "cmd.exe gpupdate /force"

I found a great article to help me out. I did need to change a few things in the script though this is what my script looks like.

 

 

On Error Resume Next
Set fs = CreateObject ("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject ("WScript.Shell")

'Get the username and profile directory
MUser = WshShell.ExpandEnvironmentStrings ("%USERNAME%")
MUserProfile = wshShell.ExpandEnvironmentStrings("%USERPROFILE%")

'Delete icons
fs.DeleteFolder MUserProfile & "\Start Menu\Programs\Accessories",True
fs.DeleteFile  MUserProfile & "\Start Menu\Programs\*.lnk"

'Run the app

wshShell.Run "D:\Company\bin\%USERNAME%\Application\app.exe"

' Connect to wmi
set objWMIService = GetObject("winmgmts:root\cimv2")
Do
  found = false
' List the processes
strQuery = "Select * from win32_process where name='app.exe'"
set colProcesses = objWMIService.ExecQuery(strQuery)

for each proc in colProcesses

   ' Get the reference class linking processes to sessions to get the session object path
   strQuery = "References of {win32_process.handle='" & proc.handle & "'} where ResultClass=Win32_SessionProcess"
   set colSessionReferences = objWMIService.ExecQuery(strQuery)

   for each oSessionReference in colSessionReferences
      'Get associators of the session object that are user accounts (linked by win32_loggedonuser)
      strQuery = "Associators of {" & oSessionReference.antecedent & "} where AssocClass=win32_LoggedOnUser"
      set colUsers = objWMIService.ExecQuery(strQuery,,48)
        for each user in colUsers
         if user.name = MUser then found = true
      next
   next
next
Loop While found = true

'Run the Windows 2003 logoff utility
wshShell.Run "c:\windows\system32\logoff.exe"

Sweet! All done! Thanks a bunch to Amit Zinman

 

Tags:

Windows Server

Making good use of the Entity Framework in a Windows Forms application…

by Mikael Henriksson 27. January 2009 18:59

I have been abusing the Entity Framework lately so I thought I’d share some of what I have learned. First of all I must say there are quite a few things that need improvement. It is good that you can generate a model straight from the database and work towards your generated classes BUT! That’s about all you can do real easy… I could not find an easy enough way to customize these generated classes so I still have to use some “object datasources” if you will.

The most straight forward way to use the Entity Framework in a Windows Forms application is to create sort of a proxy class for the entity objects. Let’s say you have a generated class called Person. Create a class called PersonProxy.cs. In this “proxy” class you keep all business logic. The class should look something like:

namespace YourNamespace 
{ 
    using YourModelNamespace; 
    public class PersonProxy 
    { 
        private YourEntityContext context; 
        public PersonProxy() 
        { 
            context = new YourEntityContext(); 
        }

        public IList<Person> GetPersons() 
        { 
            var query = from p in Person 
                        select p; 
            return query.ToList(); 
        }

        public void CreatePerson(string firstName, string lastName) 
        { 
            Person p = new Person() { FirstName = firstName, LastName = lastName }; 
            context.AddObject("Person", p); 
            context.SaveChanges(); 
        } 
    } 
}

And instead of having the entity context straight in your form1.cs you can separate the business logic from the data logic a bit more than I used to do. Now in your form1.cs or whatever your form is called you instead use the proxy class. For several reasons obviously but my main point here is readability and to cut down the lines of code in the code behind of your form.

The form class would the end up in line with:

namespace WinClient 
{ 
	public partial class Form1 : Form 
	{ 
		private PersonProxy proxy; 
		public Form1() 
		{ 
			InitializeComponent(); 
		} 
		private void Form1_Load(object sender, EventArgs e) 
		{ 
			proxy = new PersonProxy(); 
			dataGridView1.DataSource = proxy.GetPersons(); 
		} 
		private void button1_Click(object sender, EventArgs e) 
		{ 
			proxy.CreatePerson(txtFirsName.Text, txtLastName.txt); 
		} 
	} 
}

You still have an open connection to your entity model, remember that the proxy class took care of this? Any validation against your model is done in realtime so hooking up some validation events of a datagridview should be a walk in the park. You also wont have to watch all those “AddObject”, EntityKey etc. That is visible to the proxy-class where we want it. The proxy class should also handle any kind of logic that is bound to the entity model. If you need to find what the next order number is or if an email is already taken that should be done in the proxy.

I hope this proves useful to anyone working with the Entity Framework. As I wrote earlier, it still feels “restricted” in ways. It is hard to create a complete domain model with the help of entity framework. I still have to take shortcuts but for me it is definitely worth it.

Tags: ,

Entity Framework | Windows Forms

Organizing Remote Desktop Connections...

by Mikael Henriksson 27. January 2009 18:59

Part of my job is as System Administrator and I currently have 20 remote desktop connections to keep track of. Since I have deployed all machines myself I mostly have the same passwords everywhere BUT! It's frustrating having to remember all ip adresses. Searching on the internet I found a few alternatives but if you remember the Highlander movies you probably remember the quote -"There can be only one!" (it's frequently used in the movies before someone cuts someone elses head of).

 

I fell in love with Remote Desktop Manager from Devolutions!

Tags:

Tools

In search of an easy way to use nested repeaters

by Mikael Henriksson 27. January 2009 18:59

I was searching around on the net for a way to display Hierarchical Data with nested repeaters. Found some quite extensive ways to solve this simple problem. Then someone (sorry for not remembering the url) had come up with a much easier way of doing this.

I'll start with the way I want it displayed

To acomplish this I first need 2 repeaters.

<asp:Repeater Runat="server" ID="_itemsRepeater" EnableViewState="false">
	<ItemTemplate>
		<asp:Label Runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
		<asp:Repeater 
			 Runat="server" ID="_subitemsRepeater" EnableViewState="false" 
			 DataSource='<%# DataBinder.Eval(Container.DataItem, "SubItems") %>'>
			 
			<ItemTemplate>
				<br/>
				<asp:Label Runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
			</ItemTemplate>

		</asp:Repeater>
		<br/>
	</ItemTemplate>
</asp:Repeater>

As you can see, nothing fancy so far. The real trick comes in code behind. First step is to databind the repeaters and here is where it gets beautiful!

protected void Page_Load(object sender, EventArgs e)   
{
	_itemsRepeater.DataSource = ItemsBLL.GetData();
	_itemsRepeater.DataBind();
}
   
public class ItemsBLL
{
	public static IList<Item> GetData()
	{
		IList<Item> itemList = new List<Item>();
		for (int i = 0; i < 10; i++) 
		{
			Item _item = new Item("item" + i.ToString());
			for (int j = 0; j < 5; j++)
			{
				Item subItem = new Item("subitem" + j.ToString());
				_item.SubItems.Add(subItem);
			}
			
			itemList.Add(_item);
		}
		
		return itemList;
	}
}


public class Item
{
	string _name;
	IList<Item> _subItems = new List<Item>();
	
	public Item(string name) { _name = name; }
	public string Name { get { return _name; } }  

	public IList<Item> SubItems { get { return _subItems; } }
}

See how I only have to bind this one time, the business layer does the rest. No recursive lists bindning to both of the repeaters. keeping it REAL simple for the UI programmer. In this case the UI programmer is myself really but I still find it very useful and less clutter in the codebehind of the aspx page. I admit this is probably not an ideal solution if you need all the extras with keeping separate lists for recursive functions or sorting etc. I just needed something simple this time.

Tags:

ASP.NET