{"action":"created","issue":{"url":"https://api.github.com/repos/RSuter/NSwag/issues/1584","repository_url":"https://api.github.com/repos/RSuter/NSwag","labels_url":"https://api.github.com/repos/RSuter/NSwag/issues/1584/labels{/name}","comments_url":"https://api.github.com/repos/RSuter/NSwag/issues/1584/comments","events_url":"https://api.github.com/repos/RSuter/NSwag/issues/1584/events","html_url":"https://github.com/RSuter/NSwag/issues/1584","id":357957166,"node_id":"MDU6SXNzdWUzNTc5NTcxNjY=","number":1584,"title":"FileResponse instead of normal type","user":{"login":"dyesdyes","id":1426272,"node_id":"MDQ6VXNlcjE0MjYyNzI=","avatar_url":"https://avatars1.githubusercontent.com/u/1426272?v=4","gravatar_id":"","url":"https://api.github.com/users/dyesdyes","html_url":"https://github.com/dyesdyes","followers_url":"https://api.github.com/users/dyesdyes/followers","following_url":"https://api.github.com/users/dyesdyes/following{/other_user}","gists_url":"https://api.github.com/users/dyesdyes/gists{/gist_id}","starred_url":"https://api.github.com/users/dyesdyes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dyesdyes/subscriptions","organizations_url":"https://api.github.com/users/dyesdyes/orgs","repos_url":"https://api.github.com/users/dyesdyes/repos","events_url":"https://api.github.com/users/dyesdyes/events{/privacy}","received_events_url":"https://api.github.com/users/dyesdyes/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":11,"created_at":"2018-09-07T07:48:39Z","updated_at":"2018-09-07T09:49:27Z","closed_at":null,"author_association":"NONE","body":"Hi,\r\n\r\nI would like to have advice on how to solve this, I understood that FileResponse is the default value if it can't automatically deduce the right type.\r\n\r\nEvery single end point returns a FileResponse. All my controller method return ApiResult<ActualReturnedType>.\r\n\r\nI wrap the responses myself like so:\r\n\r\n```\r\npublic class ApiResult<T> : OkObjectResult\r\n    {\r\n        public ApiResult(T value, int statusCode = StatusCodes.Status200OK) : this(new ApiResponse<T>(),\r\n            statusCode)\r\n        {\r\n        }\r\n\r\n        public ApiResult(ApiError error, int statusCode = StatusCodes.Status400BadRequest) : this(\r\n            new ApiResponse<T>(error), statusCode)\r\n        {\r\n        }\r\n\r\n        public ApiResult(IdentityResult identityResult, int statusCode = StatusCodes.Status400BadRequest) : this(\r\n            new ApiResponse<T>(identityResult.Errors.Select(e => new ApiError(e.Code, e.Description)).ToArray()), statusCode)\r\n        {\r\n        }\r\n\r\n        public ApiResult(ModelStateDictionary modelState, int statusCode = StatusCodes.Status400BadRequest) : this(\r\n            new ApiResponse<T>(modelState.Select(f => new FieldError(f.Key, \"validation_error\", string.Join(\", \", f.Value.Errors.Select(e => e.ErrorMessage)))).ToArray()), statusCode)\r\n        {\r\n        }\r\n\r\n        public ApiResult(ApiResponse<T> value, int statusCode) : base(value)\r\n        {\r\n            StatusCode = statusCode;\r\n        }\r\n\r\n        public override void OnFormatting(ActionContext context)\r\n        {\r\n            base.OnFormatting(context);\r\n            context.HttpContext.Response.Headers.Add(\"X-API-RESPONSE\", \"true\");\r\n        }\r\n\r\n        public ApiResponse<T> ApiResponse => (ApiResponse<T>)base.Value;\r\n    }\r\n```\r\n\r\nAnd Api response looks like:\r\n```\r\npublic class ApiResponse<T> : IApiResponse<T>, IApiResponse\r\n    {\r\n        private string _errorMessage;\r\n\r\n        [JsonConstructor]\r\n        public ApiResponse()\r\n        {\r\n        }\r\n\r\n        public ApiResponse(T result)\r\n        {\r\n            Result = result;\r\n        }\r\n\r\n        public ApiResponse(params ApiError[] errors)\r\n        {\r\n            if (errors == null) return;\r\n            foreach (var error in errors)\r\n            {\r\n                AddError(error);\r\n            }\r\n        }\r\n\r\n        [JsonIgnore]\r\n        public string ErrorMessage\r\n        {\r\n            get\r\n            {\r\n                if (_errorMessage == null && Errors != null)\r\n                {\r\n                    _errorMessage = string.Join(\" \", Errors.Select(e => e.Description));\r\n                }\r\n                return _errorMessage;\r\n            }\r\n        }\r\n\r\n        [JsonProperty(NullValueHandling = NullValueHandling.Include)]\r\n        public IList<ApiError> Errors { get; set; } = new List<ApiError>();\r\n\r\n        [JsonProperty(NullValueHandling = NullValueHandling.Include)]\r\n        public T Result { get; set; }\r\n\r\n        public void AddError(ApiError error)\r\n        {\r\n            Errors.Add(error);\r\n        }\r\n    }\r\n```\r\nExample of a controller method:\r\n\r\n```\r\n[HttpGet]\r\n        [SwaggerResponse(200, typeof(Task<ApiResult<List<ExampleDto>>>))]\r\n        [SwaggerResponse(403, typeof(Task<ApiResult<List<ExampleDto>>>))]\r\n        public async Task<ApiResult<List<ExampleDto>>> Get([FromQuery] Guid companyChallengeId)\r\n        {\r\n            // logic \r\n            return Ok(variable);\r\n        }\r\n```"},"comment":{"url":"https://api.github.com/repos/RSuter/NSwag/issues/comments/419386563","html_url":"https://github.com/RSuter/NSwag/issues/1584#issuecomment-419386563","issue_url":"https://api.github.com/repos/RSuter/NSwag/issues/1584","id":419386563,"node_id":"MDEyOklzc3VlQ29tbWVudDQxOTM4NjU2Mw==","user":{"login":"RSuter","id":2603405,"node_id":"MDQ6VXNlcjI2MDM0MDU=","avatar_url":"https://avatars1.githubusercontent.com/u/2603405?v=4","gravatar_id":"","url":"https://api.github.com/users/RSuter","html_url":"https://github.com/RSuter","followers_url":"https://api.github.com/users/RSuter/followers","following_url":"https://api.github.com/users/RSuter/following{/other_user}","gists_url":"https://api.github.com/users/RSuter/gists{/gist_id}","starred_url":"https://api.github.com/users/RSuter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RSuter/subscriptions","organizations_url":"https://api.github.com/users/RSuter/orgs","repos_url":"https://api.github.com/users/RSuter/repos","events_url":"https://api.github.com/users/RSuter/events{/privacy}","received_events_url":"https://api.github.com/users/RSuter/received_events","type":"User","site_admin":false},"created_at":"2018-09-07T09:49:27Z","updated_at":"2018-09-07T09:49:27Z","author_association":"OWNER","body":"Ah, now we are getting there. The problem is this here: \r\nhttps://github.com/RSuter/NSwag/blob/master/src/NSwag.SwaggerGeneration/SwaggerJsonSchemaGenerator.cs#L86\r\n\r\nThe correct attributes would be: \r\n\r\n    [SwaggerResponse(200, typeof(ApiResponse<List<ExampleDto>>))]\r\n    [SwaggerResponse(403, typeof(ApiResponse<List<ExampleDto>>))]\r\n\r\nSo the actual reponse type is ApiResponse and not ApiResult, right?\r\n"}}
{"actor":{"display_login":"RSuter"}}