【问题标题】:How might I construct a non-default constructor model from a query string in ASP.Net Core?如何从 ASP.Net Core 中的查询字符串构造非默认构造函数模型?
【发布时间】:2021-01-26 07:36:36
【问题描述】:

我想从 ASP.Net Core 中的查询字符串参数构造一个具有非默认构造函数的对象。本质上,我有两个模型,它们有一个具有不同参数化的共同祖先类.根据 API 端点中的某些条件,将使用查询字符串中的参数构造一个模型。

[HttpGet("{model}")]
public ModelBase Get(string model)
{
  switch (model)
  {
    case "foo":
      ModelFoo foo = GetModelFromQueryString<ModelFoo>();
      return foo;
    case "bar":
      ModelBar bar = GetModelFromQueryString<ModelBar>();
      return bar;
  }
  return null;
}

GetModelFromQueryString&lt;TModel&gt; 显然是我希望我知道存在的神奇功能。如果它已经存在或者有人可以帮助提供实现细节,那将回答我的问题。

示例模型类如下所示:

class ModelFoo : ModelBase
{
  public ModelFoo(int param1=1, int param2=2)
  {
    // ...
  }
}

class ModelBar : ModelBase
{
  public ModelBar(int paramBaz=3)
  {
    // ...
  }
}

理想情况下,这将使以下 HTTP 调用产生所需的结果:

  • GET api/foo?param1=7&amp;param2=9 产生 new ModelFoo(param1:7, param2:9)
  • GET api/bar?paramBaz=42 产生 new ModelBar(paramBaz:42)
  • GET api/foo 产生 new ModelFoo(param1:1, param2:2)
  • GET api/foo?param2=11 产生 new ModelFoo(param1:1, param2:11)

我该怎么办?我应该完全重组吗?

我意识到这可能是一个复杂的多方面问题,因此非常感谢任何和所有帮助!

【问题讨论】:

    标签: asp.net-core model-binding api-design optional-parameters constructor-overloading


    【解决方案1】:

    您可以尝试使用我的工作演示。

    类:

    public class ModelBase
    {
         
    }
    
    class ModelFoo : ModelBase
    {
        public int param1 { get; set; }
        public int param2 { get; set; }
        public ModelFoo(int param1 = 1, int param2 = 2)
        {
            this.param1 = param1;
            this.param2 = param2;
        }
    }
    
    class ModelBar : ModelBase
    {
        public int paramBaz { get; set; }
        public ModelBar(int paramBaz = 3)
        {
            this.paramBaz = paramBaz;
        }
    }
    

    行动:

    [HttpGet("{model}")]
        public ModelBase Get(string model,int param1,int param2,int paramBaz)
        {
            switch (model)
            {
                case "foo":
                    if(param1!=0 ^ param2!=0)
                    {
                        if(param1 != 0)
                        {
                            ModelFoo foo1 = new ModelFoo
                            {
                                param1 = param1,
                            };
                            return foo1;
                        }
                        if (param2 != 0)
                        {
                            ModelFoo foo2 = new ModelFoo
                            {
                                param2 = param2,
                            };
                            return foo2;
                        }
    
                    }
                    if (param1 == 0 && param2 == 0)
                    {
                        ModelFoo foo3 = new ModelFoo();
                       
                        return foo3;
                    }
                    ModelFoo foo4 = new ModelFoo
                    {
                        param1 = param1,
                        param2 = param2,
                    };
                    return foo4;
    
    
                case "bar":
                    if (paramBaz != 0)
                    {
                        ModelBar bar = new ModelBar
                        {
                            paramBaz = paramBaz,
    
                        };
                        return bar;
                    }
                    ModelBar bar1 = new ModelBar();
                    return bar1;
            }
            return null;
        }
    

    【讨论】:

      【解决方案2】:

      不是真正直接回答您的问题,但所需的构建块已经可用。

      如果构造函数参数与属性名称匹配,Newtonsoft JSON.net 支持创建类型,并且如果在 $type 属性中设置具体类型,则还支持创建接口实例:

      public static class Program
      {
          public static async Task<int> Main(string[] args)
          {
              var sourceList = new List<IModel> { new ModelFoo(3, 7), new ModelBar(11) };
              var jsonList = JsonConvert.SerializeObject(sourceList, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
              var list = JsonConvert.DeserializeObject<List<IModel>>(jsonList, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
      
              return 0;
          }
      }
      
      public interface IModel { }
      
      public class ModelFoo : IModel
      {
          public ModelFoo(int first, int second)
          {
              First = first;
              Second = second;
          }
          public int First { get; }
          public int Second { get; }
      }
      
      public class ModelBar : IModel
      {
          public ModelBar(int third)
          {
              Third = third;
          }
      
          public int Third { get; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        • 2014-03-26
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        • 2016-03-24
        相关资源
        最近更新 更多