首页 > 解决方案 > API:根据枚举值返回视图模型/响应

问题描述

我正在使用枚举的 API 端点,我需要根据枚举值返回不同的响应(具有不同属性的类)。我确信泛型可以在这里帮助我,但我不知道如何或在哪里。

多个入口点调用调用逻辑函数的通用方法(我有 16 种不同的类型):

public class ApiController : BaseController
{
    public async Task<IActionResult> GetType1(FilterEnum filter)
    {
        return await this.PrepareResponseForFilterAndType(filter, TypeEnum.Type1);
    }

    public async Task<IActionResult> GetType2(FilterEnum filter)
    {
        return await this.PrepareResponseForFilterAndType(filter, TypeEnum.Type2);
    }

    public async Task<IActionResult> GetType16(FilterEnum filter)
    {
        return await this.PrepareResponseForFilterAndType(filter, TypeEnum.Type16);
    }

    private async Task<IActionResult> PrepareResponseForFilterAndType(FilterEnum filter, TypeEnum type)
    {
        // Call to logic, with return type of IEnumerable<IResponse>
        var response = await Logic.DoBusiness(this.UnitOfWork, filter, type);

        //// Do stuff before return

        return this.Json(response);
    }
}

在逻辑上,我应用过滤器(FilterEnum 和 TypeEnum)来获取请求的数据,必要时更新数据等等。

然后,我必须根据 TypeEnum 返回不同的响应:大多数响应共享共同值,但不是全部,并且许多响应具有特定值。

我的问题在这里:代码工作,它并不完美,但它工作。尽管如此,它还是有味道的。

我想改变界面和开关允许我做的更好和更清洁的事情。

正如您将看到的接口和实现它的类一样,接口中的所有属性也必须在每个 Type1Response、Type2Response、...、Type16Response 类中。这意味着,如果此“TypeX”的某些接口属性不存在,它们仍将在响应中以对该类型没有意义的空值出现。

public class Logic
{
    public async Task<IEnumerable<IResponse>> DoBusiness(UnitOfWork unitOfWork, FilterEnum filter, TypeEnum type)
    {
        //// Apply filter and return a collection of the relevant type from the db
        var filteredElements = unitOfWork.ElementRepository.ListForFilterAndType(filter, type);

        IEnumerable<IResponse> response = null;

        switch (type)
        {
            case TypeEnum.Type1:
                response = Mapper.Map<IEnumerable<Type1Response>>(filteredElements);
                break;
            case TypeEnum.Type2:
                response = Mapper.Map<IEnumerable<Type2Response>>(filteredElements);
                break;
            case TypeEnum.Type16:
                response = Mapper.Map<IEnumerable<Type16Response>>(filteredElements);
                break;
        }
    }
}

以及接口和 TypeXResponses

public interface IResponse
{
    int Id { get; set; } // Mostly in all types but not everywhere

    string Name { get; set; }

    string Type { get; set; }

    string Images { get; set; } // Needed for some types to format multiple urls
}

public class Type1Response : IResponse
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Type { get; set; }

    public string Images { get; set; } // No images for this type but will be present in the response cause of interface

    public int Free { get; set; }

    public int Capacity { get; set; }
}

public class Type2Response : IResponse
{
    public int Id { get; set; } // No id nor name for this type but I must have them here cause of the interface

    public string Name { get; set; } // No id nor name for this type but I must have them here cause of the interface

    public string Type { get; set; }

    public string Description { get; set; }

    public string Images { get; set; }
}

public class Type16Response : IResponse
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Type { get; set; }

    public string Description { get; set; }

    public string Images { get; set; }
}

因此,我正在寻找一种更简洁的方法来实现这一点,效果更好(没有不必要的空值),除了 TypeXResponse 之外,无需重复 16 次相同的代码。

提前致谢。

标签: c#enumsreturn-type

解决方案


推荐阅读