是否可以在 ODataController 中返回不同的模型?

2024-02-09

在 OData v4 控制器中,是否可以返回不同的模型Get()Get([FromIDataUri] key)?

我喜欢使用 ViewModel,当使用Get()我想返回一个方法xxxOverviewViewModel。当使用Get([FromIDataUri] key)方法,我想返回一个 xxxViewModel。

这可能吗?如果可能的话,如何实现?

我尝试过退回不同的型号,但总是得到一个406 Acceptable.

Webapi.config:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();

        config.MapODataServiceRoute("ODataRoute", "odata", GetEdmModel());

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Filter().Expand().Select().OrderBy().MaxTop(null).Count();
    }

    private static IEdmModel GetEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<ComplaintViewModel>("ComplaintOData");
        return builder.GetEdmModel();

    }
}

投诉O数据控制器

public class ComplaintODataController : ODataController
{
    private readonly QueryProcessor _queryProcessor;

    public ComplaintODataController(QueryProcessor queryProcessor)
    {
        _queryProcessor = queryProcessor;
    }

    [EnableQuery]
    public IQueryable<ComplaintOverviewViewModel> Get()
    {
        var result = _queryProcessor.Handle(new GetAllComplaintsQuery());
        return result;
    }

    // WHEN CALLING THIS METHOD I GET A 406: 
    [EnableQuery]
    public ComplaintViewModel Get([FromODataUri] int key)
    {
        var result = _queryProcessor.Handle(new GetComplaintByIdQuery { Id = key });
        return result;
    }
}

EDIT:

My GetAllComplaintsQuery.Handle方法如下所示:

public IQueryable<ComplaintOverviewViewModel> Handle(GetAllComplaintsQuery query)
{
    // .All is an IQueryable<Complaint>
    var result = _unitOfWork.Complaints.All.Select(c => new ComplaintOverviewViewModel
    {
        ComplaintType = c.ComplaintType.Description,
        CreationDate = c.CreationDate,
        Customer = c.Customer,
        Description = c.Description,
        Id = c.Id,
        SequenceNumber = c.SequenceNumber,
        Creator = c.Creator.Name
    });

    return result;
}

这是我的ComplaintConfiguration

public class ComplaintConfiguration : EntityTypeConfiguration<Complaint>
{
    public ComplaintConfiguration()
    {
        Property(p => p.SequenceNumber).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
        Property(p => p.Description).IsRequired();
    }
}

您没有包含您的定义视图模型类,所以让我首先确保我们对于您实际想要实现的目标达成一致。

当客户端请求列表时,您似乎想返回一些受限制的字段集抱怨来自无参数的记录Get()但当客户要求具体投诉时Get([FromODataUri] int key)您想要包含其他字段的方法。

我使用以下层次结构对这个假设进行了建模:

public class ComplaintTypeViewModel
{
    public int Id { get; set; }
}

public class ComplaintOverviewViewModel : ComplaintTypeViewModel
{
    public string Name { get; set; }
}

public class ComplaintViewModel : ComplaintOverviewViewModel
{
    public string Details { get; set; }
}

进行测试,GET /odata/ComplaintOData返回了一个列表Id and Name正如预期的那样,GET /odata/ComplaintOData(1)返回包含以下内容的单个记录Details除了其他两个字段之外,也符合预期。

我从来没有必要改变你的控制器或WebApiConfig.cs除了字符串参数builder.EntitySet<ComplaintTypeViewModel>("ComplaintOData");它必须与控制器匹配(你有"ComplaintTypeOData"在你的代码中)。

既然它有效,我试图弄清楚如何重现你的 406。我已经改变了ComplaintViewModel延长ComplaintTypeViewModel直接而不是扩展ComplaintOverviewViewModel(请注意,我刚刚复制了Name财产):

public class ComplaintTypeViewModel
{
    public int Id { get; set; }
}

public class ComplaintOverviewViewModel : ComplaintTypeViewModel
{
    public string Name { get; set; }
}

public class ComplaintViewModel : ComplaintTypeViewModel
{
    public string Name { get; set; }
    public string Details { get; set; }
}

这也很好用。

我可以重现你的 406 的唯一方法是当我改变ComplaintViewModel to not have ComplaintTypeViewModel在其继承层次结构中:

public class ComplaintTypeViewModel
{
    public int Id { get; set; }
}

public class ComplaintOverviewViewModel : ComplaintTypeViewModel
{
    public string Name { get; set; }
}

public class ComplaintViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Details { get; set; }
}

这最终给了我 406 代码GET /odata/ComplaintOData(1) while GET /odata/ComplaintOData仍在返回列表Id and Name正好。

所以,看起来只要all你的视图模型类扩展相同T from builder.EntitySet<T>("name")您可以从以下位置返回其中任何一个Get()控制器过载。请检查您如何定义您的视图模型

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在 ODataController 中返回不同的模型? 的相关文章

随机推荐