API Explorer UI and IgnoreDataMember attribute

This is using the latest 6.03 in MyGet.

If I decorate a property in a model with System.Runtime.Serialization.IgnoreDataMember, the API Explorer UI correctly hides that property from the UI.

However, if I create a DTO class inheriting from another DTO and in the inherited DTO decorate a property in a model with System.Runtime.Serialization.IgnoreDataMember, the API Explorer / UI does NOT hide that property from the UI.

Example:

namespace SSTest.ServiceModel.Bills
{
    public class Bill
    {
        virtual public string BillID { get; set; }
        virtual public string BillNo { get; set; }
        virtual public string Description { get; set; }
    }
}        

namespace SSTest.ServiceModel.Requests
{ 
    public class BillPOSTRequest : SSTest.ServiceModel.Bills.Bill, IReturn<SSTest.ServiceModel.Bills.Bill>
    {
        // Override the BillID in the DTO and decorate with IgnoreDataMember so it does not appear in Swagger or API Explorer or API UI forms
        // Because the ID is generated automatically, we don't want consumers providing this
        [System.Runtime.Serialization.IgnoreDataMember]
        public override string BillID { get; set; }
    }
}    

I think the API Explorer should be hiding this property. We’ve been depending on this to shape how our Swagger UI presents and are wanting to replace Swagger UI with API Explorer.

1 Like

There’s not really a clean way to model this in hierarchal metadata since it’s always included in the base type and only hidden in the sub type where no property will be defined, which is the current behavior.

It’s only able to work in Swagger UI since there’s no inheritance and the properties are flattened, so it can ignore the property on each type’s flatted property list that wants to ignore it.

To support this behavior I’ve added an Ignore property on [Input] and [Field] which you can use to omit the properties in Auto UI Forms with:

public class BillPOSTRequest : Bill, IReturn<Bill>
{
    [IgnoreDataMember, Input(Ignore=true)]
    public override string BillID { get; set; }
}

Or using [Field]:

[Field(nameof(BillID), Ignore = true)]
public class BillPOSTRequest : Bill, IReturn<Bill> {}

This change is available from the latest v6.0.3 that’s now available on MyGet.

Clearing nuget caches and trying with 6.03 from MyGet and the 2nd method works, but the first method does not work - field is still visible.

We can live with using the 2nd way.

Thanks

Ahh didn’t test it with [IgnoreDataMember], which excludes the property from consideration.

Can use without it, e.g:

public class BillPOSTRequest : Bill, IReturn<Bill>
{
    [Input(Ignore=true)]
    public override string BillID { get; set; }
}

I’ve found this works also:

[Field(nameof(BillID), Ignore = true)]
public class BillPOSTRequest : Bill, IReturn<Bill>
{
    [IgnoreDataMember]
    public override string BillID { get; set; }
}

Which is great, because this makes the existing Swagger UI behave as it did, and the Auto UI forms have the same fields hidden. We just need to add the decorations to the classes making use of the new Ignore Field Attribute.

We want to guide our customers onto the new Auto UI forms, but we don’t want to change existing behaviours - and this fits that need.

Thanks again.

2 Likes

Yep because [Field] does the property hoisting into the sub type, great this works for you.

This has stopped working somewhere along the way. Now when showing the Auto UI form nothing appears.

At the time of my last post, it was working with the 6.03 in MyGet, but no longer does - and persists in 6.1.0 in Nuget and also 6.1.1 in MyGet.

Inspecting the console the problem is seen below:

If I remove the attribute from the BillPOSTRequest to Ignore the RecID field, it behaves as expected - but obviously does not hide the field from the Auto UI form.

This should be resolved from the latest v6.1.1 that’s now available on MyGet.

Yes - can confirm this is fixed in the latest 6.1.1 in MyGet.

Thanks!

1 Like