views:

2867

answers:

3

In Visual Web Developer Express 2008 the SubSonic ASP.NET MVC template doesn't seem to work with a new database I added. I removed the Chinook Database and created my own one. I understand the the .tt files in the Models folder are used to generate code, but they don't (despite changing the ConnectionStringName to what I set in the web.config)

Right clicking on each .tt file and selecting 'Run Custom Tool' does not generate anything, except an error message:

Cannot find custom tool 'TextTemplatingFileGenerator' on this system.

Where is that tool kept? There are .tt files in CodeTemplates, which are used when you create a new controller or view, so I assume there is a tool that does this.

+4  A: 

It turns out, and I didn't know this, that T4 templates only run on VS Standard or better :(. I had thought that it was, at one time, available with the VS SDK - perhaps you could find it in there :(

Rob Conery
+2  A: 

There is a command line TextTransform tool which you can use:

[http://msdn.microsoft.com/en-us/library/bb126461.aspx][1]

By default in the Express versions it's installed to C:\Program Files\Common Files\Microsoft Shared\TextTemplating\1.2

However the MVC templates require the t4 templates be run within Visual Studio so I'm pretty sure without at least a patch to the templates you're not going to be able to get them to work.

Adam
Visual Studio 2008 Express Editions not supported though (according to the system requirements)
Sam
Yes and the installer stops you from proceeding without Standard or above. However I just downloaded and installed express and it added the TextTransform command line tool to the following path:C:\Program Files\Common Files\Microsoft Shared\TextTemplating\1.2So hopefully you should be able to do without the SDK.
Adam
Get an error when running on Classes.tt:_SQLServer.tt(1,4) : warning : Multiple template directives were found in the template. All but the first one will be ignored. Multiple parameters to the template directive should be specified within one template directive.
Sam
_Settings.tt(1,4) : warning : Multiple template directives were found in the template. All but the first one will be ignored. Multiple parameters to the template directive should be specified within one template directive.Context.tt(0,0) : error : Running transformation: System.InvalidCastException: Unable to cast object of type 'Microsoft.VisualStudio.TextTemplating.CommandLine.CommandLineHost' to type 'System.IServiceProvider'.
Sam
OK now I give up, unfortunately the template is expecting to run inside Visual Studio and casting Host to IServiceProvider to find paths (the Web.config and the App_Data directory). You could probably work around this by making changes to how the template does that but it seems likely there'll be other problems. Sorry I can't be more help.
Adam
+9  A: 

Following along with Adam's comment, YOU CAN do this in VS Express, but there are changes required to the template as Adam suggested.

The Visual Studio requirement is only used to get the path to the active project, which is then used to find a web.config file and the app_data path. Since those values are generally known within a project, we can hardcode substitutes values

Update the _Settings.tt file like so:

...
const string ConnectionStringName="Chinook";
//Use this when not building inside visual studio standard or higher
//make sure to include the trailing backslash!
const string ProjectPathDefault="c:\\path\\to\\project\\";

...

public EnvDTE.Project GetCurrentProject()  {

        if (Host is IServiceProvider)
        {
            IServiceProvider hostServiceProvider = (IServiceProvider)Host;
            if (hostServiceProvider == null)
                throw new Exception("Host property returned unexpected value (null)");

            EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
            if (dte == null)
                throw new Exception("Unable to retrieve EnvDTE.DTE");

            Array activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
            if (activeSolutionProjects == null)
                throw new Exception("DTE.ActiveSolutionProjects returned null");

            EnvDTE.Project dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
            if (dteProject == null)
                throw new Exception("DTE.ActiveSolutionProjects[0] returned null");

            return dteProject;
         }
         return null;
}

...

public string GetConfigPath(){
        EnvDTE.Project project = GetCurrentProject();
        if (project != null)
        {
            foreach(EnvDTE.ProjectItem item in project.ProjectItems)
            {
             // if it is the configuration, then open it up
             if(string.Compare(item.Name, "Web.config", true) == 0)
             {
              System.IO.FileInfo info =
                new System.IO.FileInfo(project.FullName);
                return info.Directory.FullName + "\\" + item.Name;
             }
            }
            return "";
        }
        else
        {
            return ProjectPathDefault+"web.config";
        }
    }

    public string GetDataDirectory(){
        EnvDTE.Project project=GetCurrentProject();
        if (project != null)
        {
            return System.IO.Path.GetDirectoryName(project.FileName)+"\\App_Data\\";
        }
        else
        {
            return ProjectPathDefault+"App_Data\\";
        }
    }
...

Then use the VS External Tools feature to set up a T4 tool (Tools->External Tools): Set these properties:

  • Title: T4
  • Command: C:\Program Files\Common Files\Microsoft Shared\TextTemplating\1.2\TextTransform.exe
  • Arguments: $(ProjectDir)\Models\Classes.tt
  • Initial directory: $(ProjectDir)
  • Use Output window and Prompt for arguments should be checked.

Click Ok and then execute the newly created tool from the Tools->External Tools menu.

ranomore
Hey ranomore,I tried your solution but I recieve everytime the Message Settings.tt(1,4) : warning : Multiple template directives were found in the template. All but the first one will be ignored. Multiple parameters to the template directive should be specified within one template directive. Have you any Idea? I took a look into Settings.tt file, there is only one template directive.Thanks in advance
john84
I know a good programmer fixes all warning messages, but in this case it's safe to make an exception.What you're seeing is that some file which is included in the outer file also has a template directive. T4 only processes the first template directive that it finds.
ranomore
I just spotted that you picked this up and got it working, great work.
Adam
The warning is very annoying, does using SubSonic mean having to live with this warning for the rest of my project's lifetime?
romkyns
You could try removing the template directive from the Settings.ttinclude file. I think that's the one causing grief.
ranomore