Still having a little difficulty with DisplayAttribute

Is there any way to have a DisplayAttribute emit AutoGenerateField=false? No matter what I do I cannot get it to have this generated. I have tried setting it to false and not setting it at all. There is only the default constructor. The other attributes are working perfectly. I am now able to set up a ton of my ui on the data service.

Derek

ServiceStack isn’t able to do this generically as it can only emit attribute properties with non-default values.

But you can override how attributes are serialized with a custom handler where you can explicitly add attribute properties for non-default values, e.g:

var feature = GetPlugin<NativeTypesFeature>();
feature.ExportAttribute<DisplayAttribute>(x => {
    var attr = (DisplayAttribute) x;
    var metadata = feature.GetGenerator().ToMetadataAttribute(x);
    if (!attr.AutoGenerateField)
        metadata.Args.Add(new MetadataPropertyType {
            Name = nameof(DisplayAttribute.AutoGenerateField),
            Type = nameof(Boolean),
            Value = "false",
        });
    return metadata;
});

So I implemented the code you supplied and now on updating the Dtos I am getting the following output.

        var nativeTypes = GetPlugin<NativeTypesFeature>();
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(System.ComponentModel.DataAnnotations.DisplayColumnAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(System.ComponentModel.DataAnnotations.DisplayFormatAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(System.ComponentModel.DataAnnotations.DataTypeAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(System.ComponentModel.DataAnnotations.EditableAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(System.ComponentModel.BindableAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(UseInSearchAttribute));
        nativeTypes.MetadataTypesConfig.ExportAttributes.Add(typeof(ViewMetaDataAttribute));
        
        nativeTypes.ExportAttribute<DisplayAttribute>(x =>
        {
            var attr = (DisplayAttribute)x;
            var metadata = nativeTypes.GetGenerator().ToMetadataAttribute(x);
            if (!attr.AutoGenerateField)
                metadata.Args.Add(new MetadataPropertyType { Name = nameof(DisplayAttribute.AutoGenerateField), Type = nameof(Boolean), Value = "false" });
            return metadata;
        });

— Updating ServiceStack Reference ‘Data.Services.dtos.cs’ —
[Failed to update ServiceStack Reference: Unhandled error]
The remote server returned an error: (500) Internal Server Error.:
System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
at ServiceStackVS.NativeTypes.Handlers.BaseNativeTypesHandler.GetUpdatedCode(String baseUrl, Dictionary`2 options)
at ServiceStackVS.ServiceStackVSPackage.UpdateGeneratedDtos(ProjectItem projectItem, INativeTypesHandler typesHandler)

Ok here’s the deal. On reflection of Custom attributes there will be an exception thrown if you try to access a property that has not been initialized as you are doing in the code above.
You get this error:

The AutoGenerateField property has not been set. Use the GetAutoGenerateField method to get the value.

I replaced that with
attr.GetAutoGenerateField() == null || (attr.GetAutoGenerateField().HasValue && !attr.GetAutoGenerateField().Value) because it is a nullable Boolean. This solved my problem

Final code looks like this.

        nativeTypes.ExportAttribute<DisplayAttribute>(x =>
        {
            var metadata = nativeTypes.GetGenerator().ToMetadataAttribute(x);
            try
            {
                var attr = (DisplayAttribute)x;
                if (attr.GetAutoGenerateField() == null || (attr.GetAutoGenerateField().HasValue && !attr.GetAutoGenerateField().Value))
                    metadata.Args.Add(new MetadataPropertyType { Name = nameof(DisplayAttribute.AutoGenerateField), TypeNamespace="System", Type = nameof(Boolean), Value = "false" });
                return metadata;
            }
            catch (Exception ex)
            {

            }
            finally
            {
            }
            return metadata;
        });
1 Like