简体   繁体   中英

Is there anyway to generate Razor views (.cshtml) based on a template beside T4?

I'm developing some code generator for generating models, controllers and views based on databases tables so I could make a Asp.Net MVC3 website. I can generate models and controllers with CodeDOM now but for generating views I need something to make the templates , like generating a .cshtml from a .cs , I thought T4 would be good idea but some of my colleagues insist on not using T4, is there any other ways? thanks

I am not sure why they would be against using T4 as a lot of the code libraries out there including Entity Framework use them. It sounds like you are doing something I just finished doing. I liked using Pre-Processed T4 templates so I am able to feed data into them from C# code and generate the files that way. This allows you to have multiple files output and basically parameters to pass data in with.

The way I use it is.. I made a class that was used to gather all the information about the databases.. which tables to include or exclude.. and then information about each column like pk or identity nullable and such. I plugged my preprocessed t4 templates in with that information was was able to generate all the SQL, views, models, controller info.. and whenever the database changed.. i just run my console app and bam its all regenerated.

Preprocessed: http://odetocode.com/Blogs/scott/archive/2011/01/03/preprocessed-t4-templates.aspx

Entity Framework: http://msdn.microsoft.com/en-us/data/gg558520.aspx

MVCScaffolding: http://blog.stevensanderson.com/2011/04/06/mvcscaffolding-overriding-the-t4-templates/

T4MVC: http://mvccontrib.codeplex.com/wikipage?title=T4MVC

Again i know this doesn't help answer your question but T4 is AMAZING and I would be interested to hear the arguement on why not to use T4.. its even built in!

btw here gets some intellisense!: http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html

If yo have any questions please feel free to hit me up I love T4 and i'd be willing to answer any questions I can.

Here is an example of a template I use to generate my POCO models.. a lot has been extracted thanks to the pre-processed abilities of using my normal c# methods to pass data in. This template creates 55 models for me based off of the tables in a database.

My "SchemeCollector" uses a DatabaseInfo, TableInfo, and ColumnInfo class that I created to hold all the schema I need. Then I have 9 other t4 templates that also use the SchemaCollector class to populate the data.

Here is the extension I use to pass the data into the template for generation. I have this all setup to use XML files for configuration also but it is unnecessary I just wanted it to be really reusable.

public partial class PocoGenerator
    {
        public string Namespace { get; set; }
        public string Inherit { get; set; }
        public DatabaseInfo Schema { get; set; }
        public bool Contract { get; set; }
        public string SavePath { get; set; }
    }

Here is the method I use to call and populate the template and save it.

static void GeneratePoco(Config config)
        {
            var template = config.Poco;
            template.Schema = config.DatabaseInfo;

            File.WriteAllText(template.SavePath, template.TransformText());

            Console.WriteLine("      - POCOs generated for " + config.DatabaseInfo.DatabaseName + " complete");
        }

Here is the template

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Windows.Forms.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ assembly name="System.Xml.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="CodeGenerator.Utilities" #>

using System;
using System.Runtime.Serialization;

namespace My.Models
{   <#  
        List<TableInfo> tables = Schema.Tables; 
    #>

    //#########################################################################################################
    //   This file has been generated from the tables contained in the <#= Schema.DatabaseName #> database.
    //   Changes to this file will be overwritten when the file is regenerated. Generated: <#= DateTime.Now #>
    //#########################################################################################################
    <#
    foreach (TableInfo table in tables)
    {
    #>

    [DataContract]
    public class <#= table.Name #> : IConfigTable
    {

        <#
        PushIndent("        "); 
            foreach (ColumnInfo col in table.Columns)
            {
                if(col.IsKey || col.IsIdentity)
                    WriteLine("[Key]");

                WriteLine("[DataMember]");
                if(col.IsNullable && col.Type != "string")
                    WriteLine("public " + col.Type + "? " + col.Name+ " { get; set; }");
                else
                    WriteLine("public " + col.Type + " " + col.Name+ " { get; set; }");
            }PopIndent();#>     
    }
    <# } #>
}

We used code smith extensively and also wrote a plugin. With t4 though ou could simply generate the classes and then remove the template - why the opposition there to T4?

Certainly, I use Razor for all my code generation (and email generation, etc.) by using the nice extension RazorGenerator . It allows you to specify this extension as a "custom tool" and generates a resultant C# class off of your .cshtml input that you can invoke (and pass in a @model ) to transform text into whatever output you like. (somewhat ironically in your case, it would be razor => razor conversions)

We have similar task, we are crating dynamic web forms that are based on input json file with form definition. Editor specify different controls that should be presented on a form (controls contain different properties, actions, validators). Below i will try to describe basic procedure of a our logic:

  1. Deserilize and validate json file.
  2. Prepare data that will be passed to the T4 template.
  3. Generate MVC models and controller from the data (step 2).
  4. Generate additional classes (eg some helpers, complex types from a model).
  5. Add to assembly embeded resources such a dataSources etc, images whatever.
  6. Compile all stuff above.
  7. Drop dll in models folder.
  8. Restart site.

All properties in the model has their [UIHint] attributes with names of a partial views. We have around 10 partial views that knows how to represent each property. To support this logic we extend ViewEngine and ModelMetadata provider.

ViewEngine looks for views in additional folder. ModelMetada provider adds to "AdditionalValues" custom properties.

Our view for a model have one row

@Html.EditorForModel()

We had overrided Object.cshtml to handle 'deep binding'. The most difficult parts was with a collections where collection items were of a complex type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM