How to resolve: Eval function does not work in master page, visible='<%# Eval(…) %>’

If you want to set the visibility of a control based on some C# code like User.IsInRole("Administrator") directly in your *.aspx page, you can use the data binding syntax <%# … %> in the ASP .NET page. You don’t need the Eval function, but you do need to bind you’re page, else the code in  <%# … %> will not be executed.

If you use the <%# … %> syntax in your master page, you should call this.DataBind() in your Page_Load event, else the code in <%# … %> won’t be executed.

*.ASPX

<%@ Master  Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" 
Inherits="Rvl.Demo.AspNet4.EF.WebApplication.SiteMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form runat="server">
<div class="page">
<asp:LinkButton ID="LinkButton1" runat="server" 
Visible='<%# User.IsInRole("Administrator") %>'>This link will only be visible for Administrators</asp:LinkButton>       
</div>
</form>
</body>
</html>

*.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Rvl.Demo.AspNet4.EF.WebApplication
{
public partial class SiteMaster : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
this.DataBind();
}
}
}

Best practices for using relative paths in CSS, HTML and ASP .NET

In many cases, elements or controls on your page must refer to an external resource such as an image or another *.aspx file. To refer to these resources I prefer to use relative paths, because on my development machine the URL might be http//:localhost but on the production machine the URL might have a host header, like http://mywebapp.roelvanlisdonk.nl. or an other port like http://localhost:81.

When using relative paths there are two kinds of elements

  • Not web server controls like (html tags, css statements etc.)
  • Web server controls (ASP .NET server controls)

Not web server controls (html tags, css statements etc.)

Always start an URL with a "/", no matter where you are in the tree structure, this relative URL will always work

  • "/Images/Logo.png"
  • <img alt="Logo" src="/Images/Logo.png" />

Don’t use:

  • "../" like "../Images/Logo.png"
  • "no slash at all" like "Images/Logo.png"

 

Web server controls

Always start an URL with a "~/"

  • "~/Images/Logo.png"
  • Response.Redirect("~/Pages/MyPage.aspx");
  • <asp:HyperLink ID="HyperLink1" runat="server" navigateUrl="~/Pages/Default.aspx">Test HyperLink</asp:HyperLink>

Don’t use:

  • "/" like "/Images/Logo.png"
  • "../" like "../Images/Logo.png"
  • "no slash at all" like "Images/Logo.png"

 

See: http://msdn.microsoft.com/en-us/library/ms178116.aspx

How to explicitly enable or disable C# unit tests in Microsoft Visual Studio 2010

If you want to enable or disable unit tests in Microsoft Visual Studio 2010, you can use the “Ignore” attribute.

This can be used to ignore ore exclude integration tests in a nightly continuous integration build.

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Rvl.Demo.Test
{
[TestClass]
public class UnitTest1
{
[TestMethod]
[Ignore]
public void TestMethod1()
{
// This unit test will be excluded (ignored) from the test runs
}
}
}

How to search in all you’re Microsoft Office Outlook 2010 folders and accounts at the same time (Hotmail, Exchange etc.)

In my daily work I use two mailboxes:

  • A Microsoft Hotmail account for private mail and text messages
  • A Microsoft Exchange account for work mail and text messages

If you want to search for mail in the inbox and sent items folder of both accounts, just type the search keywords in the search box and click “All Mail Items”

 

image

 

Note: I use the Microsoft Outlook Hotmail connector (64 bits) to manage my hotmail in Microsoft Office Outlook 2010 (free download from Microsoft, does not require hotmail plus)

PowerShell function to build a Microsoft Visual Studio setup project from command line with devenv.exe

If you want to build you’re Microsoft Visual Studio 2010 setup project in release mode, from the command line, you can use the following PowerShell function:

function RebuildSubsystem([string]$solutionPath, [string]$projectPath, [string]$devEnvPath)
{
    $parameters = "/Rebuild Release ""$solutionPath"" /Project ""$projectPath"" /ProjectConfig Release"
    "Process to start [$devEnvPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( "$devEnvPath", $parameters )
    $process.WaitForExit()
}

 

To call the function use:

RebuildSubsystem "C:\Projects\MyApplication\MyApplication.sln" "C:\Projects\MyApplication\MyApplication.Setup\MyApplication.Setup.vdproj" "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe"

PowerShell function to update a .net C# application, by using a setup package (*.msi), without changing the setup package version

The output of a Microsoft Visual Studio Setup Project is a setup package (*.msi). If you run this setup package on a system, you can’t re-install the package on that system, without changing the version of the setup package. If you want to update the .net C# application without changing the version number, you can use the following PowerShell script:

 

function DeploySubsystem([string]$name, [string]$msiPackageProductCodeGuid, [string]$msiPackagePath)
{
    "Uninstall $name"
    $parameters = "/qn /x $msiPackageProductCodeGuid"
    $processPath = "msiexec"
    "Run [$processPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( $processPath, $parameters )
    $process.WaitForExit()

    "Sleep for 5 seconds to make sure the system has updated the registry"
    [System.Threading.Thread]::Sleep(5000)

    "Install $name"
    $parameters = "/qn /i ""$msiPackagePath"""
    $processPath = "msiexec"
    "Run [$processPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( $processPath, $parameters )
    $process.WaitForExit()
}

 

To call the function use:

DeploySubsystem "MyFirstApplicaiton" "{396E89DB-5E5C-4781-9E88-0FEC56D9C06C}" "C:\Temp\MyFirstApplication.Setup.msi"   

How to check out – check in files from command line in Microsoft Visual Studio 2010 by using PowerShell

I have a Microsoft Visual Studio 2010 solution that contains a .net logging component and a customer solution that uses this .net logging component. When I fix a bug in the .net logging component I use a PowerShell script to automatically update the .net logging component in the customer solution:

 

"Settings"
$vsPath                     = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\{0}"
$devEnvPath                 = [string]::Format($vsPath, "devenv.exe")
$tfPath                     = [string]::Format($vsPath, "tf.exe")
$rebuildLoggingSolution     = $true
$checkOutFiles                 = $true
$copyFiles                     = $true
$rebuildCustomerSolution    = $true
$checkInFiles                 = $true
$files                         = @("LoggingComponent.BC.dll",
                                "LoggingComponent.BE.dll"
                                )

"Settings Logging Component Solution"
$lcPath                         = "C:\Projects\LC\Main\{0}"
$lcSolutionPath                    = [string]::Format($lcPath, "Main.sln")
$lcReleasePath                     = [string]::Format($lcPath, "Source\LC\bin\Release\{0}")

"Settings Customer Solution"
$cPath                             = "C:\Projects\Customer\Main\{0}"
$cSolutionPath                     = [string]::Format($lpPath, "Main.sln")
$cSharedBinariesPath            = [string]::Format($lpPath, "Shared Binaries\{0}")

if($rebuildLoggingSolution)
{
    $parameters = """$lcPath"" /rebuild Release"
    "Process to start [$devEnvPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( "$devEnvPath", $parameters )
    $process.WaitForExit()
}

if($checkOutFiles)
{       
    foreach($file in $files)
    {
        $path = [string]::Format($cSharedBinariesPath, $file)
        $parameters = "checkout ""$path"""
        "Process to start [$tfPath $parameters]"
        $process = [System.Diagnostics.Process]::Start( "$tfPath", $parameters )
        $process.WaitForExit()
    }
}

if($copyFiles)
{
    foreach($file in $files)
    {
        $source = [string]::Format($lcReleasePath, $file)
        $destination = [string]::Format($cSharedBinariesPath, “”)
        Copy-Item "$source" -Destination "$destination" -Force
    }
}

if($rebuildLocatiePlatform)
{
    $parameters = """$lpSolutionPath"" /rebuild Release"
    "Process to start [$devEnvPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( "$devEnvPath", $parameters )
    $process.WaitForExit()
}

if($checkInFiles)
{
    foreach($file in $files)
    {
        $path = [string]::Format($cSharedBinariesPath, $file)
        $parameters = "checkin ""$path"" /noprompt"
        "Process to start [$tfPath $parameters]"
        $process = [System.Diagnostics.Process]::Start( "$tfPath", $parameters )
        $process.WaitForExit()
    }
}

Showing a many to many relationship in a GridView by using Entity Framework 4.0, EntityDataSource and data binding in ASP .NET 4.0

The Microsoft SQL Server 2008 R2 sample database AdventureWorks, contains a table Product which as a many to many relationship with the table Document, via the junction table ProductDocument. This post describes the steps you will have to take to show all products and per product all document titles.

 

image

 

As you can see, product “506” has a relationship with multiple documents, so the column “Documents” shows 2 titles.  Because there can be more then one document title to show, I use a BulletedList, but you also could use a  CheckBoxList or DropDownList.

 

The data model

image

 

ASP .NET (*.aspx) page

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" 
CodeBehind="ManyToManyGridView.aspx.cs" 
Inherits="Rvl.Demo.AspNet4.EF.WebApplication.Pages.ManyToManyGridView" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<link href="../Styles/ManyToManyGridView.css" rel="stylesheet" type="text/css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<p class="pageTitle">Products</p>
<asp:GridView ID="GridView1" runat="server" AllowPaging="true" DataKeyNames="ProductID" 
AutoGenerateColumns="false" PageSize="50" DataSourceID="GridViewEntityDataSource">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="Id" ItemStyle-CssClass="columnPadding" 
HeaderStyle-CssClass="columnPadding" />
<asp:BoundField DataField="Name" HeaderText="Name" ItemStyle-CssClass="columnPadding" 
HeaderStyle-CssClass="columnPadding" />
<asp:TemplateField>
<HeaderTemplate>
<asp:Label ID="documentsHeaderLabel" runat="server" Text="Documents"></asp:Label>
</HeaderTemplate>
<HeaderStyle CssClass="columnPadding" />
<ItemStyle CssClass="columnPadding" />
<ItemTemplate>
<asp:BulletedList DataSource='<%# FillBulletedList(Container) %>' 
ID="documentsBulletedList" DataValueField="DocumentID" DataTextField="Title" 
runat="server"></asp:BulletedList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<!--
- Set EnableFlattening to "false", so you can use real "Product" entities in the FillBulletedList 
function and not wrapper (System.Web.UI.WebControls.EntityDataSourceWrapper) classes, generated 
by the entity framework.
- Don't use the "Include" property, this property should load related entities, like 
"ProductDocument" and "Document", but in my case in did not work, use the "OnQueryCreated" event
to provide a complicated inner join query, that loads related entities
-->
<asp:EntityDataSource ID="GridViewEntityDataSource" runat="server" EnableDelete="false" 
EnableInsert="false" EnableUpdate="false" 
ContextTypeName="Rvl.Demo.AspNet4.EF.WebApplication.Dal.AdventureWorksEntities" 
ConnectionString="name=AdventureWorksEntities" DefaultContainerName="AdventureWorksEntities" 
EntitySetName="Product" EnableFlattening="false" 
OnQueryCreated="GridViewEntityDataSource_QueryCreated">
</asp:EntityDataSource>
</asp:Content>

 

ASP .NET (*.cs) code behind page

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Rvl.Demo.AspNet4.EF.WebApplication.Dal;
using System.Data.Objects;
namespace Rvl.Demo.AspNet4.EF.WebApplication.Pages
{
public partial class ManyToManyGridView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{   
}
public List<Document> FillBulletedList(object container)
{
// Get the product from the current row
GridViewRow gvr = container as GridViewRow;
Product product = gvr.DataItem as Product;
// Create a list of documents related to the current product
List<Document> documents = new List<Document>();
foreach (ProductDocument pd in product.ProductDocument)
{
documents.Add(pd.Document);
}
return documents;
}
protected void GridViewEntityDataSource_QueryCreated(object sender, QueryCreatedEventArgs e)
{
// Load related entities ("ProductDocument" and "Document")
ObjectQuery<Product> query = e.Query.Cast<Product>() as ObjectQuery<Product>;
AdventureWorksEntities context = query.Context as AdventureWorksEntities;
context.Product.Include("ProductDocument").Include("Document");
// Show only product with related documents, by using a inner join (from .... from)
// Show only unique rows by using "Distinct"
// Show products ordered by name, by using "orderby"
var items = from ps in
((from p in query
from pd in p.ProductDocument
select p).Distinct())
orderby ps.Name
select ps;
e.Query = items;
}
}
}

The EntityDataSource use the OnQueryCreated event to provide an inner join query, that loads related entities, like “ProductDocument” and “Document”. It does not use the “Include” property, because that did not work in my case, I don’t no why, but I don’t have time to investigate. The “Include” is done on the Context of the query.

The GridView uses a TemplateField column and the ‘<%# … %>’ syntax to call a function for every row in the GridView to fill a BulletedList that shows all documents per product.