views:

639

answers:

2

When I try to create a Microsoft.TeamFoundation.Client.TeamFoundationServer object in the HomeController of my MVC application, I receive the following error:

TF30076: The server name {TfsServerName} provided does not correspond to a server URI that can be found. Confirm that the server name is correct.

I am using Windows Authentication for the MVC app, so the Controller.User property is populated as my domain login {domain\username}.

When I debugged using the Visual Studio Development Server, the code worked fine. After I began using a virtual directory in IIS, the execution of the code began returning the aforementioned error.

I am using Visual Studio / TFS 2008 (v9.0), Windows XP environment, and ASP.NET MVC 1.0.

Exception:

Microsoft.TeamFoundation.TeamFoundationInvalidServerNameException: TF30076: The server name {xxxx} provided does not correspond to a server URI that can be found. Confirm that the server name is correct. at Microsoft.TeamFoundation.Client.TeamFoundationServer.GetUriForName(String name) at Microsoft.TeamFoundation.Client.TeamFoundationServer.get_Uri() at Microsoft.TeamFoundation.Client.CheckAuthenticationProxy..ctor(TeamFoundationServer server) at Microsoft.TeamFoundation.Client.TeamFoundationServer.Authenticate(Boolean useProvider, ICredentialsProvider provider) at Microsoft.TeamFoundation.Client.TeamFoundationServer.Authenticate() at Portal.TfsHelper.AuthenticateTfsServer() in D:\Portal\Portal\Models\TfsHelper.cs:line 99

Code throwing the exception is shown below:

try
{
    // authenticate before using tfs server
    //TfsServer is created using the following: TfsServer = new TeamFoundationServer("server-name");
    if (!TfsServer.HasAuthenticated)
    {
        TfsServer.Authenticate();
        _hasAuthenticated = true;
    }
}
catch (Exception ex)
{
#warning: temporary error handling for TFS authentication
    String exString = ex.ToString();
    throw new Exception(ex.Message, ex.InnerException);
}

Any thoughts on why this is happening?

Exception appearing after calling "RegisteredServers.AddServer("server-name", "http://server-name:8080");":

System.Security.SecurityException: Requested registry access is not allowed. at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource) at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable) at Microsoft.TeamFoundation.Client.RegisteredServers.OpenCurrentUser(Boolean writable, Boolean shouldCreate) at Microsoft.TeamFoundation.Client.RegisteredServers.AddServer(String serverFriendlyName, String serverUrl) at Portal.Controllers.HomeController..ctor() in D:\Portal\Portal\Controllers\HomeController.cs:line 42 The Zone of the assembly that failed was: MyComputer

A: 

Most likely, the server name {TfsServerName} provided does not correspond to a server URI that can be found. You should confirm that the server name is correct.

Come on, do you think it's lying to you? That it found the server but decided you don't deserve to use it? Most likely, you're not passing it the server name you think you are. Stop in the debugger and make sure it's the same string you get when you test in the Development Server.

Also, did you receive an error, or was it an exception? If it was an exception, then please catch the exception, then post the entire exception by posting the result of ex.ToString().

John Saunders
I verified that the server name is the same in both scenarios. Also added exception to my original question.
mjw.
This looks fairly straightforward. I bet that Microsoft.TeamFoundation.Client.TeamFoundationServer is an ASMX proxy class for the web service, in which case get_Uri is fetching the Uri property, and finding that it's not valid.
John Saunders
Thanks. I'm a newb in some areas, including TFS. Can you be more specific about your thoughts as to cause and resolution of this issue?
mjw.
Take advantage of the fact that this always happens. Set a breakpoint at TfsHelper.cs:line 99, and look at the properties of the TeamFoundationServer object.
John Saunders
Right, I've gone that far already: That code is simply calling the Authenticate() method on a TeamFoundationServer object which hasn't been correctly created, due to the exception. The properties all display the 'Microsoft.TeamFoundation.TeamFoundationInvalidServerNameException' instead of displaying values.
mjw.
Ok, time I do more to help. I'll do some research (I've never used the API). Can you please show the code that initializes the TeamFoundationServer instance and calls Authenticate?
John Saunders
I have added the code to my original question.
mjw.
I see. Call http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.client.registeredservers.getservernames.aspx right before Authenticate, and look at the list of servers.
John Saunders
I called the RegisteredServers.GetServerNames() method, which returned an empty string[]... no names returned. I know that the value of System.Web.HttpContext.User.Identity.Name is my correct "domain\username" string, but do you think permissions/ASP.NET service are somehow involved with this?
mjw.
No. Read the link I posted to GetServerNames and RegisteredServers. Recall what happens in Visual Studio when you start using a new server. You have to register it. I think you have to register your server in the context of IIS.
John Saunders
Does that mean calling the RegisteredServer.AddServer() method, then? I tried this, and received a Permission exception (added to original question)
mjw.
I saw some articles that mentioned giving the asp.net account permissions in the registry. I tried this (even tried giving "Everyone" full control of the keys) to no avail. The registry path (paths?) that seem to be in question are: [HKCU] (or [HKLM]?) "Software\\Microsoft\\VisualStudio\\9.0\\TeamFoundation\\Servers"
mjw.
You may want to edit that by hand (carefully) just to test. Maybe copy the corresponding keys from your HKCU. This may be like the issue with event log sources - new source requires registry write, ASP.NET does not have the privs. Answer: create little installer class to do the work and run installutil.exe against the DLL as part of web app deployment. Same here - you need privs to write the registry - don't do that in the app, but in the installer.
John Saunders
Yep, I tried copying the keys from HKCU to HKLM when I was adjusting the permissions, etc. None of that seemed to work. It seems kind of pointless if I have to run installutil.exe just to debug a project in a virtual directory. I still can't figure out why it runs when in the Visual Studio Development Server but not when in a virtual directory in IIS...
mjw.
Because in the dev server case, it's running as you - and you've already got this server registered.
John Saunders
So the windows authentication with impersonate set to true still will not "run as me" in the virtual directory? Did I understand that correctly?
mjw.
That's right. It's not the same as an interactive login. Impersonation will have given ASP.NET your rights and privileges, but not your interactive profile.
John Saunders
A: 

Some attempts at psychic debugging:

  • Are you passing a friendly name or a real, valid URI? If a friendly name, have you used Visual Studio or regedit or similar to initialize the URI mapping? (HKLM\Software\Microsoft\VisualStudio\xxx\TeamFoundation\Servers)
  • Is ASP running in a network context which requires a different URI to reach TFS (e.g. netbios name vs fully qualified domain name, different port...)
  • Are the proxy settings the same on the two machines? Firewall?
  • What credentials are you passing thru to the TeamFoundationServer constructor?
    • If none (as the sample code shows), what domain account is your App Pool running under?
    • Is the thread where you construct TeamFoundationServer running in an impersonated context? Have you verified impersonation is working the way you expect?
Richard Berg
- I have added servers at HKLM\Software\Microsoft\VisualStudio\xxx\TeamFoundation\Servers- ASP is running under the ASPNET process- not sure about proxy settings on TFS server machine- Not passing any credentials. BTW: is there a way to create credentials? The methods I was looking at all seem to want ICredentials as parameters but I can't find a way to instantiate an object that implements that interface...
mjw.
You don't need to modify the registry (and I wouldn't suggest it, unless you do it from inside VS -- too much room for error). Just give it a real, honest-to-god URI. I.e. instead of "myserver" give it "http://myserver:8080" or "https://server.domain.company.com:443" or whatever. ///// "The ASP.Net process" means nothing -- App Pools run under a specific Windows user account (or LocalSystem or NetworkService). ///// The easiest way to create credentials is to construct one of these classes: http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx
Richard Berg
I ended up setting the identity of the App Pool to run under a specific user account which allows the TFS processes to run under that user context. This solved the problem of not being able to connect to the TFS server object via the API. Though both threads on this question addressed certain issues, this answer pointed me toward the best solution.Thanks.
mjw.