【问题标题】:Web Api 2 - Populating Default Values on Complex Query String ParameterWeb Api 2 - 填充复杂查询字符串参数的默认值
【发布时间】:2016-05-08 20:39:09
【问题描述】:

我正在使用 ASP.Net Web API 2 构建一个 REST API。我有一个 GET 端点,它接受来自查询字符串的复杂对象。

public async Task<IHttpActionResult> GetAsync([FromUri]SpendingAccountSearchParams spendingAccountSearchParams) {...}

搜索对象有很多属性,这些属性要么可以为空,要么在对象的构造函数中填充了默认值。例如:

public SpendingAccountSearchParams()
{
    AsOfDate = DateTime.Now;
    Skip = 0;
    Top = 20;
}

如果我在查询字符串中传递了至少 1 个参数,那么我的 SpendingAccountSearchParams 对象将填充到控制器中,并且所有默认值都设置正确。

但是,如果我不传递任何值,那么我的 SpendingAccountSearchParams 对象在构造函数中为空。

如果没有传递查询字符串参数,如何自动强制所有属性获取默认值?

我想要这个的等价物,但显然它无效并且不起作用:

public async Task<IHttpActionResult> GetAsync([FromUri]SpendingAccountSearchParams? spendingAccountSearchParams = new SpendingAccountSearchParams()) {...}

我知道在控制器中我可以检查 null 并在它不存在时创建一个新对象,但这只是一个端点的示例。最终,我将拥有许多具有不同搜索参数的端点,并且我希望所有端点都自动发生。

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • 你应该使用模型活页夹。
  • 我不熟悉模型绑定器是什么,你能告诉我更多关于它的信息吗?

标签: c# asp.net asp.net-web-api2


【解决方案1】:

出于某种原因,如果您使用 getter/setter 而不是属性,它可以开箱即用。

public SpendingAccountSearchParams()
{
    DateTime AsOfDate { get; set; } = DateTime.Now;
    int Skip { get; set; } = 0;
    int Top { get; set; } = 20;
}

【讨论】:

    【解决方案2】:

    你可以试试这个代码

         public async Task<IHttpActionResult> GetAsync([FromUri]SpendingAccountSearchParams spendingAccountSearchParams){
         if(spendingAccountSearchParams==null)
          {
             spendingAccountSearchParams.AsOfDate=DateTime.Now;
        spendingAccountSearchParams.Skip=0;
        spendingAccountSearchParams.Top=20;
         }
        else
        {
         // your code
    
        }
    }
    

    【讨论】:

    • 谢谢,但正如我在原始帖子中所说“我知道在控制器中我可以检查 null 并在它不存在时创建一个新对象,但这只是其中的一个示例端点。最终,我将拥有许多具有不同搜索参数的端点,我希望所有端点都自动发生。"
    【解决方案3】:

    鉴于您希望所有这些都自动发生,那么您应该创建一个自定义模型绑定器。

    阅读Parameter Binding in ASP.NET Web API

    使用模型绑定器,您可以访问 HTTP 请求等内容, 动作描述,以及来自路由数据的原始值。

    要创建模型绑定器,请实现 IModelBinder 接口。这 接口定义了一个方法,BindModel

    bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext);
    

    这是SpendingAccountSearchParams 对象的简化模型绑定器。

    public class SpendingAccountSearchParamsModelBinder : IModelBinder {
        public bool BindModel(HttpActionContext controllerContext, ModelBindingContext bindingContext) {
            if (bindingContext.ModelType != typeof(SpendingAccountSearchParams)) {
                return false;
            }
    
            ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (val == null) {
                //create your default object
                var result = new SpendingAccountSearchParams();
                bindingContext.Model = result;
                return true;
            }
    
            //you could do other checks and add ModelState errors if needed 
    
            return true;
        }
    }
    

    然后您需要注册您的活页夹。

    您可以为类型添加 [ModelBinder] 属性。 Web API 将为该类型的所有参数使用指定的模型绑定器。

    [ModelBinder(typeof(SpendingAccountSearchParamsModelBinder))]
    public class SpendingAccountSearchParams
    {
        // ....
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-02
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 2020-01-06
      • 1970-01-01
      相关资源
      最近更新 更多