简体   繁体   中英

C# string Formatting based on Model Attribute Annotation

I'm working on a ".dat" file creation project, where the requirement is to generate a file with the necessary padding "zeros" or "spaces" for all the string values.

For example: I have a Class as below and the requirement is while generating a File using this model, file content should be 7 characters in length and anything below that should be replaced with "0" character .

public class Header
{
     // String length of 7, append "0" for leftover spaces.
     public string RECORD_TYPE { get;set;};
}

By considering the requirement above, if I set a Value to this Field as "ABC" (ie 3 characters in length) then it should be converted as "ABC0000" while generating a File to fulfill the 7 characters requirement .

To achieve this, I created a Custom Attribute as below:

public interface IFormatterAttribute
{
    string Format(string toFormat);
}

[AttributeUsage(AttributeTargets.All)]
public class PaddedLengthAttribute : Attribute, IFormatterAttribute
{
    private readonly int _length;
    private readonly char _paddingChar;
    private readonly PaddingDirection _paddingDirection;

    public PaddedLengthAttribute(int length, char paddingChar = '0', PaddingDirection direction = PaddingDirection.Right)
    {
        _length = length;
        _paddingChar = paddingChar;
        _paddingDirection = direction;
    }

    public string Format(string toFormat)
    {
        return _paddingDirection switch
        {
            PaddingDirection.Left => toFormat.PadLeft(_length, _paddingChar),
            PaddingDirection.Right => toFormat.PadRight(_length, _paddingChar),
            _ => toFormat.PadRight(_length, _paddingChar),
        };
    }

    public enum PaddingDirection
    {
        Left,
        Right
    }
}

So that, I can decorate Field using this custom attribute below:

[PaddedLengthAttribute(7,'0')]
public class Header
{
     // String length of 7, append "0" for leftover spaces.
     public string RECORD_TYPE { get;set;};
}

I need help here to understand the better approach of calling Format method of PaddedLengthAttribute class dynamically for each attribute it assigned to.

You can use Reflection to iterate through the properties of your Header class and retrieve their attributes, and if the property has a PaddedLengthAttribute, you can use it to format the property value.

Here's an example:

public static class AttributeHelper
{
    public static void ApplyPaddingAttributes(Header header)
    {
        var headerType = header.GetType();
        var properties = headerType.GetProperties();
        foreach (var property in properties)
        {
            var attributes = property.GetCustomAttributes(typeof(PaddedLengthAttribute), false);
            if (attributes.Length > 0)
            {
                var value = (string)property.GetValue(header);
                var attribute = (PaddedLengthAttribute)attributes[0];
                property.SetValue(header, attribute.Format(value));
            }
        }
    }
}

And you can use it like this:

var header = new Header() { RECORD_TYPE = "ABC" };
AttributeHelper.ApplyPaddingAttributes(header);

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