在 .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 方法中使用继承的类 的相关文章

随机推荐

  • 复选框检查事件监听器

    最近我一直在使用 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