{"record":{"id":"624e5cba2142c087","repo":"RicoSuter/NSwag","slug":"type-fullname-does-not-implement-property-prefix","errorCode":null,"errorMessage":"{type.FullName} does not implement property 'Prefix'","messagePattern":"(.+?) does not implement property 'Prefix'","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/NSwag.Generation.WebApi/Infrastructure/RoutePrefixAttributeFacade.cs","lineNumber":29,"sourceCode":"namespace NSwag.Generation.WebApi.Infrastructure\n{\n    /// <summary>\n    /// Uses reflection to provide a common interface to the following types:\n    /// * RoutePrefixAttribute\n    /// * IRoutePrefix\n    /// </summary>\n    internal sealed class RoutePrefixAttributeFacade\n    {\n        private readonly PropertyInfo _prefix;\n\n        public RoutePrefixAttributeFacade(Attribute attr)\n        {\n            var type = attr.GetType();\n\n            _prefix = type.GetRuntimeProperty(\"Prefix\");\n            if (_prefix == null)\n            {\n                throw new ArgumentException($\"{type.FullName} does not implement property 'Prefix'\");\n            }\n\n            Attribute = attr;\n        }\n\n        public Attribute Attribute { get; }\n\n        public string Prefix => (string)_prefix.GetValue(Attribute);\n\n        public static RoutePrefixAttributeFacade TryMake(Attribute a)\n        {\n            var type = a.GetType();\n\n            if (type.Name == \"RoutePrefixAttribute\" ||\n                type.GetTypeInfo().ImplementedInterfaces.Any(i => i.Name == \"IRoutePrefix\"))\n            {\n                return new RoutePrefixAttributeFacade(a);\n            }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/RicoSuter/NSwag/blob/63daf8fcc3a25151b62eb4b326a1e8ea048a0d41/src/NSwag.Generation.WebApi/Infrastructure/RoutePrefixAttributeFacade.cs#L11-L47","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npublic class ApiPrefixAttribute : Attribute { public string Value { get; } }\n\n// after\npublic class ApiPrefixAttribute : Attribute { public string Prefix { get; } public ApiPrefixAttribute(string prefix) { Prefix = prefix; } }","handlingStrategy":"validation","validationCode":"// Verify custom route-prefix attributes expose 'Prefix'\nvar ok = typeof(ApiPrefixAttribute).GetRuntimeProperty(\"Prefix\") != null;\nif (!ok) throw new InvalidOperationException(\"Custom RoutePrefix attribute must expose public 'Prefix' property\");","typeGuard":"function hasPrefixProperty(attr) {\n  return attr != null && typeof attr.Prefix === \"string\"; // C#: attr.GetType().GetRuntimeProperty(\"Prefix\") != null\n}","tryCatchPattern":"try { document = generator.Generate(settings); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"does not implement property 'Prefix'\"))\n{\n    logger.LogError(ex, \"Custom route prefix attribute lacks 'Prefix' property\");\n}","preventionTips":["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."],"tags":["reflection","webapi","route-prefix","nswag"],"backgroundTag":"missing-required-argument","analyzedSha":"63daf8fcc3a25151b62eb4b326a1e8ea048a0d41","analyzedAt":"2026-09-14T11:38:15.205Z","contentChangedAt":"2026-09-14T11:38:15.205Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}