Silverlight and RIA services – overriding an attribute set in a base class.

Recently I found myself in the following situation. I had let’s say this class: DerivedClass inheriting from a BaseClass on the server side of things.

One of the properties of the BaseClass has the [Required] attribute applied.

public class BaseClass{

[Required]
public string Name { get; set; }

}

It just happen that in my DerivedClass I needed some more validation to be done so I would like to go for a [CustomValidation] attribute with its own custom validation method. More, I don’t need the constraint of the [Required] attribute anymore (if you remember the [Required] attribute, by default, implies the property should not have an empty or null value) so I want to revert its effect.

You can write the following code:

using System.ComponentModel.DataAnnotations

[MetadataType(typeof(DerivedClassMetaData)]
public class DerivedClass : BaseClass{

}

public class DerivedClassMetaData{

[Required(AllowEmptyStrings=true)]
[CustomValidation(typeof(SomeValidationClass), “ValidationMethod”)]
public string Name{ get; set; }

}

public class SomeValidationClass{

public static ValidationResult ValidationMethod(object value, ValidationContext validationContext){
}
}

The most important thing in the code above is the [MetadataType] attribute which is basically allowing me to attach meta data type to my derived class and basically readjusting some of its inherited attributes. One thing I did was to redefine the [Required] attribute to undo the effect of the similar definition on the BaseClass. Secondly I attached a custom validation to the Name property.
A very good resource on custom validation is
here.

On the client side, in the code generated the Name property looks like this:

[System.ComponentModel.DataAnnotations.CustomValidationAttibute(typeof(SomeValidationClass), @”ValidationMethod”)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings=true)]
public string Name{

}

The whole SomeValidationClass code is brought over from the business side and included in the generated code so the CustomValidationAttribute can find its arguments.

Cheers.

How to become a sysadmin on a SQLEXPRESS 2008 installation when you are not the original installer, SQL authentication is not enabled but you are a Windows administrator.

I have gotten a new job and I am in that phase where you start slowly to setup your machine, the environment etc.

One of the things I had to do is to set up the database for the project my team works on. The database has to be configured locally on a 2008R2 SQLEXPRESS instance (installed already by an system administrator and obviously under a different Windows account).

Long story short when I attempted to create a database I got access denied. Any other attempt to gain administrative rights over the database server failed. Did I mentioned the account I was logged on is part of the local Administrators? Yes, that too and even though I launched the management studio in admin mode as well, it did not help. It seemed as the database server did not really care that I am a mighty administrator on my machine Open-mouthed smile.

Reading some articles out there I learnt that the MS-SQL 2008 version does not include the Windows administrators in the by now very select and limited group of sysadmins. It seems to be true at least in my case. This means that if the person that installs the database server does not make you specifically a sysadmin you will not be automatically a full privileged user over the database server only because you are a Windows admin.

There is a way you can make yourself a sysadmin in a situation like mine where somebody else installed the server, left you out and you do not have access to the original installer.

You have to launch the database server in “single-user” mode which is when your Windows administrator account can act as a sysadmin and you can add it as a login to the database and make it part of the sysadmins role.

  • Start by stopping the SQL server and close the Management Studio
  • Launch a command prompt as an Administrator.
  • Then launch the SQL Server Configuration Manager; select SQL Server services; right click on the SQL Server (SQLEXPRESS) service and click Properties.
  • Select the Service tab and double click on Binary Path; you should get a drop down containing the command that launches that specific SQL instance:
  • image
  • Copy it and paste it in the previously opened command prompt window; add an extra –m to the parameters: “”c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\Binn\sqlservr.exe” –m –sSQLEXPRESS”;
  • Press Enter and it will look like Linux is about to start. When it stops and one of the last lines logged to the window is saying “SQL Server is now ready for client connection” it means you succeeded and your “single-user” instance is running.
  • Launch the SQL Server Management Studio as an Administrator and do whatever you want because you are now a sysadmin; basically you would like to add your Windows account as a SQL login; add the sysadmin server role to this login;
  • When you are done with it return to the command prompt window and press Ctrl+C and respond Y to shutdown the SQL service.
  • Go back to the Management Studio and start your instance the usual way and test. You should be able to do what you please.

Hope this helps.

Cheers.

System.Data.ConstraintException: Failed to enable constraints.

(continued from the title) One or more rows contain values violating non-null, unique, or foreign-key constraints.

I was working on a small project and I used the DataSet designer to quickly obtain an adapter and a strongly typed table.
I parameterized the table adapter so I can provide a different connection string and a different table for the SELECT query.

As always when you use the designer to initially generate the adapter and data table you have to point it to a table.
The designer inspects then the table and builds all the good things: table adapter, strongly typed data table and row, and so on.
The problem is that it hardcodes the connection string and the name of the table in the SELECT command and I would really like to re-use the generated code to obtain data from other tables too. So, I parameterized the adapter to accept a different table knowing well enough that the other tables have to have identical schema/structure.
I guess otherwise, the adapter.GetData() or adapter.Fill() methods will fail, probably with the above message – the one in the title.

If you read the error message in the title it doesn’t give you the impression it would be thrown for a schema discrepancy. Oh, but it does and that’s what confuses you as you don’t suspect a schema difference to be the problem! And we are not necessarily talking of a big discrepancy like missing a field or even a field of a different type.
No, the one that I encountered was caused by a different width of the field. The autogenerated MaxLength for one of my fields (10) was smaller than the width of the same field in a second table that I tried to use the adapter on. The field in the second table was 30 characters wide. This is what caused the exception to be thrown.

So, to get into some details I will start by saying that I am trying to access dbf tables somewhere in a folder. I am using the Visual FoxPro OLEDB driver which has the ability to treat a folder as a database and the dbf files in the folder as tables of the database. The Visual FoxPro ODBC driver does the same but needs a preconfigured entry in the ODBC connections of the system whereas with the OLEDB you can have the connection string built at run-time.

Anyway with MyDataAdapter and FileDataTable classes already generated, I wrote a few lines of code below to test that the adapter and my parameterizations work well enough to fill data from more than the initial table that I used to generate the classes from.

MyTableAdapter sta = new MyTableAdapter();
Test.FileDataTable sdt;
// setting the new connection for the adapter
sta.SetConnectionString(new OleDbConnection(“Provider=VFPOLEDB.1;Data Source=” + @
\\TESTSERVER\c$\FOLDER));
// setting the table we will use the adapter against
sta.SetTable(“FILE1.DBF”);
try {
// attempt to fill the DataTable
sdt = sta.GetData();
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
throw;
}

Now, this code works well when trying to fetch the records from FILE1.DBF (the original file) but when I tried to do the same from a structurally identical (almost) FILE2.DBF an exception was thrown: System.Data.ConstraintException: Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.

This message is not helping at all in finding precisely what the problem is and more, there was really no constraints to be concerned with and all the columns of the FileDataTable were defined to support nulls. Anyway, in an effort to see if I can get some more information I did a bit of digging and I was led to the Datatable.GetErrors() method. I thought it is worth a try as I had nothing else to go on with anyway.

So, I made the first modification to the code above by adding a DataRow[] dr = sdt.GetErrors(); line in the catch clause. That really didn’t work, as the line was causing an exception complaining that the sdt variable is null. Pretty obvious I said: “I am trying to call GetErrors on a table that doesn’t exist as it failed to be instantiated because an exception.” So, what I had to do is to instantiate an empty DataTable manually ahead of time, and then, in the try block use adapter.Fill(dataTable) instead of the GetData() syntax. This way by the time we call Fill(dataTable), dataTable is already an instantiated object which we can call GetErrors() on and obtain our array containing the DataRows with the problem.

MyTableAdapter sta = new MyTableAdapter();
Test.FileDataTable sdt = new Test.FileDataTable();
// setting the new connection for the adapter
sta.SetConnectionString(new OleDbConnection(“Provider=VFPOLEDB.1;Data Source=” + @
\\TESTSERVER\c$\FOLDER));
// setting the table we will use the adapter against
sta.SetTable(“FILE.DBF”);
try {
// attempt to fill the DataTable
sta.Fill(sdt);
}
catch (Exception ex) {

// get all the rows involved in errors
DataRow[] dr = sdt.GetErrors();
throw;

}

By expanding the first row in the now populated dr array, and looking at the RowError property, I can see:   “Column ‘prod’ exceeds the MaxLength limit.”
So this is when I checked the table and saw that the prod field was 30 chars wide, clearly more than the 10 chars MaxLength specified in the FileDataTable definition.
Apparently out of two tables which I believed identical the first one had a field narrower than the second table.

If you want to make this go away you could edit the FileDataTable’s problem field definition by modifying its MaxLength to be roomy enough.
Another way is to disable the enforcement of constraints at run-time by setting DataSet.EnforceConstraints = false, with the downside that the data in wider fields will be truncated and lost.

The last code addition is to accommodate this second approach. As the data tables don’t have their own EnforcedConstraints property we have to instantiate a DataSet.  We then add the table to it and then set the EnforceConstraints = false; This will cause the ignoring of the discrepancy between the field width in the data set definition and the width of the field that exists in the physical table. The code will not error out again but the value of the field will be truncated.

The final code could look something like this:

DataSet ds = new DataSet(“Test”)
MyTableAdapter sta = new MyTableAdapter();
Test.FileDataTable sdt = new Test.FileDataTable();
ds.Tables.Add(sdt);
ds.EnforceConstraints = true;
// setting the new connection for the adapter
sta.SetConnectionString(new OleDbConnection(“Provider=VFPOLEDB.1;Data Source=” + @
\\TESTSERVER\c$\FOLDER));
// setting the table we will use the adapter against
sta.SetTable(“FILE.DBF”);
try {
// attempt to fill the DataTable
sta.Fill(sdt);
}
catch (Exception ex) {

// get all the rows involved in errors
DataRow[] dr = sdt.GetErrors();
throw;
}

Cheers.

Talking about TFS 2010 Dashboard Permissions when running in SharePoint Server 2010 – Layers & Layers of Security

  This is a very interesting and revealing article about one of the many very misterious sides of the integration between Team Foundation Server Sharepoint. It is not exhaustive but for the amount of brand new information it contains, I surely not regret the 10 minutes that I spent reading it .

TFS 2010 Dashboard Permissions when running in SharePoint Server 2010 – Layers & Layers of Security

Good luck

Using foreach to loop through the elements of an enumeration in .Net (C#)

If you find yourself in need of looping through the elements of an enumeration
and do something for each of them then you may want to take a look at the following code:

enum Elements {
        Manganese,         Chrome,         Gold,         Argon
}
// we cannot loop through the enumeration but we can through an array of strings
// representing the name of the elements of that enumeration,
// which is what Enum.GetNames() method will gladly give us if we pass the type of the enumeration

foreach (string elementName in Enum.GetNames(typeof(Elements))) {
    // then, if we need to create an instance of the enumeration type based on the
    // current elementName we use Enum.Parse() method which takes:
    //  - the type of the enumeration and
    //  - the elementName (a string);
    //  Enum.Parse() returns <object> so we have to explicitly cast it to our enumeration type

    Elements element = (Elements)Enum.Parse(typeof(Elements), elementName);

}
so, the above foreach loops four times and in each iteration you have access to an element
of the enumeration as its native type and as a string representation – its name.
Cheers.

Talking about “The path is already mapped to workspace…” | Ryan McDonnell

You have one of your projects P source controlled by a Team Foundation Server TFS1. You have a local copy on a laptop.
You forget about that copy and in the meantime you installed and new Team Foundation Server TFS2 and decommissioned the old one.
Before, you took care to remove the local copy of project P on your desktop computer  from source control so you have no problems of adding it to the new TFS2 server and it work quite well.
One day you have to go on a field trip and you grab your laptop. When you open source control on the new TFS2, your project which was just added there is not mapped locally so you try to map it back to the same folder it always was. Unfortunately the message “The path is already mapped to workspace…” is unforgiving and does not allow you to do the mapping. Of course you can map it to a different folder but you do not want that because like me you carefully chose the name of the folder. It is the best name ever for that particular project and you don’t want to add a number at the end and ruin it. So I turned to Internet:

I read many other posts talking about similar or exactly the same error message and none helped.
My previous TFS was already uninstalled so I couldn’t use the tf.exe utility as other people suggested.

Then I came about this post … extremely useful post.
Only a small addition for Windows XP users though I guess and hope they are becoming scarce these days.
In Windows XP the path for the file is:
C:\Documents and Settings\theuser\Local Settings\Application Data\Microsoft\Team Foundation\version\Cache\VersionControl.config

The theuser – profile for the windows user account, and version are values that you have to provide. With VS2010 version is actually 3.0

Quote

“The path is already mapped to workspace…” | Ryan McDonnell
I just recently setup a new Team Foundation Server installation on a newer more powerful server. The older server was quickly taken offline. I stripped the source control bindings from old projects and proceeded to bind them to the new server.

In doing so, I was given the following error: The path is already mapped to workspace .A quick search lead me to a post by Buck Hodges, the lead developer on the Team Foundation Build team.

The solution is fairly easy. An XML file named VersionControl.config stores the mappings you have to each workspace and Team Foundation Server.

On Vista, this file is located at:  C:\Users\theuser\AppData\Local\Microsoft\TeamFoundation\version\Cache\VersionControl.config
Open up that file and remove the appropriate entry that pertains to the decommissioned server.

Where are the ASP.Net’s Profile, ProfileCommon when you need them?

We all know about the ability to maintain a profile for an user of an ASP.Net Web Site. I am going to assume that you already configured the aspnetdb database on your SQL server of choice in case you decided not to go with the disconnected aspnetdb in the App_Data folder.

Define a custom Profile in web.config

In many books they tell you to edit web.config by adding the <profile> element and within the <profile> element add a <properties> element which will finally contain the properties of the profile. It looks like this:
<authentication mode=”Forms”>
<forms defaultUrl=”Login.aspx” ></forms>
</authentication>
<connectionStrings >
<add name=”LocalSql2008Express” connectionString=”Data Source=HYPERCUBE\SQLEXPRESS;Initial Catalog=aspnetdb;Integrated Security=True”/>
</connectionStrings>
<profile enabled=”true” defaultProvider=”SqlProfileProvider”>
<providers>
<clear/>
<add name=”SqlProfileProvider” type=”System.Web.Profile.SqlProfileProvider” connectionStringName=”LocalSql2008Express”
applicationName=”ProfileTest”/>
</providers>
<properties>
<clear/>
<add name=”PreferredLanguage” allowAnonymous=”true” type=”System.String”/>
</properties>
</profile>
Now this book I was reading tells me that I should be able to access the PreferredLanguage property from the code behind this way: Profile.PreferredLanguage, where Profile is an instance of ProfileCommon, a class created behind the scenes and which exposes all the property definitions from the web.config file as property members of the ProfileCommon class (and obviously Profile too as it is an instance of ProfileCommon).
What the book that I read did not tell me is that in Visual Studio 2005/2008 this luxury of having the Profile instance created automatically for you is available only if your web site is a WebSite Project and it doesn’t work if you use a WebApplication Project. More, from what I see in Visual Studio 2010,  it doesn’t work at all with either type of web project. I am pretty sure of that, as I have brought a Web Site project up and Profile and ProfileCommon are not recognized by the compiler.
Actually after I installed the RTM I can say that VS 2010 does actually create Profile instance of a ProfileCommon, automatically generated class.
However, while racking my brains to understand what is going on I came across a post in the Visual Studio 2008 documentation which helps one in coding a ProfileCommon class and then instantiate a Profile variable of type ProfileCommon in the code behind class of certain pages as needed.
Excerpt:
The Visual Studio 2008 Web application project does not automatically include the ProfileCommon class. However, you can create your own ProfileCommon class that contains strongly typed properties for the items configured in the profile system. Then you can access the current Profile property of the HttpContext object to get and set the properties. The following example shows how to create a custom ProfileCommon class.
So, you can spend some effort and code the ProfileCommon yourself. Let’s see how the code should look like:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Profile;

namespace ProfileTest
{
public class ProfileCommon
{
public string PreferredLanguage
{
get{ return (string) HttpContext.Current.Profile.GetPropertyValue(“PreferredLanguage”); }
set{

HttpContext.Current.Profile.SetPropertyValue(“PreferredLanguage”,value); }
}
}
}
You can then add an instance of the ProfileCommon class named Profile to the pages that must use the profile system, as shown in the following example.

public partial class _Default : System.Web.UI.Page
{
ProfileCommon Profile = new ProfileCommon()
txtLanguage.Text = Profile.PreferredLanguage;
//…
}

Define a custom Profile in code

It is an inconvenience not having the Profile object created automatically for you so you can easily access the profile’s properties. There is another approach to this and that is to not use web.config at all to define the profile but rather do it in code. Yes, create a custom profile by inheriting the ProfileBase. I am not going to describe the whole process here, as there is an excellent blog entry by Jon Galloway at
Cheers,
May 1st, 2010