Toolroom Tech Blog

Devlopers Digest

Returning Templates after AJAX Request in MVC 3

How to return a DisplayTemplate or EditorTemplate in a partial response after AJAX calls in ASP.net MVC 3.

Ever had the need to return a DisplayTemplate or EditorTemplate within a Response after an AJAX call? Altough it is not very nice, the easiest way seems to be this ... and it may save lots of time: just access the view directly by its filename.

public PartialViewResult GetNew()
{
	return PartialView(
		"~/Views/Receipe/EditorTemplates/IngredientModel.cshtml", 
		new IngredientModel { Id = Guid.Empty }
	);
}

Windows 7 Keyboard Shortcuts

An almost complete list of keyboard shortcuts for Windows 7.

Short but useful

New Win 7 Shortcuts

Win+ Maximize the current window
Win+ If the current window is maximized, restore it; if the current window is restored, minimize it
Win+ Dock the current window to the left half of the screen
Win+ Dock the current window to the right half of the screen
Win+Shift+ Move current window to the left monitor (with dual monitors)
Win+Shift+ Move current window to the right monitor (with dual monitors)
Win+Home Minimize all but the current window
Win+Space Peek at the desktop
Win+[Plus sign] Zoom in
Win+[Minus sign] Zoom out
Win+P Open the projection menu (generally used for laptops connected to projectors)
Alt+P In Explorer, show/hide the preview pane

Win7 Taskbar Modifiers

Shift+Click Open a new instance of the program
Ctrl+Click Cycle between windows in a group
Middle Click Open a new instance of the program
Ctrl+Shift+Click Open a new instance of the program as Administrator
Shift+Right-Click Show window menu

Window Management

Alt+F4 Close the active window
Alt+Tab Switch to previous active window
Alt+Esc Cycle through all open windows
Win+Tab Flip 3D
Ctrl+Win+Tab Persistent Flip 3D
Win+T Cycle through applications on taskbar (showing its live preview)
Win+M Minimize all open windows
Win+Shift+M Undo all window minimization
Win+D Toggle showing the desktop
Win+ Maximize the current window
Win+ If the current window is maximized, restore it; if the current window is restored, minimize it
Win+ Dock the current window to the left half of the screen
Win+ Dock the current window to the right half of the screen
Win+Shift+ Move current window to the left monitor (with dual monitors)
Win+Shift+ Move current window to the right monitor (with dual monitors)
Win+Home Minimize all but the current window
Win+Space Peek at the desktop
Win+[Plus sign] Zoom in
Win+[Minus sign] Zoom out

Starting Programs

Win+1 Open the first program on your Quick Launch bar
Win+2 Open the second program on your Quick Launch bar
Win+n Open the nth program on your Quick Launch bar
Win+U Open the ease of access center
Win+F Open the search window
Win+X Open the Mobility Center
Win+E Open Explorer
Win+R Open the Run window
Win+B Move focus to notification tray (the right-most portion of the taskbar)
Win+P Open the projection menu (generally used for laptops connected to projectors)
Win+Pause Open the System Properties portion from the Control Panel
Ctrl+Shift+Esc Open Windows Task Manager

Logging in and out

Win, , Enter Shutdown
Win, →, →, R Restart
Win, →, →, S Sleep
Win, →, →, W Switch Users
Win+L Locks computer

Windows Explorer

Alt+ Go back
Alt+ Go forward
Alt+ Go up a directory
Alt+D Move focus to address bar
Alt+D, Tab Move focus to search bar
Alt+Enter Open the Properties window of the current selection
Ctrl+Mousewheel Change the view type (extra large, small, list view, detail, etc.)
Alt+P Show/hide the preview pane

In-Browser issues with form element heights

How to apply the same height to form elements in web pages.

Ever tried to apply the same height to a textbox and a select? It's crazy!

The problem is (maybe god knows why) the different boxing model. Try this ... and it should work:

input, select, textarea {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -ms-box-sizing: border-box;
}

Browser compatibility: Opera, Mozilla and Webkit and IE >8

Reset your CSS

Reduce browser styling inconsistencies with a few lines of css, for HTML4 and HTML5.

This css from Eric Meyer resets almost everything to unique base values for all browsers, so that you start with a unique base. Or click here to go to the source page.

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

Everyone's SEO'ing

Search Engine Optimization (SEO) is very important. But Online-Marketing, finally that's what you aim to achieve with SEO, is much more. Get an overview in a few lines: SEM, SEA, CRO, SMO, SMM

It's not enough 

Nowadys the whole internet world talks about Search Engine Optimization (SEO). Indeed, SEO is ultra important for web presences to get present in the minds of people. But Online-Marketing, finally that's what you aim to achieve with SEO, is much more. SEO is just one of at least three equally important parts of online marketing.

Intruducing the Online-Marketing Team

  1. Search Engine Marketing (SEM)
    SEM includes all actions to introduce web pages to search engines or raise their visibility. Short: Everything that could bring your web page on top of search result lists on Google, Bing, Yahoo and other engines. On closer inspection you can differentiate between Search Engine Advertising (SEA) and Search Engine Optimization (SEO).
    The typically payable methods for SEA incorprate services like Google AdWords, banner advertising, text displays. In contrast, the primary goal of SEO is to make a web page successful also without paying search engine providers. Therefore, SEO actions aim to optimize a web pages content, structure and links from/to other pages: Visible Content, Meta Tags (including Dublin Core), Rich Snippets, etc.
  2. Conversion Rate Optimization (CRO)
    Simplified, CRO is all about the conversion of a visitor to a lead. Therefore CRO tries to lead the visitor into a given direction or scheme that promises success (whatever success may be): convert the visitor of a web shop into a customer or buyer, convert the visitor of a blog into a reader as he subscribes to your RSS feed, ...
  3. Sozial Media OPtimization (SMO), sometimes called Sozial Media Marketing (SMM)
    SMO is the optimization of web pages in respects of better interaction with social media services like Twitter, Google+, Facebook, LinkedIn, and all others. The actions include the permanent creation and delivery of content, options to share and spread content with Like-Buttons and Sozial Bookmarks, Interaction with visitors with comments and incentive programmes, active share of content via rss services like twitterfeed.

More game players

  1. Usability
    If a software is not user friendly, nobody likes it (minorities excluded). Just imagine, do you buy in online shops that are slow and where it takes lots of time to find the product you're searching for? Websites  focussed on usability profit from the positive side effects on CRO!
  2. Professionality and respactability
    Give your web pages a professional design and represent yourself serious. A Do-It-Yourself webpage or a free of charge 'out of the box thingy' is really not the way to make a web page successful.

Shurly, there are other factors and disciplines that make web pages successful. But you catch the most with this.

OrderBy vs. ThenOrderBy

Few days ago I corrected a bug where the developer didn't use linq ordering properly, the result was very disarranged list content. So if you've ever wondered why Linq proivides us with OrderBy AND ThenOrderBy, you should read this.

Few days ago I corrected a bug where the developer didn't use linq ordering properly, the result was very disarranged list content. So if you've ever wondered why Linq proivides us with OrderBy AND ThenOrderBy, you should read this.

Imaginary sample project

Our little project uses the Entity Framework to display a simpe task list that keeps track of started and already finished tasks. In our list we want to show all started tasks before all others.

The table 'Task' owns the following columns:

  1. Id: int
  2. Title: nvarchar(50)
  3. Description: nvarchar(1000)
  4. Start: datetime2
  5. End: datetime2

OrderBy

Idea 1: Let's try it with OrderBy

Entities.Tasks.OrderByDescending(l => l.End == null)

Ok, active items are on top ... but all other tasks are also ordered by the [End]. Let's take a look on the generated sql statement:

SELECT 
[Task1].[Id] AS [Id], 
[Task1].[Title] AS [Title], 
[Task1].[Description] AS [Description], 
[Task1].[Start] AS [Start], 
[Task1].[End] AS [End]
FROM ( SELECT 
	CASE WHEN ([Extent1].[End] IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1], 
	[Extent1].[Id] AS [Id], 
	[Extent1].[Title] AS [Title], 
	[Extent1].[Description] AS [Description], 
	[Extent1].[Start] AS [Start], 
	[Extent1].[End] AS [End]
	FROM [dbo].[Task] AS [Extent1]
)  AS [Task1]
ORDER BY [Task1].[C1] DESC

Idea 2: The ultimate solution: add a second orderby!

Entities.Tasks.OrderByDescending(l => l.End == null).OrderByDescending(l => l.Start)

But the result is frustrating because of Linqtelligence: The first order is completely ignored, since we would order by [End] and then just reorder by [Start].

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[DisplayName] AS [DisplayName], 
[Extent1].[ProjectId] AS [ProjectId], 
[Extent1].[ActivityId] AS [ActivityId], 
[Extent1].[Start] AS [Start], 
[Extent1].[End] AS [End], 
[Extent1].[Fee] AS [Fee], 
[Extent1].[BillableQuota] AS [BillableQuota], 
[Extent1].[Notes] AS [Notes], 
[Extent1].[UserId] AS [UserId], 
[Extent1].[DBInsert] AS [DBInsert], 
[Extent1].[DBUpdate] AS [DBUpdate], 
[Extent1].[DBState] AS [DBState]
FROM [dbo].[LogItem] AS [Extent1]
ORDER BY [Extent1].[Start] DESC

Idea 3: Adding a second orderby does not make sense, since it would just be a secondary order. Let's try intersect, to get select the active tasks first and merge it with the finished afterwards.

Entities.Tasks.Where(l => l.End == null).OrderByDescending(l => l.End == null).Concat(Entities.Tasks.Where(l => l.End != null).OrderByDescending(l => l.Start));

Active items are again on top, but nothing is ordered by [Start]. So what happened? Linq has thrown all ordering and instead built a pretty union statement.

SELECT 
[UnionAll1].[Id] AS [C1], 
[UnionAll1].[Title] AS [C2], 
[UnionAll1].[Description] AS [C3], 
[UnionAll1].[Start] AS [C5], 
[UnionAll1].[End] AS [C6]
FROM  (SELECT 
	[Extent1].[Id] AS [Id], 
	[Extent1].[Title] AS [Title], 
	[Extent1].[Description] AS [Description], 
	[Extent1].[Start] AS [Start], 
	[Extent1].[End] AS [End]
	FROM [dbo].[Task] AS [Extent1]
	WHERE [Extent1].[End] IS NULL
UNION ALL
	SELECT 
	[Extent2].[Id] AS [Id], 
	[Extent2].[Title] AS [Title], 
	[Extent2].[Description] AS [Description], 
	[Extent2].[Start] AS [Start], 
	[Extent2].[End] AS [End]
	FROM [dbo].[Task] AS [Extent2]
	WHERE [Extent2].[End] IS NOT NULL) AS [UnionAll1]

 

ThenOrderBy

ThenOrderBy solves the issue very lovely.

SELECT 
[Task1].[Id] AS [Id], 
[Task1].[Title] AS [Title], 
[Task1].[Description] AS [Description],
[Task1].[Start] AS [Start], 
[Task1].[End] AS [End]
FROM ( SELECT 
	CASE WHEN ([Extent1].[End] IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1], 
	[Extent1].[Id] AS [Id], 
	[Extent1].[Title] AS [Title], 
	[Extent1].[Description] AS [Description], 
	[Extent1].[Start] AS [Start], 
	[Extent1].[End] AS [End]
	FROM [dbo].[Task] AS [Extent1]
)  AS [Task1]
ORDER BY [Task1].[C1] DESC, [Task1].[Start] DESC

T-SQL statement for Entity Framework query

A very useful snippet that creates the T-SQL query for a linq statement.

Snippet

This very useful snippet below creates the T-SQL query from a linq statement.

/// <summary>
/// Returns the T-SQL string for a given query
/// </summary>
/// <param name="queryable">Source ObjectQuery object to get the SQL for</param>
/// <returns>T-SQL statement for the input query object</returns>
public static string GetQuery(this IQueryable queryable)
{
	if(queryable == null || !(queryable is ObjectQuery))
		throw new ArgumentException("Argument is null or no ObjectQuery.", "queryable");
	 
	return ((ObjectQuery)queryable).ToTraceString();
}

Linq to Sql: Row not found or changed

Finding a way back from LINQ to SQL cuncurrency hell.

Yesterday I was trapped in concurrency hell and had no idea why.

Background

The Windows Phone App I am currently working on, synchronizes data between a local database and a REST service. When the app receives an update for a row, I select the row to be updated from the local database via LinqToSql, update its values with the data from the service and save it.

The issue

As you can see in the snippet below, I select a record, update it ... and a few lines later the update crashes with a lovely System.Data.Linq.ChangeConflictException saying "Row not found or changed". How is that possible? I'm sure that nobody modifies or deletes the data in the meantime.

private void updatePerson(Person person)
{
	var localPerson = DataStore.Data.Persons.Where(p => p.Id == person.Id);
	if(localPerson == null)
	{
		//person is new, so create it
		DataStore.Data.Persons.InsertOnSubmit(person);
	}
	else
	{
		//update existing person
		localPerson.Name = person.Name;
		localPerson.CustomerId = person.CustomerId;
		localPerson.DepartmentId = person.DepartmentId;
		localPerson.IsActive = person.IsActive;
	}
	
	DataStore.Data.SubmitChanges(); //crash boom bang --> Row not found or changed.
}

Aha! LINQ to SQL uses Optimistic Concurrency

Hahaaa, that's it! When LINQ to SQL selects a record, it does not lock any data. When it is updating a record, it compares all columns with their original values.

So what does this mean? The update query that I expected from LINQ to SQL was:

UPDATE Persons
SET Name = 'Mr. Buggy',
	CustomerId = null,
	DepartmentId = 6,
	IsActive = true
WHERE
	Id = 9999

But the real world is different; due to optimistic concurrency it compared all columns:

UPDATE Persons
SET Name = 'Mr. Buggy',
	CustomerId = null,
	DepartmentId = 6,
	IsActive = true
WHERE
	Id = 9999 AND
	Name = 'Mr. Buggy' AND
	CustomerId = 1234 AND
	DepartmentId = 1 AND
	IsActive = true

This still does neither explain nor solve my issue, since my original values did not change in the meantime. But with the knowledge of Optimistic Concurrency and a few more minutes of debugging, I found (my) fault: The database field for CustomerId is not nullable ... but the REST Service returned null.

I fixed this and everyone (that's me) is happy!

Properly adding UIElements from code

Although it's not the way how you should design your WPF applications, you may try to add UIElements at runtime from code behind. Therefore you should introduce the recently added elements into the XAML namescope. Otherwise you will not be able to find the added item  again and you may run in troubles with animation storyboards, since they use runtime name lookups with their key property "TargetName".

In the sample below, a row with a label and a textbox is added to a grid at runtime:

private void AddParam(int rowId, string labelText, string displayValue)
{
	grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

	var label = new Label { Content = labelText };
	label.SetValue(Grid.RowProperty, rowId);
	label.SetValue(Grid.ColumnProperty, 0);
	grid.Children.Add(labelO);

	var textboxName = string.Format("dauerPosParam{0}__O", rowId);
	var textbox = new TextBox { Text = displayValue, Name = textboxName };
	textbox.SetValue(Grid.RowProperty, rowId);
	textbox.SetValue(Grid.ColumnProperty, 1);
	grid.Children.Add(textbox);
	if(FindName(textboxName) == null)
		RegisterName(textboxName, textbox);
}

Get further Information at FrameworkElement.RegisterName or NameScope.RegisterName.

Default Mobile Viewport Width

Recently I've done some optimizations for mobile websites where I focused on the default viewport size of common mobile browsers.

Here's the list of the default viewport width I used:

Windows Phone 7 IE: 1024px
Android: 800px
iPhone Safari: 980px
Opera Mobile: 850px