1

ビューのようなプロパティの T4 テンプレート内で読み取ることができるモデルのカスタム データ注釈を作成できますか? ビューの作成に基づいて、Scaffold などのデータ注釈パラメーターを追加したいと考えています。

ありがとうございました

4

3 に答える 3

4

だから、これはあなたがそれを行う方法です。カスタム属性を作成する方法については、このチュートリアルに従ってくださいhttp://origin1tech.wordpress.com/2011/07/20/mvc-data-annotations-and-custom-attributes/

T4 スキャフォールディング テンプレートでこの属性値を読み取るには、まずhttp://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspxの説明に従ってテンプレート ファイルを追加します。

次に、たとえば、AddView フォルダーから List.tt を開きます。このテンプレートは、Index ビューを作成します。

テンプレート ファイルの末尾に移動し、クラス ModelProperty の定義を見つけます。それにプロパティ値を追加します ( public string MyAttributeValue { get; set; }

List.tt を少し下に移動し、bool Scaffold(PropertyInfo property) メソッドを見つけます。独自の属性プロパティ リーダーを追加する必要があります。上記のチュートリアルの場合、この方法は次のようになります。

string OptionalAttributesValueReader(PropertyInfo property){
    foreach (object attribute in property.GetCustomAttributes(true)) {
        var attr = attribute as OptionalAttributes ;
        if (attr != null) {
                return attr.style;
        }
    }
    return String.Empty;
}

次に、ファイルの下部にあるメソッド List GetEligibleProperties(Type type) を見つけます。次のようにリーダーを追加します。

            ...
            IsForeignKey = IsForeignKey(prop),
            IsReadOnly = prop.GetSetMethod() == null,
            Scaffold = Scaffold(prop),
            MyAttributeValue =  OptionalAttributesValueReader(prop)

この属性を使用して読み取りたい場合は、List.tt で Scaffold プロパティが使用されているように実行できます。

      List<ModelProperty> properties = GetModelProperties(mvcHost.ViewDataType);
      foreach (ModelProperty property in properties) {
          if (property.MyAttributeValue != String.Empty) {
              //read the value
              <#= property.MyAttributeValue #>  
           }
       }

これらのクラスはプロジェクトで定義されているため、プロジェクトの dll と名前空間を List.tt の先頭に追加する必要がありました。

     <#@ assembly name="C:\myProjectPath\bin\myMVCproject.dll" #>
     <#@ import namespace="myMVCproject.CustomAttributes" #>

モデルが変更され、足場でこれらの新しい変更を見つける必要がある場合は、プロジェクトを再構築する必要があります。

解決策を探している人なら誰でもこれが役立つことを願っています。不明な点があれば質問してください。

于 2013-11-03T07:26:47.943 に答える
2

これは私が MVC 5 で行った方法です。これはずっと前に行ったもので、忘れている可能性があります。変更したテンプレートに表示されているものをコピーして貼り付けているだけです。

(たとえば) 作成/編集ビューまたはリスト ビュー テーブルでプロパティの順序を設定する方法が必要でした。そこでOrderAttribute、整数プロパティを持つカスタム属性を作成しましたOrder

T4 テンプレートでこの属性にアクセスするために、ファイルを変更しましたModelMetadataFunctions.cs.include.t4Order一番上に、オブジェクトから属性に設定された値を取得する 1 つのメソッドと、その順序でアイテムPropertyMetadataのリストを単純に並べ替える別のメソッドを追加しました。PropertyMetadata

List<PropertyMetadata> GetOrderedProperties(List<PropertyMetadata> properties, Type modelType) {
    return properties.OrderBy<PropertyMetadata, int>(p => GetPropertyOrder(modelType, p)).ToList();
}

int GetPropertyOrder(Type type, PropertyMetadata property) {
    var info = type.GetProperty(property.PropertyName);
    if (info != null)
    {
        var attr = info.GetCustomAttribute<OrderAttribute>();
        if (attr != null) 
        {
            return attr.Order;
        }
    }
    return int.MaxValue;
}

最後に、たとえば List テンプレートで、GetOrderedPropertiesメソッドを呼び出す部分を追加しました。

var typeName = Assembly.CreateQualifiedName("AcCtc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", ViewDataTypeName);
var modelType = Type.GetType(typeName);

var properties = ModelMetadata.Properties.Where(p => p.Scaffold && !p.IsPrimaryKey && !p.IsForeignKey && !(p.IsAssociation && GetRelatedModelMetadata(p) == null)).ToList();
properties = GetOrderedProperties(properties, modelType);

foreach (var property in properties)
{
//...
}

残念ながら、属性を取得するために必要な Type オブジェクトを作成するには、プロジェクトの名前が必要でした。理想的ではありません。おそらく別の方法で取得できますが、すべてのバージョンのものを含むこの文字列がないと管理できませんでした。

于 2015-05-15T23:05:38.967 に答える