Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: C# Service Code Generator Produces Controller Base Class with Incorrect Interface Implementation #5427

Open
4 tasks done
mario-guerra opened this issue Dec 22, 2024 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@mario-guerra
Copy link
Member

Describe the bug

Description:

The C# service code generator produces a controller base class that declares it implements an interface, but the base class itself does not directly implement the methods defined in that interface. Instead, it relies on a nested class to implement the interface methods. This creates a mismatch between the declared interface implementation and the actual implementation, leading to build errors.

Steps to Reproduce:

  1. Use the OpenAPI code generator to generate a C# ASP.NET Core project with a controller that implements an interface.
  2. Observe that the generated controller base class declares that it implements the interface but does not directly implement the interface methods.
  3. Observe that the generated base class defines an abstract nested class and an abstract property of that type.
  4. Attempt to build the project.
  5. Observe the compiler error CS0535: '...' does not implement interface member '...'.

Expected Behavior:

The generated base controller class should either:

  1. Directly Implement the Interface: The base class should directly implement the methods defined in the interface.
  2. Not Declare Interface Implementation: The base class should not declare that it implements the interface. Instead, the nested class should implement the interface, and the concrete controller should implement the abstract property.

Actual Behavior:

The generated base controller class declares that it implements the interface but does not directly implement the interface methods. Instead, it relies on a nested class to implement the interface methods.

Reproduction

I'm working on a 'Todo' app that's pretty large, and I can share the tsp file I used to generate, here's an example of a generated interface and controller base files for context:

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// <auto-generated />

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Getitdone.Service.Models;

namespace Getitdone.Service.Operations
{

    public interface ICommentOpsOperations
    {
        Task<Comment> GetCommentAsync(string commentId);
        Task<Comment> UpdateCommentAsync(string commentId, UpdateCommentRequest body);
        Task DeleteCommentAsync(string commentId);

    }
}

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// <auto-generated />

using System;
using System.Net;
using System.Threading.Tasks;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
using Getitdone.Service.Models;
using Getitdone.Service;

namespace Getitdone.Service.Controllers
{
    [ApiController]
    public abstract partial class CommentsOperationsControllerBase : ControllerBase
    {

        internal abstract ICommentsOperations CommentsOperationsImpl { get; }


        [HttpGet]
        [Route("/comments")]
        [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(Comment[]))]
        public virtual async Task<IActionResult> GetComments([FromQuery(Name = "task_id")] string taskId, [FromQuery(Name = "project_id")] string projectId)
        {
            var result = await CommentsOperationsImpl.GetCommentsAsync(taskId, projectId);
            return Ok(result);
        }


        [HttpPost]
        [Route("/comments")]
        [ProducesResponseType((int)HttpStatusCode.Created, Type = typeof(Comment))]
        public virtual async Task<IActionResult> CreateComment(CreateCommentRequest body)
        {
            var result = await CommentsOperationsImpl.CreateCommentAsync(body);
            return Ok(result);
        }

    }
}

Checklist

@mario-guerra mario-guerra added the bug Something isn't working label Dec 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants