コード例 #1
0
    public async Task BindModelAsync_LogsFormatterRejectionAndSelection()
    {
        // Arrange
        var sink            = new TestSink();
        var loggerFactory   = new TestLoggerFactory(sink, enabled: true);
        var inputFormatters = new List <IInputFormatter>()
        {
            new TestInputFormatter(canRead: false),
            new TestInputFormatter(canRead: true),
        };

        var provider = new TestModelMetadataProvider();

        provider.ForType <Person>().BindingDetails(d => d.BindingSource = BindingSource.Body);
        var bindingContext = GetBindingContext(typeof(Person), metadataProvider: provider);

        bindingContext.HttpContext.Request.ContentType = "application/json";
        var binder = new BodyModelBinder(inputFormatters, new TestHttpRequestStreamReaderFactory(), loggerFactory);

        // Act
        await binder.BindModelAsync(bindingContext);

        var writeList = sink.Writes.ToList();

        // Assert
        Assert.Equal($"Attempting to bind model of type '{typeof(Person)}' using the name 'someName' in request data ...", writeList[0].State.ToString());
        Assert.Equal($"Rejected input formatter '{typeof(TestInputFormatter)}' for content type 'application/json'.", writeList[1].State.ToString());
        Assert.Equal($"Selected input formatter '{typeof(TestInputFormatter)}' for content type 'application/json'.", writeList[2].State.ToString());
    }
コード例 #2
0
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException($"{nameof(bindingContext)} is null");
            }

            //调用原始body绑定数据
            bodyModelBinder.BindModelAsync(bindingContext);
            //判断是否设置了值
            if (!bindingContext.Result.IsModelSet)
            {
                return(Task.CompletedTask);
            }

            //获取绑定对象
            var model = bindingContext.Result.Model;

            var stringPropertyInfo = model.GetType().GetProperties().Where(c => c.PropertyType == typeof(string));

            foreach (var property in stringPropertyInfo)
            {
                string value = StringHelper.StringWithTrim(property.GetValue(model)?.ToString());
                property.SetValue(model, value);
            }

            return(Task.CompletedTask);
        }
        /// <inheritdoc cref="BindModelAsync"/>
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (!bindingContext.HttpContext.WebSockets.IsWebSocketRequest)
            {
                var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                if (valueProviderResult != ValueProviderResult.None)
                {
                    bindingContext.Result = ModelBindingResult.Success(valueProviderResult.FirstValue);
                    return(Task.CompletedTask);
                }

                // 바인딩 소스가 HTTP+Body 인 경우
                if (bindingContext.BindingSource == BindingSource.Body)
                {
                    var binder = new BodyModelBinder(_options.InputFormatters,
                                                     _requestStreamReaderFactory,
                                                     _loggerFactory,
                                                     _options);

                    return(binder.BindModelAsync(bindingContext));
                }
            }
            else
            {
                if (string.IsNullOrWhiteSpace(bindingContext.ModelName))
                {
                    if (!(bindingContext.HttpContext.Items["web-socket-io-packet"] is WebSocketIoPacket packet))
                    {
                        return(Task.CompletedTask);
                    }

                    try
                    {
                        var obj = JsonConvert.DeserializeObject(packet.Data.ToString(), bindingContext.ModelType);
                        bindingContext.Result = ModelBindingResult.Success(obj);
                    }
                    catch
                    {
                        return(Task.CompletedTask);
                    }
                }
                else
                {
                    var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                    if (valueProviderResult == ValueProviderResult.None)
                    {
                        return(Task.CompletedTask);
                    }

                    bindingContext.Result = ModelBindingResult.Success(valueProviderResult.FirstValue);
                }
            }

            return(Task.CompletedTask);
        }
コード例 #4
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            bindingContext.HttpContext.Request.EnableRewind();
            object baseModel       = null;
            object hydratedModel   = null;
            var    boundProperties = new List <KeyValuePair <string, string> >();
            var    modelBinderId   = string.Empty;
            var    valueProviders  = new List <KeyValuePair <string, IValueProvider> >();

            bindingContext.HttpContext.Request.Body.Position = 0;
            await defaultBinder.BindModelAsync(bindingContext);

            hydratedModel = bindingContext.Result.Model;

            if (hydratedModel == null)
            {
                if (hydratedModel == null)
                {
                    try
                    {
                        if (!bindingContext.HttpContext.Items.ContainsKey("bodyParms"))
                        {
                            bindingContext.HttpContext.Request.Body.Position = 0;
                            Stream stream = bindingContext.HttpContext.Request.Body;
                            byte[] buffer = new byte[bindingContext.HttpContext.Request.ContentLength.Value];
                            stream.Read(buffer, 0, buffer.Length);
                            string temp = Encoding.UTF8.GetString(buffer);
                            bindingContext.HttpContext.Items.Add("bodyParms", temp);
                        }
                        var jobj = JObject.Parse(bindingContext.HttpContext.Items["bodyParms"].ToString());
                        foreach (var p in jobj.Properties())
                        {
                            if (string.Equals(p.Name, bindingContext.FieldName, StringComparison.CurrentCultureIgnoreCase))
                            {
                                hydratedModel = Convert.ChangeType(jobj[p.Name].ToString(), bindingContext.ModelType);
                                break;
                            }
                        }
                    }
                    catch (Exception exp)
                    {
                        bindingContext.Result = ModelBindingResult.Failed();
                        return;
                    }
                }
                bindingContext.Result = ModelBindingResult.Success(hydratedModel);
            }
        }
コード例 #5
0
        /// <summary>Binds value from binding context.</summary>
        /// <param name="bindingContext">Model binding context instance.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            await _defaultBinder.BindModelAsync(bindingContext);

            if (bindingContext.Result.IsModelSet && bindingContext.Result.Model is IRequestHasIdentity <TKey> data)
            {
                var value          = bindingContext.ValueProvider.GetValue("Id").FirstValue;
                var convertedValue = ConvertValue(value);
                if (convertedValue != null)
                {
                    data.Id = convertedValue;
                }

                bindingContext.Result = ModelBindingResult.Success(data);
            }
        }
コード例 #6
0
    public async Task BindModelAsync_DoesNotThrowNullReferenceException()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        var provider    = new TestModelMetadataProvider();

        provider.ForType <Person>().BindingDetails(d => d.BindingSource = BindingSource.Body);
        var bindingContext = GetBindingContext(
            typeof(Person),
            httpContext: httpContext,
            metadataProvider: provider);
        var binder = new BodyModelBinder(new List <IInputFormatter>(), new TestHttpRequestStreamReaderFactory());

        // Act & Assert (does not throw)
        await binder.BindModelAsync(bindingContext);
    }
コード例 #7
0
    public async Task BindModelAsync_LogsNoFormatterSelectedAndRemoveFromBodyAttribute()
    {
        // Arrange
        var sink            = new TestSink();
        var loggerFactory   = new TestLoggerFactory(sink, enabled: true);
        var inputFormatters = new List <IInputFormatter>()
        {
            new TestInputFormatter(canRead: false),
            new TestInputFormatter(canRead: false),
        };

        var provider = new TestModelMetadataProvider();

        provider.ForType <Person>().BindingDetails(d => d.BindingSource = BindingSource.Body);
        var bindingContext = GetBindingContext(typeof(Person), metadataProvider: provider);

        bindingContext.HttpContext.Request.ContentType = "multipart/form-data";
        bindingContext.BinderModelName = bindingContext.ModelName;
        var binder = new BodyModelBinder(inputFormatters, new TestHttpRequestStreamReaderFactory(), loggerFactory);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.Collection(
            sink.Writes,
            write => Assert.Equal(
                $"Attempting to bind model of type '{typeof(Person)}' using the name 'someName' in request data ...", write.State.ToString()),
            write => Assert.Equal(
                $"Rejected input formatter '{typeof(TestInputFormatter)}' for content type 'multipart/form-data'.", write.State.ToString()),
            write => Assert.Equal(
                $"Rejected input formatter '{typeof(TestInputFormatter)}' for content type 'multipart/form-data'.", write.State.ToString()),
            write => Assert.Equal(
                "No input formatter was found to support the content type 'multipart/form-data' for use with the [FromBody] attribute.", write.State.ToString()),
            write => Assert.Equal(
                $"To use model binding, remove the [FromBody] attribute from the property or parameter named '{bindingContext.ModelName}' with model type '{bindingContext.ModelType}'.", write.State.ToString()),
            write => Assert.Equal(
                $"Done attempting to bind model of type '{typeof(Person)}' using the name 'someName'.", write.State.ToString()));
    }
コード例 #8
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            await defaultBinder.BindModelAsync(bindingContext);

            if (bindingContext.Result.IsModelSet)
            {
                var fromRouteProperties = bindingContext.Result.Model !.GetType()
                                          .GetProperties()
                                          .Where(x => x.CustomAttributes.Any(z => z.AttributeType == typeof(FromRouteAttribute)));
                var data = bindingContext.Result.Model;

                foreach (var property in fromRouteProperties)
                {
                    var value = bindingContext.ValueProvider.GetValue(property.Name)
                                .FirstValue;
                    var parsedValue = Convert.ChangeType(value, property.PropertyType);
                    data.GetType()
                    .GetProperty(property.Name)
                    ?.SetValue(data, parsedValue);
                }

                bindingContext.Result = ModelBindingResult.Success(data);
            }
        }
コード例 #9
0
 public Task BindModelAsync(ModelBindingContext bindingContext)
 {
     return(_bodyModelBinder.BindModelAsync(bindingContext));
 }