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.
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;
});