Is there a way to effectively make [ModelMetadataType] work across multiple assemblies?

259 views Asked by At

I have an ASP.NET Core 3.1 web API application that has various models used for by its endpoints for input and output of data. Because other C# applications will be communicating with this one, I decided to move these shared models to a NuGet package that all the applications can use.

As is usual, these models' properties are decorated with various data annotation attributes, such as [Required], in order to allow for the standard model validation to prevent invalid input. They are also decorated with specific ASP.NET MVC Core attributes, such as [FromQuery], in order to allow them to be correctly bound to incoming requests.

However, I don't want the ASP.NET MVC Core attributes to appear in the shared NuGet package. Firstly because they are only relevant to the web API, so it makes sense to apply them there; secondly because including them in the NuGet will pull in various ASP.NET Core-related dependencies that again, are not relevant to other consumers of this package.

ASP.NET Core has the [ModelMetadataType] attribute that covers this - but only when the models in question reside in the same assembly. Is there a built-in or simple way to make [ModelMetadataType] work across different assemblies, without subclassing and/or redeclaring the models?

(I am fully aware that allowing such would create a security risk by allowing downstream consumers to potentially alter the behaviour of upstream models, but since these models and this package and the applications in question are all internal to the company I work for, it isn't a problem in this case.)

Code samples illustrating the basic concept:

// NuGet package - model declaration
public class MyModel
{
    [Required]
    public int MyProperty { get; set; }
}

...

// ASP.NET Core web API - enrich model with additional metadata
public class MyModelMetadata
{
    [FromQuery(Name = "foo")]
    public int MyProperty { get; set; }
}

...

// ASP.NET Core web API - desired effective (composite) model
public class MyModel
{
    [Required]
    [FromQuery(Name = "foo")]
    public int MyProperty { get; set; }
}
0

There are 0 answers