在base类中有一个虚拟方法,其输入签名是
params object?[]? id
。我想通过将路线模板读入prams参数来覆盖(或隐藏)此方法
当路由模板中有多个主键时。
我可以在派生类中引入重载并调用基方法,但是
基本方法在 API 中仍然可见。这是不可取的,因为当
模型具有 复合主键 通过 API 调用基本方法会引发异常。
下面是架构的简化示例
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Example.Controller;
public class Model { } // Has any number of keys
[ApiController]
[Route("api/[controller]")]
public class Base<TEntity> : ControllerBase where TEntity : class
{
protected DbContext Context;
[HttpGet("{id}")]
public virtual object? Method(params object?[]? id) =>
Context.Set<TEntity>().Find(id);
}
public class Derived : Base<Model>
{
// Overriding does not work because the signature doesn't match
// 'Derived.Get(int, int)': no suitable method found to override
[HttpGet("{a}/{b}")]
public override object? Method(int a, int b) => base.Method(a, b);
// Overloading in the derived class, passing parameters as arguments
// to the base method works as expected
[HttpGet("{a}/{b}/{c}")]
public object? Method(int a, int b, int c) => base.Method(a, b, c);
}
问题
"{a}/{b}/{c}"
读入基本方法参数 id
?HttpGet
方法具有可变数量的参数?您可以研究使用所谓的 slug 参数:
星号
或双星号*
:**
- 可以用作路由参数的前缀来绑定到 URI 的其余部分。
- 称为包罗万象的参数。例如,
: 匹配以blog/{**slug}
开头且其后具有任何值的任何 URI。blog/
后面的值被分配给 slug 路径值。blog/
因此,您可以将 id 视为 slug 参数,并按
/
分割该值,尽管它会将所有内容视为 string
并且不会验证是否传递了正确数量的参数,您需要手动执行此操作。
也许可以通过自定义模型绑定来实现某些目标,但就我个人而言,我不会首先引入此类,或者尝试通过继承来重用它以用于复合 PK 案例(所以不要继承
Base<TEntity>
或引入另一层继承是基础继承仅包含受保护的辅助方法)。我认为DRY原则不应该与KISS相冲突,并且过度概括导致过度复杂化并不是一件好事。
了解更多: