C# 有没有办法强制WebAPI严格遵守已发布的接口?

C# 有没有办法强制WebAPI严格遵守已发布的接口?,c#,asp.net-web-api,asp.net-web-api-routing,C#,Asp.net Web Api,Asp.net Web Api Routing,我试图解决的用例是我们领域模型的封装。例如,我们有在后端处理中使用的内部模型,我们不希望将其公开给客户端。这种封装的主要原因之一是变化的波动性,因为我们的域对象可能比“已发布”的客户机模型变化得更快。因此,我们希望限制WebApi控制器只返回“已发布”的客户机模型 为此,我们需要在WebApi项目之外创建没有内部模型引用的接口,然后利用WebApi控制器上的这些接口,最后更改路由/过滤,以验证正在访问的路由/方法是接口的一部分 大会A 大会B 在上面的示例中,我希望调用/bad/1返回404,因

我试图解决的用例是我们领域模型的封装。例如,我们有在后端处理中使用的内部模型,我们不希望将其公开给客户端。这种封装的主要原因之一是变化的波动性,因为我们的域对象可能比“已发布”的客户机模型变化得更快。因此,我们希望限制WebApi控制器只返回“已发布”的客户机模型

为此,我们需要在WebApi项目之外创建没有内部模型引用的接口,然后利用WebApi控制器上的这些接口,最后更改路由/过滤,以验证正在访问的路由/方法是接口的一部分

大会A 大会B 在上面的示例中,我希望调用
/bad/1
返回404,因为这是一条未发布的路由


有什么想法吗?

您可以创建一个动作过滤器,检查映射的动作是否是控制器继承接口的成员


您还可以创建一个筛选器,当手动将其归因于您不希望公开的方法时,该筛选器将返回404 Not Found响应。

创建程序集C,它处理与DomainModel的所有交互以及PublishedModels的构造。在程序集B中,删除对DomainModel程序集的引用

  • 现在没有人可以在使用或返回DomainModel对象的程序集B中编写代码
  • 此外,没有人可以在程序集C中编写公开DomainModel对象的方法,因为程序集B在尝试使用程序集C时也会出现编译错误

您现在只需要监控项目引用,这很容易通过可视化或构建检查来完成。

您可以限制WebAPI中类中显示的内容。仅显示您希望“发布”的字段。您可以创建一个操作筛选器,用于检查被调用的操作是否是控制器继承接口的成员。您还可以创建一个过滤器,当将其归因于您不希望公开的方法时,它将返回404@ElenaDBA你能详细说明一下如何“限制显示内容”吗?您是否正在考虑为属性添加一些属性?谢谢@Nkosi过滤器是我对如何实现这一目标的最佳猜测谢谢你验证我的想法!:)我认为你应该加上这个回答,这样我们就可以投票了。为什么
坏的
会存在呢?有内部电话吗?我喜欢布兰登的回答。它强制执行接口隔离。“不应强制客户机实现其不使用的接口,也不应强制客户机依赖其不使用的方法”()
public class PublishedModel
{
    public int Foo {get; set;}
    public string Bar {get; set;}
}

public interface IPublishedAPI
{
    PublishedModel GetModel(int id);
}
public class MyApi : ApiController, IPublishedAPI
{
    public IDomainManager _manager;

    public MyApi(IDomainManager manager)
    {
        _manager = manager;
    }

    [HttpGet]
    [Route("good/{id}")]
    public PublishedModel Good(int id)
    {
          DomainModel domainModel = _manager.GetDomainModelById(id);
          return new PublishedModel
          {
              Foo = domainModel.Foo,
              Bar = domainModel.Bar,
          }
    }

    [HttpGet]
    [Route("bad/{id}")]
    public DomainModel Bad(int id)
    {
          var domainModel = _manager.GetDomainModelById(id);
          return domainModel;
    }
}