RicoSuter/NSwag · error · ArgumentException
does not implement property 'Prefix
Error message
{type.FullName} does not implement property 'Prefix' What it means
RoutePrefixAttributeFacade wraps a route-prefix-like attribute and resolves its 'Prefix' property via type.GetRuntimeProperty("Prefix"). If the attribute's runtime type does not expose a public 'Prefix' property, the constructor throws ArgumentException naming the offending type. NSwag throws this when a custom RoutePrefixAttribute substitute does not implement the expected property.
Solutions
- Add a public 'Prefix' string property (with getter) to the custom attribute class.
- Use the framework's standard RoutePrefixAttribute instead of a custom implementation.
- Derive the custom attribute from the official RoutePrefixAttribute so 'Prefix' is inherited.
- Check the full type name in the message to identify which assembly supplies the non-conforming attribute.
Example fix
// before
public class ApiPrefixAttribute : Attribute { public string Value { get; } }
// after
public class ApiPrefixAttribute : Attribute { public string Prefix { get; } public ApiPrefixAttribute(string prefix) { Prefix = prefix; } } Defensive patterns
Strategy: validation
Validate before calling
// Verify custom route-prefix attributes expose 'Prefix'
var ok = typeof(ApiPrefixAttribute).GetRuntimeProperty("Prefix") != null;
if (!ok) throw new InvalidOperationException("Custom RoutePrefix attribute must expose public 'Prefix' property"); Type guard
function hasPrefixProperty(attr) {
return attr != null && typeof attr.Prefix === "string"; // C#: attr.GetType().GetRuntimeProperty("Prefix") != null
} Try / catch
try { document = generator.Generate(settings); }
catch (ArgumentException ex) when (ex.Message.Contains("does not implement property 'Prefix'"))
{
logger.LogError(ex, "Custom route prefix attribute lacks 'Prefix' property");
} Prevention
- Use the official RoutePrefixAttribute instead of hand-rolled copies.
- When porting attributes between frameworks, keep the public property names 'Prefix' and 'Template'.
- Add a reflection-based test asserting required attribute properties exist.
When it happens
Trigger: Supplying a custom [RoutePrefix]-style attribute (or referencing a re-implementation of System.Web.Http.RoutePrefixAttribute in a different package) that lacks a public 'Prefix' property, when the WebApi document generator scans controller attributes and builds the facade.
Common situations: Porting code from ASP.NET (System.Web.Http) to ASP.NET Core or vice versa with a hand-rolled RoutePrefixAttribute that renamed the property; NuGet package swap changing the attribute implementation; typos like 'Prefixe' or a private setter with no public getter being fine but a renamed property not.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- does not implement property 'Template
- This UI does not support multiple documents per UI: Do not…
- The SwaggerUiRoute cannot contain
- The NSwag DI services are not registered: Call…
- The OpenAPI/Swagger document
AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14).
Data as JSON: /api/errors/624e5cba2142c087.
Report an issue: GitHub.
Appendix: source
Thrown at src/NSwag.Generation.WebApi/Infrastructure/RoutePrefixAttributeFacade.cs:29
namespace NSwag.Generation.WebApi.Infrastructure
{
/// <summary>
/// Uses reflection to provide a common interface to the following types:
/// * RoutePrefixAttribute
/// * IRoutePrefix
/// </summary>
internal sealed class RoutePrefixAttributeFacade
{
private readonly PropertyInfo _prefix;
public RoutePrefixAttributeFacade(Attribute attr)
{
var type = attr.GetType();
_prefix = type.GetRuntimeProperty("Prefix");
if (_prefix == null)
{
throw new ArgumentException($"{type.FullName} does not implement property 'Prefix'");
}
Attribute = attr;
}
public Attribute Attribute { get; }
public string Prefix => (string)_prefix.GetValue(Attribute);
public static RoutePrefixAttributeFacade TryMake(Attribute a)
{
var type = a.GetType();
if (type.Name == "RoutePrefixAttribute" ||
type.GetTypeInfo().ImplementedInterfaces.Any(i => i.Name == "IRoutePrefix"))
{
return new RoutePrefixAttributeFacade(a);
}View on GitHub (pinned to 63daf8fcc3)