Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Roslyn更改属性_C#_Roslyn_Custom Attributes - Fatal编程技术网

C# 如何使用Roslyn更改属性

C# 如何使用Roslyn更改属性,c#,roslyn,custom-attributes,C#,Roslyn,Custom Attributes,我努力在roslyn库中找到正确的方法来更改属性并重写属性: class Program { static void Main(string[] args) { //this is the original class var str = @"public class OfferModel { public int Id { get; set; } [Required(Erro

我努力在roslyn库中找到正确的方法来更改属性并重写属性:

class Program
{ 
    static void Main(string[] args)
    {

        //this is the original class 
        var str = @"public class OfferModel
        {
            public int Id { get; set; }

            [Required(ErrorMessage = \""Required\"")]
            [Display(Name = \""Date of Offer *\"")]
            public DateTime? OfferDate { get; set; }

            [Required(ErrorMessage = \""Required\"")]
            [Display(Name = \""Amount *\"")]
            [Range(1, double.MaxValue, ErrorMessage = \""Invalid Amount\"")]
            public decimal? Amount { get; set; }
        }";

        var tree = CSharpSyntaxTree.ParseText(str);

        var myWriter = new MyReWriter();
        var newRoot = myWriter.Visit(tree.GetRoot());

        Console.WriteLine(newRoot.ToFullString());

    }
}

public class MyReWriter : CSharpSyntaxRewriter
{
    public MyReWriter() : base() { }

    public override SyntaxNode VisitAttribute(AttributeSyntax node)
    {
        var newNode = node;

        if (node.Name.ToString() == "Required")
        {
            newNode = PrepareNewRequiredArgument(node);
        }

        return base.VisitAttribute(newNode);
    }

    private AttributeSyntax PrepareNewRequiredArgument(AttributeSyntax node)
    {
        var newNode = node;
        //ErrorMessageResourceType
        //ErrorMessageResourceName
        var argResType = node.ArgumentList.Arguments.FirstOrDefault(aa => aa.NameEquals.Name.Identifier.Text == "ErrorMessageResourceType");
        var argResName = node.ArgumentList.Arguments.FirstOrDefault(aa => aa.NameEquals.Name.Identifier.Text == "ErrorMessageResourceName");
        if (argResType != null && argResName != null)
        {
            //already exists, don't do anything
            return newNode;
        }

        var argErrorMessage = node.ArgumentList.Arguments.FirstOrDefault(aa => aa.NameEquals.Name.Identifier.Text == "ErrorMessage");

        if (argErrorMessage != null)
        {
            var name = ParseName("Required");
            var tokenValue = ((LiteralExpressionSyntax)argErrorMessage.Expression).Token.Value;

            var argErrorMessageResourceName = AttributeArgument(
                LiteralExpression(SyntaxKind.StringLiteralExpression,
                    Token(default(SyntaxTriviaList),
                            SyntaxKind.StringLiteralToken, "ErrorMessageResourceName", tokenValue.ToString(), default(SyntaxTriviaList))));

            //var argErrorMessageResourceType = AttributeArgument(
            //   LiteralExpression(SyntaxKind.NumericLiteralExpression, 
            //        Token(default(SyntaxTriviaList),
            //                SyntaxKind.NumericLiteralToken, "ErrorMessageResourceType", "typeof(WebModels)", default(SyntaxTriviaList))));

            var otherList = new SeparatedSyntaxList<AttributeArgumentSyntax>();
            otherList = otherList.AddRange(new[] { argErrorMessageResourceName });
            //otherList = otherList.AddRange(new[] { argErrorMessageResourceName, argErrorMessageResourceType });
            var argumentList = AttributeArgumentList(otherList);
            var newAttribute = Attribute(name, argumentList);

            newNode = node.ReplaceNode(node, newAttribute);
        }
        return newNode;
    }
}
这同样适用于[Display]/[Range]属性。如果我能使[必需]工作,我可以将其应用于[显示]/[范围]

您的最后一行是:

newNode=node.ReplaceNode(node,newAttribute)

看起来您只是试图用不同的实例(newAttribute)替换子树(节点)的根。ReplaceNode无法在根节点上工作。相反,您应该只使用新节点

应该是:


newNode=newAttribute

您当前的代码究竟是如何失败的?如果调试代码,在什么情况下其行为会变得与您期望的不同?上面的代码生成如下属性:[Required(ErrorMessageResourceName)]它应该是:[Required(ErrorMessageResourceType=typeof(WebModels),ErrorMessageResourceName=“Required”)]
public class OfferModel
{
    public int Id { get; set; }

    [Required(ErrorMessageResourceType = typeof(WebModels), ErrorMessageResourceName = \""Required\"")]
    [Display(Name = \""Date of Offer *\"")]
    public DateTime? OfferDate { get; set; }

    [Required(ErrorMessageResourceType = typeof(WebModels), ErrorMessageResourceName = "Required")]
    [Display(ResourceType = typeof(WebModels), Name = "Amount *")]
    [Range(1, double.MaxValue, ErrorMessageResourceName = "InvalidAmount")]
    public decimal? Amount { get; set; }
}