当前位置: 首页 > 知识库问答 >
问题:

自定义模型绑定器未从Swagger UI调用

慕容康安
2023-03-14

我正在使用。Net framework 4.6.1和Swashback版本5.3.2在我的WebApi项目中。Swagger UI没有提供将输入作为请求主体发送到使用自定义模型绑定器的my POST Api的选项。

-使用的模型:

    [ModelBinder(typeof(FieldValueModelBinder))]
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string EmployeeName { get; set; }
        public string City { get; set; }
    }

-使用的API Post方法:

    [HttpPost]
    // POST: api/Employee
    public HttpResponseMessage Post([ModelBinder(typeof(FieldValueModelBinder))]Employee emp)
    {
        if (!ModelState.IsValid)
            return Request.CreateResponse(HttpStatusCode.BadRequest, "Please provide valid input");
        else
            //Add Employee logic here
            return Request.CreateResponse(HttpStatusCode.OK, "Employee added sucessfully");
    }

-使用的活页夹型号:

public class FieldValueModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
    /// <summary>
    /// Store received data in API in KeyValuePair
    /// </summary>
    private List<KeyValuePair<string, string>> kvps;

    /// <summary>
    /// Storing error while binding data in Model class
    /// </summary>
    private Dictionary<string, string> dictionaryErrors = new Dictionary<string, string>();

    /// <summary>
    /// Implementing Base method and binding received data in API to its respected property in Model class
    /// </summary>
    /// <param name="actionContext">Http Action Context</param>
    /// <param name="bindingContext">Model Binding Context</param>
    /// <returns>True if no error while binding. False if any error occurs during model binding</returns>
    public bool BindModel(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
    {
        try
        {
            var bodyString = actionContext.Request.Content.ReadAsStringAsync().Result;
            if (actionContext.Request.Method.Method.ToUpper().Equals("GET"))
            {
                var uriContext = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);
                if (uriContext.HasKeys())
                {
                    this.kvps = uriContext.AllKeys.ToDictionary(k => k, k => uriContext[k]).ToList<KeyValuePair<string, string>>();
                }
            }
            else if (!string.IsNullOrEmpty(bodyString))
            {
                this.kvps = this.ConvertToKvps(bodyString);
            }
            else
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Please provide valid input data.");
                return false;
            }
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Please provide data in a valid format.");
            return false;
        }

        // Initiate primary object
        var obj = Activator.CreateInstance(bindingContext.ModelType);
        try
        {
            this.SetPropertyValues(obj);
        }
        catch (Exception ex)
        {
            if (this.dictionaryErrors.Any())
            {
                foreach (KeyValuePair<string, string> keyValuePair in this.dictionaryErrors)
                {
                    bindingContext.ModelState.AddModelError(keyValuePair.Key, keyValuePair.Value);
                }
            }
            else
            {
                bindingContext.ModelState.AddModelError("Internal Error", ex.Message);
            }

            this.dictionaryErrors.Clear();
            return false;
        }

        // Assign completed Mapped object to Model
        bindingContext.Model = obj;
        return true;
    }

我面临以下问题:

>

  • 当我们在post方法中使用“ModelBinder”时,Swagger UI显示这个屏幕,其中输入参数以查询字符串的形式发布,CustomModelBinder被调用,并尝试读取请求体以执行模型绑定和验证,在这种情况下为空。

    公共HttpResponseMessage帖子([ModelBinder(typeof(FieldValueModelBinder))]员工emp)

    当我们在post方法中使用FromBody时,Swagger UI会显示这个
    屏幕,我们可以在其中发送请求正文中的输入,但是在这个
    情况下,不调用CustomModelBinder,我们无法执行模型绑定和验证。

    公共HttpResponseMessage帖子([FromBody]员工emp)

    当我们尝试同时使用“modelbinder”和“frombody”时,Swagger UI将输入作为查询,我们得到以下响应:

    通过Postman的测试,该API运行良好,我们能够在请求正文中传递输入并获得正确的输出。自定义模型绑定也起作用,并在模型状态无效的情况下填充错误消息,然后我们可以使用这些消息在响应中发送。

    在将输入数据发布到请求体中的API时,需要更改哪些内容才能从Swagger UI调用自定义模型绑定器。请建议。

  • 共有1个答案

    梁季
    2023-03-14

    您可以使用IDocumentFilter来实现这一点。下面是代码:

    private class ApplyDocumentVendorExtensions : IDocumentFilter
    {
        public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry s, IApiExplorer a)
        {
            if (swaggerDoc != null)
            {
                foreach (var path in swaggerDoc.paths)
                {
                    if (path.Value.post != null && path.Value.post.parameters != null )
                    {
                        var parameters = path.Value.post.parameters;
                        if (parameters.Count == 3 && parameters[0].name.StartsWith("emp"))
                        {
                            path.Value.post.parameters = EmployeeBodyParam;
                        }
                    }
                }
            }
        }
    
        private IList<Parameter> EmployeeBodyParam
        {
            get
            {
                return new List<Parameter>
                {
                    new Parameter {
                        name = "emp",
                        @in = "body",
                        required = true,
                        schema = new Schema {
                            @ref = "#/definitions/Employee"
                        }
                    }
                };
            }
        }
    }
    
     类似资料:
    • 我正在用Web API5构建Web服务。我正在通过扩展IModelBinder接口来实现自定义模型绑定器,以将复杂类型映射为操作的参数。装订部分工作正常。但不会进行模型验证。ModelState.IsValid始终为true。 如果我显式调用Validate()或使用[FromUri]属性,则ModelState.isValid设置正确。 我应该在模型绑定器内实现验证部分。如果是,我应该如何实现?

    • 如果您是一位经验丰富的ML开发人员,而且ML Kit的预训练的模型不能满足您的需求,您可以通过ML Kit使用定 的TensorFlow Lite模型。 使用Firebase托管您的TensorFlow Lite模型或将其与您的应用程序打包在一起。然后,使用ML Kit SDK来使用您的自定义模型的最佳版本构建应用。如果您使用Firebase托管您的模型,ML Kit会自动更新您的用户的所用版本。

    • 英文原文:http://emberjs.com/guides/models/customizing-adapters/ 在Ember Data中,处理与后台数据仓库通信的逻辑是通过Adapter来完成的。Ember Data适配器内置了一些关于REST API的假定。如果后台的实现与Ember Data假定的惯例不同,那么通过扩展缺省的适配器可能很容易的实现。 有时因为一些原因需要自定义适配器,例

    • 我正在为log4j2编写一个自定义包装器。使用https://logging.apache.org/log4j/2.x/manual/customloglevels.html#Customlogggers 要求是根据要记录的对象类型选择追加器。我想的方法是扩展log4j2记录器并覆盖log方法(如info),在这些方法中检查对象类型并调用所需的appender。 现在我想让我的应用程序使用slf4

    • 我试图为当前登录的用户添加一些自定义数据,所以我发现我可以实现自己的UserDetailsService并将其插入Spring中,但它从未被调用,我总是以用户名字符串的形式获得主体。 我有我的UserDetailsService实现: 我的UserDetails实现: 并尝试通过多种方式在config(SecurityConfiguration)中设置它:

    • 自定义绑定(Custom Binding)允许我们通过代码实现自定义绑定规则,从而完成更高级的业务需求。 示例代码 //.js片段 justep.Bind.bindingHandlers.yourBindingName = { init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {