在 .NET Web API POST/PUT 方法中使用继承的类

2023-11-26

我不知道如何在 Web API 控制器中使用继承的类。我have to create only oneAPI 控制器用于创建和更新数据库中继承的对象。

与我的模型类似(所有这些模型都存在 Dto):

public class Animal
{
    public virtual string Name {get; set;} // e.g. Harry
    public virtual string Type {get; set;} // e.g. Dog
}

public class AnimalDto
{
    public string Name;
    public Type Type;
}

public class Dog : Animal
{
    public virtual bool CanBark {get; set;} // e.g. true
}

public class Cat : Animal
{
    public virtual bool CanMiau {get; set;}
}

我已经尝试在控制器中使用 json 。但总是有 jsonnull

[HttpPost]
public ActionResult Post([FromBody]JObject json)
{
    // idk what's going here?!
}

现在是我的控制器,但这会切断狗或猫模型的所有属性

[HttpPost]
public ActionResult Post([FromBody]AnimalDto animal)
{
    // idk what's going here?!
}

我正在使用 .NET Core 2.0

有任何想法吗?谢谢!

EDIT

如果我想动态地执行此操作怎么办?就像是:

var animal = json.ToObject<Animal>();
var actualAnimal = json.ToObject<typeof(animal.Type)>();

我怎样才能做到这一点?


我已经尝试在控制器中使用 json 。但是 json 总是 null

你总是得到的原因null是你没有声明正确Type。你不应该收到string动物类型通过[FromBody].



    [HttpPost]
    public ActionResult Post([FromBody]string json)
    public ActionResult Post([FromBody]Dog dog)
    {
        // now you get the dog
    }
  

附带说明一下,如果您根本不关心类型,一种方法是声明一个dynamic type:

[HttpPost]
public IActionResult Post([FromBody] dynamic json)
{
    return new JsonResult(json); 
}

在这种情况下,动态类型是JObject,您可以根据需要将它们转换为任何类型:

public IActionResult Post(/*[ModelBinder(typeof(AnimalModelBinder))]*/[FromBody] JObject json)
{
    var animal=json.ToObject<Animal>();
    var dog = json.ToObject<Dog>();
    return new JsonResult(json); 
}

现在是我的控制器,但这会切断狗或猫模型的所有属性

如果您想使用AnimalDto,您应该使属性可访问:



    public class AnimalDto
    {
        public string Name;
        public string Name{get;set;}
        public string Type;
        public string Type{get;set;}
    }
  

[Edit]

如果我想动态地执行此操作怎么办?就像是:

var animal = json.ToObject<Animal>();
var actualAnimal = json.ToObject<typeof(animal.Type)>();

如果我们想将 json 转换为某种特定类型,我们首先必须知道目标是什么Type是 。但你的animal.Type财产是一种类型String,这可能是一个约定的字符串。如果这Typeproperty 正是没有命名空间的类名,例如

  • Cat.Type必须等于Cat
  • Dog.Type必须等于Dog
  • Fish.Type必须等于Fish

那么你可以使用Type.GetType()解析目标类型。例如 :

// typename : the Animal.Type property
// ns : the namespace string 
private Type ResolveAnimalType(string typename,string ns){
    if(string.IsNullOrEmpty(ns)){ ns = "App.Models";}
    typename= $"{ns}.{typename}";
    var type=Type.GetType(
        typename,
        assemblyResolver:null,  // if you would like load from other assembly, custom this resovler
        typeResolver: (a,t,ignore)=> a == null ? 
            Type.GetType(t, false, ignore) : 
            a.GetType(t, false, ignore),
        throwOnError:true,
        ignoreCase:false
    );
    return type;
}

Anyway, 您可以自定义我们解决目标的方式Type根据您自己的需求。进而将 json 对象转换为你想要的Type按方法ToObject<T>():

[HttpPost]
public IActionResult Post([FromBody] JObject json)
{
    var typename = json.Value<string>("type");
    if(String.IsNullOrEmpty(typename)) 
        ModelState.AddModelError("json","any animal must provide a `type` property");
    
    // resolve the target type
    var t= ResolveAnimalType(typename,null);

    // get the method of `.ToObject<T>()`
    MethodInfo mi= typeof(JObject)
        .GetMethods(BindingFlags.Public|BindingFlags.Instance)
        .Where(m=> m.Name=="ToObject" && m.GetParameters().Length==0 && m.IsGenericMethod  )
        .FirstOrDefault()
        ?.MakeGenericMethod(t); // ToObject<UnknownAnimialType>()

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

在 .NET Web API POST/PUT 方法中使用继承的类 的相关文章

  • 如何获取正在访问 ASP.NET 应用程序的当前用户?

    为了获取系统中当前登录的用户 我使用以下代码 string opl System Security Principal WindowsIdentity GetCurrent Name ToString 我正在开发一个 ASP NET 应用程
  • 编译时运算符

    有人可以列出 C 中可用的所有编译时运算符吗 C 中有两个运算符 无论操作数如何 它们的结果始终可以在编译时确定 它们是sizeof 1 and 2 当然 其他运算符的许多特殊用途可以在编译时解决 例如标准中列出的那些整数常量表达式 1 与
  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 为什么两个不同的 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
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 复选框检查事件监听器

    最近我一直在使用 Chrome 插件 API 我希望开发一个插件 这将使我管理网站的生活变得更轻松 现在我想做的是在选中某个复选框时触发一个事件 由于这个网站不属于我 我无法更改代码 因此我使用 Chrome API 主要问题之一是没有 I
  • 从 python 数据帧的列构造二分图

    我有一个包含三列的数据框 data subdomain data domain data IP 我想为子域的每个元素构建一个二分图 对应同一个域 权重为它出现的次数 对应 例如我的数据可能是 subdomain domain IP test
  • TransferRequestHandler 和 BeginRequest 的性能问题

    我已经开始使用 New Relic 来监控性能http alternativeto net那是一个相当大的网站 我注意到的是 他们报告为 TransferRequestHandler 的方法花费了大量时间 当我深入研究它时 我发现实际上是
  • 二元炸弹 - 第 4 阶段

    我很难追踪以下二进制炸弹的汇编代码 学校的一项作业 其中必须拆除炸弹 该炸弹包含 6 个阶段 所有阶段都有 1 个正确的输入才能进入下一阶段 我目前处于 Phase 4 它有一个名为 func4 的递归函数 我已经确定输入是 d d 它是两
  • 如何将文件传递到阻塞上游作业的下游作业?

    我想要完成的是签出代码develop分支 将其合并到master分支 建立app war 运行测试 如果测试成功则推送到master branch 测试应该在需要的单独作业中运行app war 我当前的设置如下 Job Main结帐自dev
  • 如何多次运行 php 单元并连接覆盖率报告?

    我测试的代码充满了最终静态类 虽然我们无法重构它以进行更好的测试 但我有一个中间解决方案 可以在其自己的进程上运行几个小测试 一切正常 但我没有收到覆盖报告 因为其中一个覆盖了另一个 我目前正在 clover 中生成报告 但我对其他报告非常
  • 如何列出接口类型中的方法名称?

    例如 type FooService interface Foo1 x int int Foo2 x string string 我想做的是获取列表 Foo1 Foo2 使用运行时反射 尝试这个 t reflect TypeOf FooSe
  • Flutter 切换到 Tab 重新加载 Widget 并运行 FutureBuilder

    问题 我有 2 个使用默认选项卡控制器的选项卡 如下所示 Widget build BuildContext context return DefaultTabController length 2 child Scaffold drawe
  • 根据一列的值更新另一列的值

    我有一个名为 Vendor 的表 在该表中我有一个名为 AccountTerms 的列 它仅显示一个值 即 0 1 2 3 等 我还有一个我想使用的专栏 ulARAgeing 以反映该值的含义 例如 0 Current 1 30 Days
  • 错误:使用 SQLDF 没有此类列

    下面是脚本 gt library sqldf gt turnover read csv turnover csv gt names turnover 1 Report Date PersID Status DOB 5 Age Tenure
  • 如何用seaborn拟合泊松分布?

    我尝试将数据拟合为泊松分布 import seaborn as sns import scipy stats as stats sns distplot x kde False fit stats poisson 但我收到这个错误 Attr
  • 如何更新应用程序?

    互联网上似乎没有太多用于更新 Android 应用程序的资源 那么 我需要做的就是更改应用程序的 build gradle 文件中的版本号和名称吗 versionCode 2 versionName 1 0 1 这就是全部 现在我只需要制作
  • 即使一项检查失败如何继续执行

    我正在尝试访问不同的网址并使用 matchImageSnapshot 将屏幕截图与基线图像进行比较 这里的问题是当我的一个 url 因 matchimagesnapshot 失败时 它不会继续到下一个 URL 注意 我尝试使用变量 env
  • 获取插入后生成的id

    我正在 Android 上使用 SQLite 我想知道获取我插入的行的生成 id 的最佳方法 我认为解决方案在包含后进行搜索 但它看起来不是最好的方法 The insert方法返回id刚刚插入的行或 1如果插入过程中出现错误 long id
  • 滚动到带有标题的 Xamarin Forms ListView 的开头

    我在 Xamarin Forms 中滚动到 ListView 顶部时遇到一些问题 我可以通过调用 ScrollTo 并传递第一项来滚动到第一项 问题是 当列表有标题项时 我找不到滚动到标题的方法 这可能吗 我能想到的唯一解决方法是不使用标头
  • “new new Something”如何在 JavaScript 中产生有效的结果?

    我目前正在开发一个 JavaScript 解析器并研究ECMAScript 5 1 规范 这是目前令我困惑的一个问题 11 2 左侧表达式定义以下内容NewExpression生产 NewExpression MemberExpressio
  • 密码散列的盐也应该被“散列”吗?

    我认为这可能是一个愚蠢的问题 但我已经很困惑我应该在这里做什么才能最好 对密码哈希进行加盐处理时 盐是否也应该进行哈希处理还是保留为明文 注意 我正在对 SHA 256 中的密码进行哈希处理 并且 Salt 是预定义的字符串 因为一次只会存
  • 并发文件写入

    如何写入可由多个源 可能以并发方式 访问的文本文件 确保不会丢失写入操作 例如 如果两个不同的进程在同一时刻写入文件 这可能会导致问题 简单的解决方案 不是很快也不是很优雅 是在开始进程时锁定文件 创建 lock 文件或类似文件 并在写入完
  • 如何优化在 date 的 where 子句中包含 to_char 的 Oracle 查询

    我有一张表 其中包含49403459记录 我想查询某个日期范围内的表 说04 10 2010 to 04 10 2010 但是 日期以格式存储在表中10 APR 10 10 15 06 000000 AM 时间戳 结果当我这样做时 SELE
  • 在 .NET Web API POST/PUT 方法中使用继承的类

    我不知道如何在 Web API 控制器中使用继承的类 我have to create only oneAPI 控制器用于创建和更新数据库中继承的对象 与我的模型类似 所有这些模型都存在 Dto public class Animal pub