是否可以在 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 中返回不同的模型? 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr

随机推荐