微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.net – 在F#Web Api项目中使用可选的查询参数

我正在使用F#ASP.NET模板将C#webapi项目转换为F#.除了可选的查询参数,一切都很好.我不断得到这个错误
{
    "message": "The request is invalid.","messageDetail": "The parameters dictionary contains an invalid entry for parameter 'start' for method 'System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage] GetvendorFiles(Int32,System.Nullable`1[System.DateTime])' in 'Thor.WebApi.vendorFilesController'. The dictionary contains a value of type 'System.Reflection.Missing',but the parameter requires a value of type 'System.Nullable`1[System.DateTime]'."
}

F#函数签名:

[<HttpGet; Route("")>]
member x.GetvendorFiles( [<Optional; DefaultParameterValue(100)>] count,[<Optional; DefaultParameterValue(null)>] start : Nullable<DateTime> ) =

C#函数签名:

[HttpGet]
[Route("")]
public async Task<HttpResponseMessage> GetvendorFiles(int count = 100,DateTime? start = null)

有没有人知道任何解决方法

更新:
我弄清了这个问题的原因. ASP.NET提取控制器操作using ParameterInfo认值.显然,F#编译器不会像C#一样编译认值(即使使用DefaultParameterValueAttribute)

什么是最好的方式或解决这个问题?是否需要注入或实现自己的ParameterBinding的一些过滤器?

解决方法

您可以使用自定义ActionFilterattribute实现解决此问题.以下代码支持在缺少操作参数时使用DefaultParameterValue值,以及当action参数具有System.Reflection.Missing类型的值时.

代码也在Gist ActionFilter for ASP.NET Web API DefaultParameterValue support in F#中.

namespace System.Web.Http

open System.Reflection
open System.Web.Http.Filters
open System.Web.Http.Controllers
open System.Runtime.InteropServices

/// Responsible for populating missing action arguments from DefaultParameterValueAttribute values.
/// Created to handle this issue https://github.com/aspnet/Mvc/issues/1923
/// Note: This is for later version of System.Web.Http but Could be back-ported.
type DefaultParameterValueFixupFilter() =
  inherit ActionFilterattribute()
  /// Get list of (paramInfo,defValue) tuples for params where DefaultParameterValueAttribute is present.
  let getDefParamVals (parameters:ParameterInfo array) =
    [ for param in parameters do
        let defParamValAttrs = param.GetCustomAttributes<DefaultParameterValueAttribute>() |> List.ofSeq 
        match defParamValAttrs with
        // Review: we are ignoring null defaults.  Is this correct?
        | [x] -> if x.Value = null then () else yield param,x.Value
        | [] -> () 
        | _ -> failwith "Multiple DefaultParameterValueAttribute on param '%s'!" param.Name
    ]
  /// Add action arg default values where specified in DefaultParameterValueAttribute attrs.
  let addActionArgDefsFromDefParamValAttrs (context:HttpActionContext) =  
    match context.ActionDescriptor with
    | :? ReflectedHttpActionDescriptor as ad ->
      let defParamVals = getDefParamVals (ad.MethodInfo.GetParameters())
      for (param,value) in defParamVals do
        match context.ActionArguments.TryGetValue(param.Name) with
        | true,:? System.Reflection.Missing
        | false,_ ->
          // Remove is null-op if key not found,so we handle both match cases OK.
          let _ = context.ActionArguments.Remove(param.Name)
          context.ActionArguments.Add(param.Name,value)
        | _,_ -> ()
    | _ -> ()
  /// Override adding suport for DefaultParameterValueAttribute values.
  override x.OnActionExecuting(context) =
    addActionArgDefsFromDefParamValAttrs context
    base.OnActionExecuting(context)
  /// Override adding suport for DefaultParameterValueAttribute values.
  override x.OnActionExecutingAsync(context,cancellationToken) =
    addActionArgDefsFromDefParamValAttrs context
    base.OnActionExecutingAsync(context,cancellationToken)

原文地址:https://www.jb51.cc/html/230404.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐