Thursday, April 26, 2012
The following query will find all tables in my catalog with a column name like ‘city’
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%City%'
ORDER BY schema_name, table_name;
Thursday, March 01, 2012
Did you know you can set your DNS Servers from the command prompt using the NETSH command (available in win 2003 and later)?
You can even specify the order in which the servers are registered in the DNS lookup
netsh interface ip set dns "Local Area Connection" static 8.8.8.8
netsh interface ip add dnsservers "Local Area Connection" 8.8.4.4 index=2
netsh interface ip add dnsservers "Local Area Connection" 10.0.8.100 index=3
If you want to configure DNS to use DHCP:
netsh interface ip set dns “Local Area Connection” dhcp
if you want to clear the table entirely:
netsh interface ip set dns “Local Area Connection” address=none
You’ll need to replace “Local Area Connection” with your LAN Connection name, should it differ.
Wednesday, February 29, 2012
Get a summary aggregation of rows in T-Sql is easy thanks to the Sum operator:
Select Sum(Qty) From Table
Why is there no Product() aggregation operation for T-Sql? Sometimes I want the values multiplied, not added.
Luckily, some one who is much smarter in math than I, observed:
log(A * B) = log(A) + log(B)
So, summing the log, and converting back to its exponential value will yield its product.
Select CAST(EXP(SUM(LOG(Qty))) as int) as ExtendedQTY
Happy Calculating!
UPDATE: The above expression seems to calculate the wrong value when the value being multiplied is a large number. For example:
Select CAST(EXP(LOG(11111)) as int) yields 11110, not 11111.
Try this instead:
DECLARE @ExtendedQty FLOAT
Select @ExtendedQTY = COALESCE(@ExtendedQTY, 1) * Table.Qty From Table
Select @ExtendedQty
As always, your feedback is welcome.
Saturday, January 28, 2012
If your connection hangs while attempting to start sql server broker service, its likely caused by the system trying to gain exclusive access to your database. Some people recommend stopping and restarting the sql server instance. I find that a little heavy-handed, like swatting a fly with a sledge hammer. Instead switch the database into single user mode, enable the broker service, and restore the database to multi-user mode.
1) Set the database to single user mode:
ALTER DATABASE [DBNAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
2) Enable Broker Service on the database
ALTER DATABASE [DBNAME] SET ENABLE_BROKER;
3)Restore the database to multi-user mode
ALTER DATABASE [DBNAME] SET MULTI_USER
Of course you’ll need proper permissions, but enabling the service this way prevents interruption to any other databases running on your server.
Also make sure Broker Service is enabled:
SELECT is_broker_enabled FROM sys.databases WHERE name = ‘DBNAME’;It should return 1 if its enabled.
-- Enable Service Broker:
ALTER DATABASE [DBNAME] SET ENABLE_BROKER;
-- Disable Service Broker:
ALTER DATABASE [DBNAME] SET DISABLE_BROKER;
Wednesday, October 26, 2011
Tired of ISP DNS service errors? switch to use Google’s. They are FAST and ALWAYS available.
Primary: 8.8.8.8
Secondary: 8.8.4.4
1: var daysOfWeek = new[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
2: var workDays = daysOfWeek.Except( new []{ "SUNDAY", "SaTURdaY"}); // Performs a case sensitive search and yields Sunday,Monday - Saturday.
3: workDays = daysOfWeek.Except(new[] { "SUNDAY", "SaTURdaY" },StringComparer.OrdinalIgnoreCase); // Performs a case insensitive search and yields Monday-Friday
The except operator takes a comparer that tells it how to evaluate the two lists. Nice one!
Thursday, June 30, 2011
Sometimes working with the js Serializer is easy, sometimes its not. When I attempt to serialize an object that is derived from a base, the serializer decided whether or not to include the type name.
When its present, the type name is represented by a ___type attribute in the serialized json like this:
{"d":{"__type":"Commerce.Integration.Surfaces.OrderCreationRequest","RepId":0}}
The missing type name is a problem if I intend to ship the object back into a web method that needs to deserialize the object. Without the Type name, serialization will fail and result in a ugly web exception.
The solution, which feels more like a work-around, is to explicitly tell the serializer to ALWAYS generate the type name for each derived type. You make this declaration by adding a [GenerateScriptType())] attribute for each derived type to the top of the web page declaration.
For example, assuming I had 3 derivations of OrderCreationRequest; PersonalOrderCreationRequest, CompanyOrderCreationRequest, InternalOrderCreationRequestion, the code-behind for my web page would be decorated as follows:
[GenerateScriptType(typeof(PersonalOrderCreationRequest))]
[GenerateScriptType(typeof(CompanyOrderCreationRequest))]
[GenerateScriptType(typeof(InternalOrderCreationRequest))]
public partial class OrderMethods : Page
{
...
}
With the type names generated in the serialized JSON, the serializer can successfully deserialize instances of any of these types passed into a web method.
Hope this helps you as much as it did me.
Thursday, April 28, 2011
I was working on a project that required a determination if the type was an IEnumerable collection of some type.
Using a bit of reflection and the handy-dandy GetGenericTypeDefinition method, I arrive at this:
Code Snippet
- public static bool IsIEnumerableOfT(Type type)
- {
- return type.GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof (IEnumerable<>)) ;
- }
Happy Coding!
Wednesday, April 20, 2011
Ever wanted to re-order your Thunderbird accounts?
You can either modify the prefs.js manually
1. Exit Thunderbird if its running.
2. Locate your prefs.js file (default location is c:\users\[your account]AppData\Thunderbird\Profiles
3. create a backup , just in case.
4. Open the prefs.js in any text editor and look for: user_pref("mail.accountmanager.accounts", "account1,account2,account3,account4…"); line
5. Change the order of the accounts manually
6. Restart Thunderbird
OR
1. Download and install the FolderPane add-on.
2. From Thunderbird, select Tools->Add ons –> Folderpane and reorder the accounts using the “Move Up” and “Move Down” buttons.
3. Close and restart Thunderbird.
The choice is yours.
Tuesday, March 29, 2011
I’m posting this here because I keep forgetting the syntax, and thought others might benefit as well.
Given :
public class ParentItem
{
IEnumerable<ChildItem> Children
}
Selecting all the childitem instances from an IEnumerable<ParentItem>:
var allChildren = ParentItems.SelectMany(parent=>parent.Children);
Selecting matching childItem instances from an IEnumerable<ParentItem>:
var selectedChildren = ParentItems.SelectMany(parent=>parent.Children).Where(child=><boolean expression for filtering children>)
Saturday, March 19, 2011
Culture beats Strategy every time.
Tuesday, March 15, 2011
If your website uses the AppPoolIdentity and requires access to the private key of an x509Certficate, you’ll need to grant the read permissions to the iis application pool.
To grant permissions to the AppPoolIdentity:
- Run Certificates.MMC (or Start->run->mmc.exe, Add Certificate Snap-In for LocalMachine)
- Select the certificate (Personal node on the certificate tree) , right click and Manage Permissions.
- Add a new user to the permissions list.
- Enter "IIS AppPool\AppPoolName" on the local machine". Replace "AppPoolName" with the name of your application pool.
Tuesday, February 15, 2011
I’ve read some posts regarding this error when using the First() or Single() command. They suggest using FirstOrDefault() or SingleorDefault() instead.
But I recently encountered it when using a Sum() command in conjunction with a Where():
Code Snippet
- var effectiveFloor = policies.Where(p => p.PricingStrategy == PricingStrategy.EstablishFloor).Max(p => p.Amount);
When the Where() function eliminated all the items in the policies collection, the Sum() command threw the “Sequence contains no elements” exception.
Inserting the DefaultIfEmpty() command between the Where() and Sum(), prevents this error:
Code Snippet
- var effectiveFloor = policies.Where(p => p.PricingStrategy == PricingStrategy.EstablishFloor).DefaultIfEmpty().Max(p => p.Amount);
but now throws a Null Reference exception!
The Fix:
Using a combination of DefaultIfEmpty() and a null check in the Sum() command solves this problem entirely:
Code Snippet
- var effectiveFloor = policies.Where(p => p.PricingStrategy == PricingStrategy.EstablishFloor).DefaultIfEmpty().Max(p => p==null?0 :p.Amount);
Tuesday, January 18, 2011
If you attempt to make an ajax call that cross domain or protocol boundaries, the default XHR (XmlHttpRequest) processor will fail. The out-of-the-box implementation forbids crossing boundaries.
Enter flXHR. A flash-based proxy that implements (and extends) the XHR API. That’s good news for JQuery developers. It means you can use flXHR just like the native Jquery XHR. There’s also a Jquery proxy plugin that makes it SIMPLE.
You can download the sample here. In my example, I’m hosting the website under IIS and have created an alias for localhost called CMDEV. I’ve also configured the website for SSL. This gives me 1 website with multiple domain names, and allows me to simulate cross-domain & cross-protocol calls. The service code resides in the code behind page and is a static method decorated with the [WebMethod] attribute.
About crossdomain.xml: The file must reside in the website root (unless you specify its location with the PolicyURL setting) and is VERY picky about the structure of the file. My sample sets the security policy wide open and is not recommended for production use.
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="master-only" />
<allow-access-from domain="*" secure="false" />
<allow-http-request-headers-from domain="*" headers="*" secure="false" />
</cross-domain-policy>
If you wish to support cross-protocol calls (calling an HTTPS service from an HTTP page), you must include the secure=false attribute for both allow-access-from and allow-http-request-headers-from tags. You’ll also need to specify the noCacheHeader:false setting when configuring the proxy.
(from the Unsecured.aspx page in the sample)
$.flXHRproxy.registerOptions(URL_SECURED + "/", { xmlResponseText: false, noCacheHeader: false });
a final word, flXHR only works for asynchronous calls. If you attempt to make a syncrhonous ajax callback, the xhr proxy will select the default processor, and you’ll get a failure (“Access is denied”) message.
Tuesday, November 23, 2010
I found this fix online which appears to have resolve this issue, so I wanted to share it here. I take no credit/responsibility for it, except to say that it has resolved the issue for me.
Set the 32-bit flag on resgen.exe
a. Open a Visual Studio command-prompt as an administrator
b. Navigate to the Microsoft SDKs\Windows\v7.0A\bin directory.
c. ***SAVE A COPY*** of your original resgen.exe file. This is very important if you want to be able to replace our tweak with the original file without having to repair your installation.
copy resgen.exe regen.exe.old
d. Set the 32-bit flag to true using corflags.exe
corflags.exe resgen.exe /32BIT+ /Force
e. Note the warning about strong name issues. On my machine the build now succeeds, without needing to do any additional work due to strong name issues. IF you have problems after trying this method, you can try the following to skip string name verification for that assembly-
f. Register resgen.exe for strong name verification skipping using sn.exe
sn.exe –Vr resgen.exe
WARNING! This is a security risk. You are bypassing strongname verification for this assembly, making it possible for malicious code posing as resgen.exe to execute. To turn verification back on, use sn.exe –Vu resgen.exe
Friday, November 05, 2010
Supposedly, HTTPPostedFile.FileName is supposed to contain just the name of the uploaded file. It should exclude the original filename path. This doesn’t always appear to be the case, and seems to vary by the browser doing an upload.
To avoid the browser issue entirely, use a FileInfo(HttpPostedFile.FileName) to return just the file name (and extension) portion of the file.
Change this:
Code Snippet
- var saveFileName = Path.Combine(UploadedFileServerPath, FilePackage.PostedFile.FileName);
to this:
Code Snippet
- var saveFileName = Path.Combine(UploadedFileServerPath, new FileInfo(FilePackage.PostedFile.FileName).Name);
I recently migrated my dev environment to a new pc. I moved over all the databases and reattached them. Unfortunately, I soon discovered my SSBS services weren’t working. I was sending messages to my service, but nothing was showing up in the queue. I added logging and monitoring to the stored procs that act as an entry point to the services, and the stored procs I use for activation. Still, nothing.
When I ran the Broker Server Diagnostic tool (ssbdiagnose) (available in {Program files}\Microsoft Sql Server\100\tools\binn, it reported the following issues:
Service Broker Diagnostic Utility
The EXECUTE AS for the user dbo specified for activation on queue dbo.FulfillerQueue_Initiator_Mock cannot be impersonated due to an exception Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
The EXECUTE AS for the user dbo specified for activation on queue dbo.FulfillerQueue_Target_Mock cannot be impersonated due to an exception Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
Could not validate the SEND permission of user dbo on service FulfillerService_Target_Mock due to exception Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
3 Errors, 0 Warnings
So what's going on here? I use integrated security on my dev machine, why is it complaining that the principal "dbo" doesn't exist?
The problem is the result of moving my database from another server (my previous dev machine). The underlying SID of the owner object is no longer valid in my new database. Since the owner id of these objects don’t match the owner id of the currently executing user, SQL Server generated a permission exception.
The fix is pretty easy, I just needed to change the ownership of these objects back to the SA user:
ALTER AUTHORIZATION ON DATABASE [MYDATABASE] TO [SA]
Running SSBDiagnose with the CONFIGURATION option generated happier results:
C:\Program Files\Microsoft SQL Server\100\Tools\Binn>ssbdiagnose.exe -d FulfillmentMessaging CONFIGURATION FROM SERVICE FulfillerService_Initiator_Mock TO SERVICE Fulfiller Service_Target_Mock ON CONTRACT FulfillerContract ENCRYPTION OFF
Microsoft SQL Server 10.0.2531.0
Service Broker Diagnostic Utility
0 Errors, 0 Warnings
With my permissions errors resolved, my SSBS services were working once again.
Friday, October 08, 2010
Many of the examples of databinding use datasource or objectsource controls. I prefer to databind from the code-behind. I feel I have finer control over how to data is prepared before I load it.
The downside to doing this “late binding” of the data, and I can’t use the strongly typed names in my declarative markup. The following code fails because the compiler can’t resolve the “Products” reference.
Code Snippet
- <asp:DataList ID="DataList1" runat="server" RepeatColumns="1" DataSource='<%#Products%>'>
instead, you must use the Eval() method of the Databinder to resolve the references. The following works fine for any type of binding (late or early):
Code Snippet
- <asp:DataList ID="DataList1" runat="server" RepeatColumns="1" DataSource='<%#DataBinder.Eval(Container.DataItem,"Products")%>'>
Happy Coding!
Tuesday, September 28, 2010
Code Snippet
- ThreadPoolHelper.QueueUserWorkItem(arg1, arg2, arg3,
- (localArg1, localArg2, localArg3) =>
- {
- /* code block */
- });
Monday, September 27, 2010
I’m posting this because I never seem to be able to recall this value when I need it. Under Windows 7:
Environment.SpecialFolders.Programs resolves to: C:\Users\[username]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
Saturday, September 25, 2010
I recently attempted to install a windows service I had created. I created an installer and deployed the msi to the target machine. When I ran the setup I was prompted for the username and password credentials for the identity to run the service.
I had a local account created. The account was permissioned correctly and had been granted the rights to logon as a service. After supply the credentials, the I received the following error:
Error 1001. The account name is invalid or does not exist, or the password is invalid for the account name specified.
After some research, I discovered that you’ve got to include the machine name when specifying the username. So rather than just a username of “ServiceAccountUser”, I needed to specify “MyServer\ServiceAccountUser”.
The shorthand form of “.\ServiceAccountUser” also works.
Hope this helps.
Sunday, September 19, 2010
After I renamed the page and namespace for my aspx page, I started getting a compilation error:
“The name 'GridView1' does not exist in the current context”. This was odd since the aspx codebehind and inherits attributes were in sync with the aspx.cs and aspx.designer.cs files. So what was wrong?
During my rename operation, Visual Studio (or possibly ReSharper) excluded the designer file from my project. I hadn’t noticed because I usually work with the “Show All Files” option enabled in my solution explorer.
The Fix: Simple. Add the excluded designer files back into Visual Studio and Compile.
All Better!
Saturday, September 18, 2010
This has nothing to do with .Net development, but I’m sure others are running into this problem, so I thought I’d write a quick post about it.
After updating my Windows PC to Adobe Flash Player 10.1, whenever I attempt to view YouTube videos (either through IE or Chrome), I get a green background and no video, some audio, and then my browser locks up.
Turns out to be an issue with Adobe’s hardware acceleration feature (new to version 10). To disable hardware acceleration, you need to modify a setting in the flash player itself, by right-clicking the video, selecting settings and then uncheck “Use Hardware acceleration”.
I COULD NOT DO ON YOUTUBE WITHOUT IT LOCKING UP MY BROWSER.
Here’s my solution,
- Visit the FlashPlayer Test page at: http://www.adobe.com/software/flash/about/.
- Install the flash player if you have not already done so.
- When the flash video plays, right click on the video, select Settings from the context menu and uncheck the “Use Hardware Acceleration” option. The settings seem to “stick” between sessions, so you should be all set.
- Browse to Youtube and click on a video.
- Enjoy!
Thursday, September 16, 2010
I've got a solution to running and debugging unit tests for WCF hosted services that utilize the CMServiceHost. Whether your generate your serivce proxy via WSDL (Add Service Reference) or Shared Contract (ClientFactory), the solution is similar. This email will detail how to invoke a WCF Service Host for testing in both scenarios.
Testing a service client generated via "Add Service Reference"
I'll illustrate the solution using the following sample unit test. Let's assume you've created a service proxy for the "TestService" service with Add Service Reference, and assigned it to the "TestSvc" namespace. You're test looks like this:
1: [TestMethod]
2: public void Test_InvokeTestService()
3: {
4: var client = new TestSvc.TestServiceClient();
5: var pingResp = client.Ping();
6: TestContext.WriteLine("Ping Response: {0}", pingResp);
7: }
Let's assume this service is hosted by our ChannelDelivery.Host project and the above test lives int he ChannelDelivery.Test project.
1. Start by getting latest of the _ReferencedAssemblies in the dev branch of TFS.
2. In your Test Project, add a reference to the Platform.UnitTests_Utilities assembly (its available in the _ReferencedAssemblies\Framework folder in the Applications solutions).
3. Decorate your unit test with the AspNetDevelopmentServer attribute. This attribute takes two arguments; a unique host idenfiter, and the location of the web site to run. Assuming You're running this for the ChannelDelivery unit tests, you'd specify the arguments as follows: [AspNetDevelopmentServer("ChannelDeliveryHost", @"ChannelDelivery\ChannelDelivery.Host")]
4. In your unit test code, after your create your service proxy, and before you invoke the service operation, add a call to
client.Endpoint.Address= WebTestHelper.GetRedirectedEndpointAddress("ChannelDeliveryHost", TestContext, client.Endpoint.Address);
Your code should now resemble:
[TestMethod]
[AspNetDevelopmentServer("ChannelDeliveryHost", @ "ChannelDelivery\ChannelDelivery.Host")]
public void Test_InvokeTestService()
{
var client = new TestSvc.TestServiceClient();
client.Endpoint.Address= WebTestHelper.GetRedirectedEndpointAddress("ChannelDeliveryHost", TestContext, client.Endpoint.Address);
var pingResp = client.Ping();
TestContext.WriteLine("Ping Response: {0}", pingResp);
}
Testing a service client that shares service contract and uses ClientFactory.
I'll illustrate the solution using the following sample unit test. Let's assume you've created a service proxy for the "EchoService" service using the ClientFactory. You're test looks like this:
[TestMethod]
public void Test_ChannelDeliveryEcho()
{
using (var svc = ClientFactory.ProduceServiceClient<IEchoService>())
{
TestContext.WriteLine("Echo Test Results:" + svc.Client.Echo("Echo!"));
}
}
To enable integration testing of the EchoService:
1. Start by getting latest of the _ReferencedAssemblies in the dev branch of TFS.
2. Decorate your unit test with the AspNetDevelopmentServer attribute. This attribute takes two arguments; a unique host identifier, and the location of the web site to run. Assuming You're running this for the ChannelDelivery unit tests, you'd specify the arguments as follows: [AspNetDevelopmentServer("ChannelDeliveryHost", @"ChannelDelivery\ChannelDelivery.Host")]
3. In your unit test code, after your create your service proxy, and before you invoke the service operation, call the RedirectServiceUri method on the service proxy, passing a reference to the TestContext.
Your code should now resemble:
[TestMethod]
[AspNetDevelopmentServer("ChannelDeliveryHost",@"ChannelDelivery\ChannelDelivery.Host")]
public void Test_ChannelDeliveryEcho()
{
using (var svc = ClientFactory.ProduceServiceClient<IEchoService>())
{
svc.RedirectServiceUri(TestContext);
TestContext.WriteLine("Echo Test Results:" + svc.Client.Echo("Echo!"));
}
}
Summary
When you debug or run this unit test, the AspNetDevelopmentServer (the one that runs when you press f5 on your web site), starts up and runs on a random port. The WebTestHelper and RedirectServiceURI methods, uses the currently executing test context to determine the random port assignment, and determines the new service address based on the random port and current service uri. The methods also ensure the new uri is valid by attempting to send a POST request to the uri.
You can now run your integration unit tests that rely on hosted wcf services.
The code for GetRedirectedEndpointAddress (aka GetRedirectedUriString) follows:
Code Snippet
-
- public static string GetRedirectedUriString(object TestContext, string defaultUriStr)
- {
- return GetRedirectedUriString(TestContext, defaultUriStr, null);
- }
-
- public static string GetRedirectedUriString(object TestContext, string DefaultUriStr, string HostIdentifier)
- {
- Uri hostUri = getHostUriFromTestContext(TestContext, HostIdentifier);
- if (hostUri == null) return DefaultUriStr;
- var defaultUri = new Uri(DefaultUriStr);
- string newUriStr = hostUri.Scheme + "://" + hostUri.Authority + defaultUri.PathAndQuery;
- newUriStr = EnsureValidUri(new Uri(newUriStr));
- return newUriStr;
- }
-
- private static Uri getHostUriFromTestContext(object context, string identifier)
- {
- const string DevServerKeyName = "AspNetDevelopmentServer.";
- const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
- PropertyInfo info = context.GetType().GetProperty("Properties", bindingFlags);
- if (info != null)
- {
- var contextProperties = info.GetValue(context, null) as Dictionary<string, object>;
- if (contextProperties != null)
- {
- if (string.IsNullOrEmpty(identifier))
- {
- var entry = contextProperties.FirstOrDefault(kvp => kvp.Key.StartsWith(DevServerKeyName));
- return entry.Value as Uri;
- }
- var uri = contextProperties[DevServerKeyName + identifier] as Uri;
- return uri;
- }
- }
- return null;
- }
-
- private static string EnsureValidUri(Uri targetUri )
- {
- var uri = targetUri.ToString();
- for (int i = 0; i < targetUri.Segments.Length; i++ )
- {
- var response = WebTools.DoHttpPost(uri, null);
- if (response.Contains("404"))
- {
- while (targetUri.Segments[i] == "/")
- i++;
- if (i <= targetUri.Segments.Length)
- uri = uri.Replace(targetUri.Segments[i] , "");
- }
- else
- return uri;
- }
- return targetUri.ToString();
-
- }
- public static void WriteMessageToTestContext(object TestContext, string message)
- {
- var mi = TestContext.GetType().GetMethod("WriteLine");
- if (mi != null)
- {
- var parameters = new object[] {message, new object[] {}};
- mi.Invoke(TestContext, parameters);
- }
- }
Here’s a recent post I made to the MSDN Forums and the reply which quickly fixed my problem. I’m posting it here, because I didn’t find it anywhere else on the web.
I'm in the process of migrating projects from one solution to another.
I've created the new solution, and copied the project files from their current disk location (a subdir of the old solution's folder) to their new disk location (a subdir under the new solution's folder).
I then tried to add the application to TFS. The application was added, as well as any solution items, but the projects were not. When I view the projects under the "Change Source Control" dialog in visual studio, the binding shows as "Invalid" I've tried to unbind and rebind the projects, but they remain "invalid" and VS/TFS refuses to put them under source control
How can I add these migrated projects to their new location in TFS. When the migration is complete, I'll prune the projects out of the old solution, and remove them from TFS.
And the response from MFST
You can try following steps
1 Unbind the project in "Change Source Control" dialog
2 Right the project and click Add the Project to source Control in solution explorer
Worked like a charm!
Thanks MFST!