public void ModelMetadataProvider_UsesPredicateOnType() { // Arrange var type = typeof(User); var provider = CreateProvider(); var context = new ModelBindingContext(); var expected = new[] { "IsAdmin", "UserName" }; // Act var metadata = provider.GetMetadataForType(type); // Assert var predicate = metadata.PropertyBindingPredicateProvider.PropertyFilter; var matched = new HashSet<string>(); foreach (var property in metadata.Properties) { if (predicate(context, property.PropertyName)) { matched.Add(property.PropertyName); } } Assert.Equal<string>(expected, matched); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } var theFile = controllerContext.HttpContext.Request.Files[bindingContext.ModelName]; // case 1: there was no <input type="file" ... /> element in the post if (theFile == null) { return null; } // case 2: there was an <input type="file" ... /> element in the post, but it was left blank if (theFile.ContentLength == 0 && String.IsNullOrEmpty(theFile.FileName)) { return null; } // case 3: the file was posted return theFile; }
public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); Type[] typeArguments = null; if (ModelType.IsInterface) { Type matchingClosedInterface = TypeHelper.ExtractGenericInterface(bindingContext.ModelType, ModelType); if (matchingClosedInterface != null) { typeArguments = matchingClosedInterface.GetGenericArguments(); } } else { typeArguments = TypeHelper.GetTypeArgumentsIfMatch(bindingContext.ModelType, ModelType); } if (typeArguments != null) { if (SuppressPrefixCheck || bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return _modelBinderFactory(typeArguments); } } return null; }
public void BindModel() { // Arrange Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object)); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int[])), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider { { "someName[0]", "42" }, { "someName[1]", "84" } } }; mockIntBinder .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext ec, ModelBindingContext mbc) => { mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType); return true; }); // Act bool retVal = new ArrayModelBinder<int>().BindModel(context, bindingContext); // Assert Assert.True(retVal); int[] array = bindingContext.Model as int[]; Assert.Equal(new[] { 42, 84 }, array); }
public virtual bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingContext newBindingContext = CreateNewBindingContext(bindingContext, bindingContext.ModelName); bool boundSuccessfully = TryBind(actionContext, newBindingContext); if (!boundSuccessfully && !String.IsNullOrEmpty(bindingContext.ModelName) && bindingContext.FallbackToEmptyPrefix) { // fallback to empty prefix? newBindingContext = CreateNewBindingContext(bindingContext, modelName: String.Empty); boundSuccessfully = TryBind(actionContext, newBindingContext); } if (!boundSuccessfully) { return false; // something went wrong } // run validation and return the model // If we fell back to an empty prefix above and are dealing with simple types, // propagate the non-blank model name through for user clarity in validation errors. // Complex types will reveal their individual properties as model names and do not require this. if (!newBindingContext.ModelMetadata.IsComplexType && String.IsNullOrEmpty(newBindingContext.ModelName)) { newBindingContext.ValidationNode = new Validation.ModelValidationNode(newBindingContext.ModelMetadata, bindingContext.ModelName); } newBindingContext.ValidationNode.Validate(actionContext, null /* parentNode */); bindingContext.Model = newBindingContext.Model; return true; }
public async Task BindModel() { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(typeof(IDictionary<int, string>)), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider { { "someName[0]", new KeyValuePair<int, string>(42, "forty-two") }, { "someName[1]", new KeyValuePair<int, string>(84, "eighty-four") } }, OperationBindingContext = new OperationBindingContext { ModelBinder = CreateKvpBinder(), MetadataProvider = metadataProvider } }; var binder = new DictionaryModelBinder<int, string>(); // Act var retVal = await binder.BindModelAsync(bindingContext); // Assert Assert.NotNull(retVal); var dictionary = Assert.IsAssignableFrom<IDictionary<int, string>>(retVal.Model); Assert.NotNull(dictionary); Assert.Equal(2, dictionary.Count); Assert.Equal("forty-two", dictionary[42]); Assert.Equal("eighty-four", dictionary[84]); }
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); // case 1: there was no <input ... /> element containing this data if (valueProviderResult == null) { return false; } string base64String = (string)valueProviderResult.ConvertTo(typeof(string)); // case 2: there was an <input ... /> element but it was left blank if (String.IsNullOrEmpty(base64String)) { return false; } // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary // then we need to remove these quotes put in place by the ToString() method. string realValue = base64String.Replace("\"", String.Empty); try { bindingContext.Model = ConvertByteArray(Convert.FromBase64String(realValue)); return true; } catch { // corrupt data - just ignore return false; } }
public void BindModel_MissingValue_ReturnsTrue() { // Arrange Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider() }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.ServiceResolver.SetService(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true }); mockIntBinder .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext cc, ModelBindingContext mbc) => { mbc.Model = 42; return true; }); KeyValuePairModelBinder<int, string> binder = new KeyValuePairModelBinder<int, string>(); // Act bool retVal = binder.BindModel(context, bindingContext); // Assert Assert.True(retVal); Assert.Null(bindingContext.Model); Assert.Equal(new[] { "someName.key" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray()); }
public void TryBindStrongModel_BinderExists_BinderReturnsIncorrectlyTypedObject_ReturnsTrue() { // Arrange Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)), ModelName = "someName", ModelState = new ModelStateDictionary(), ValueProvider = new SimpleHttpValueProvider() }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true }); mockIntBinder .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext cc, ModelBindingContext mbc) => { Assert.Equal("someName.key", mbc.ModelName); return true; }); // Act int model; bool retVal = context.TryBindStrongModel(bindingContext, "key", new EmptyModelMetadataProvider(), out model); // Assert Assert.True(retVal); Assert.Equal(default(int), model); Assert.Single(bindingContext.ValidationNode.ChildNodes); Assert.Empty(bindingContext.ModelState); }
public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { return (from provider in _providers let binder = provider.GetBinder(actionContext, bindingContext) where binder != null select binder).FirstOrDefault(); }
public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException("bindingContext"); } ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); // case 1: there was no <input ... /> element containing this data if (valueResult == null) { return null; } string value = valueResult.AttemptedValue; // case 2: there was an <input ... /> element but it was left blank if (String.IsNullOrEmpty(value)) { return null; } // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary // then we need to remove these quotes put in place by the ToString() method. string realValue = value.Replace("\"", String.Empty); return Convert.FromBase64String(realValue); }
public void BindModel() { // Arrange Mock<IModelBinder> mockDtoBinder = new Mock<IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()), ModelName = "someName" }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(ComplexModelDto), mockDtoBinder.Object) { SuppressPrefixCheck = true }); mockDtoBinder .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext cc, ModelBindingContext mbc2) => { return true; // just return the DTO unchanged }); Mock<TestableMutableObjectModelBinder> mockTestableBinder = new Mock<TestableMutableObjectModelBinder> { CallBase = true }; mockTestableBinder.Setup(o => o.EnsureModelPublic(context, bindingContext)).Verifiable(); mockTestableBinder.Setup(o => o.GetMetadataForPropertiesPublic(context, bindingContext)).Returns(new ModelMetadata[0]).Verifiable(); TestableMutableObjectModelBinder testableBinder = mockTestableBinder.Object; testableBinder.MetadataProvider = new DataAnnotationsModelMetadataProvider(); // Act bool retValue = testableBinder.BindModel(context, bindingContext); // Assert Assert.True(retValue); Assert.IsType<Person>(bindingContext.Model); Assert.True(bindingContext.ValidationNode.ValidateAllProperties); mockTestableBinder.Verify(); }
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(ComplexModelDto), false /* allowNullModel */); ComplexModelDto dto = (ComplexModelDto)bindingContext.Model; foreach (ModelMetadata propertyMetadata in dto.PropertyMetadata) { ModelBindingContext propertyBindingContext = new ModelBindingContext(bindingContext) { ModelMetadata = propertyMetadata, ModelName = ModelBindingHelper.CreatePropertyModelName(bindingContext.ModelName, propertyMetadata.PropertyName) }; // bind and propagate the values IModelBinder propertyBinder; if (actionContext.TryGetBinder(propertyBindingContext, out propertyBinder)) { if (propertyBinder.BindModel(actionContext, propertyBindingContext)) { dto.Results[propertyMetadata] = new ComplexModelDtoResult(propertyBindingContext.Model, propertyBindingContext.ValidationNode); } else { dto.Results[propertyMetadata] = null; } } } return true; }
public void ModelNameProperty() { // Arrange ModelBindingContext bindingContext = new ModelBindingContext(); // Act & assert MemberHelper.TestStringProperty(bindingContext, "ModelName", String.Empty); }
public void ModelStateProperty() { // Arrange ModelBindingContext bindingContext = new ModelBindingContext(); ModelStateDictionary modelState = new ModelStateDictionary(); // Act & assert MemberHelper.TestPropertyWithDefaultInstance(bindingContext, "ModelState", modelState); }
public void PropertyFilterPropertyReturnsDefaultInstance() { // Arrange ModelBindingContext bindingContext = new ModelBindingContext(); Predicate<string> propertyFilter = _ => true; // Act & assert MemberHelper.TestPropertyWithDefaultInstance(bindingContext, "PropertyFilter", propertyFilter); }
public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { // no entry return TaskCache.CompletedTask; } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { if (string.IsNullOrEmpty(valueProviderResult.Values)) { if (bindingContext.ModelType == typeof(decimal?)) { decimal? defaultValue = null; bindingContext.Result = ModelBindingResult.Success(defaultValue); return TaskCache.CompletedTask; } else { decimal defaultValue = 0.0M; bindingContext.Result = ModelBindingResult.Success(defaultValue); return TaskCache.CompletedTask; } } decimal model = Convert.ToDecimal( valueProviderResult.Values, CultureInfo.InvariantCulture); bindingContext.Result = ModelBindingResult.Success(model); return TaskCache.CompletedTask; } catch (Exception exception) { bindingContext.ModelState.TryAddModelError( bindingContext.ModelName, exception, bindingContext.ModelMetadata); //customized error message //string displayName = bindingContext.ModelMetadata.DisplayName ?? bindingContext.ModelName; //bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, // string.Format("not decimal input:{0}", displayName)); // Were able to find a converter for the type but conversion failed. return TaskCache.CompletedTask; } }
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { Contract.Assert(!_parent.SuppressPrefixCheck); // wouldn't have even created this binder if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { IModelBinder binder = _parent._modelBinderFactory(); return binder.BindModel(actionContext, bindingContext); } return false; }
public void ModelProperty_ThrowsIfModelMetadataDoesNotExist() { // Arrange var bindingContext = new ModelBindingContext(); // Act & assert ExceptionAssert.Throws<InvalidOperationException>( () => bindingContext.Model = null, "The ModelMetadata property must be set before accessing this property."); }
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (controllerContext.Controller.RequestType() != HttpVerbs.Get) { return base.BindModel(controllerContext, bindingContext); } else { return base.CreateModel(controllerContext, bindingContext, bindingContext.ModelType); } }
public void ModelTypeAreFedFromModelMetadata() { // Act var bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)) }; // Assert Assert.Equal(typeof(int), bindingContext.ModelType); }
private async Task BindModelCoreAsync(ModelBindingContext bindingContext) { // Create model first (if necessary) to avoid reporting errors about properties when activation fails. if (bindingContext.Model == null) { bindingContext.Model = CreateModel(bindingContext); } foreach (var property in bindingContext.ModelMetadata.Properties) { if (!CanBindProperty(bindingContext, property)) { continue; } // Pass complex (including collection) values down so that binding system does not unnecessarily // recreate instances or overwrite inner properties that are not bound. No need for this with simple // values because they will be overwritten if binding succeeds. Arrays are never reused because they // cannot be resized. object propertyModel = null; if (property.PropertyGetter != null && property.IsComplexType && !property.ModelType.IsArray) { propertyModel = property.PropertyGetter(bindingContext.Model); } var fieldName = property.BinderModelName ?? property.PropertyName; var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName); ModelBindingResult result; using (bindingContext.EnterNestedScope( modelMetadata: property, fieldName: fieldName, modelName: modelName, model: propertyModel)) { await BindProperty(bindingContext); result = bindingContext.Result ?? ModelBindingResult.Failed(modelName); } if (result.IsModelSet) { SetProperty(bindingContext, property, result); } else if (property.IsBindingRequired) { var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName); bindingContext.ModelState.TryAddModelError(modelName, message); } } bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, bindingContext.Model); }
/// <inheritdoc /> public async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var requestServices = bindingContext.HttpContext.RequestServices; var binder = (IModelBinder)_factory(requestServices, arguments: null); await binder.BindModelAsync(bindingContext); }
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { DetailsViewModel o = (DetailsViewModel)base.BindModel(controllerContext, bindingContext); if (ControllerHelper.RequestType(controllerContext) == HttpVerbs.Post) { Expression<Func<DetailsViewModel, MembershipUserWrapper>> expression = m => ((DetailsViewModel)bindingContext.Model).UserOriginal; string expressionText = ExpressionHelper.GetExpressionText(expression); string jsonUserDetails = bindingContext.ValueProvider.GetValue(expressionText).AttemptedValue; o.UserOriginal = baseModel.DeserializeFromJson<MembershipUserWrapper>(jsonUserDetails); } return o; }
public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) { ValueProviderResult vpResult = GetCompatibleValueProviderResult(bindingContext); if (vpResult == null) { return false; // conversion would have failed } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, vpResult); object model = vpResult.RawValue; ModelBinderUtil.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model); bindingContext.Model = model; return true; }
public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return CollectionModelBinderUtil.GetGenericBinder(typeof(IDictionary<,>), typeof(Dictionary<,>), typeof(DictionaryModelBinder<,>), bindingContext.ModelMetadata); } else { return null; } }
public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!bindingContext.ModelMetadata.IsReadOnly && bindingContext.ModelType.IsArray && bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { Type elementType = bindingContext.ModelType.GetElementType(); return (IModelBinder)Activator.CreateInstance(typeof(ArrayModelBinder<>).MakeGenericType(elementType)); } return null; }
public virtual bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); EnsureModel(actionContext, bindingContext); IEnumerable<ModelMetadata> propertyMetadatas = GetMetadataForProperties(actionContext, bindingContext); ComplexModelDto dto = CreateAndPopulateDto(actionContext, bindingContext, propertyMetadatas); // post-processing, e.g. property setters and hooking up validation ProcessDto(actionContext, bindingContext, dto); bindingContext.ValidationNode.ValidateAllProperties = true; // complex models require full validation return true; }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { controllerContext.EnsureArgumentNotNull("controllerContext"); bindingContext.EnsureArgumentNotNull("bindingContext"); _params = (bindingContext.Model as IDictionary<SymbolId, object>) ?? new RubyParams(); bindingContext.ValueProvider.ForEach(pair => { bindingContext.ModelState.SetModelValue(pair.Key, pair.Value); _params.Add(pair.Key.ToSymbolId(), pair.Value.AttemptedValue); }); return _params; }
public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) { // Fast-path the case where we already have the providers. if (_providers != null) { return new CompositeModelBinder(_providers); } // Extract all providers from the resolver except the the type of the executing one (else would cause recursion), // or use the set of providers we were given. IEnumerable<ModelBinderProvider> providers = actionContext.ControllerContext.Configuration.Services.GetModelBinderProviders().Where(p => !(p is CompositeModelBinderProvider)); return new CompositeModelBinder(providers); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ValueProviderResult valueResult = bindingContext.ValueProvider .GetValue(bindingContext.ModelName); ModelState modelState = new ModelState { Value = valueResult }; object actualValue = null; if (!string.IsNullOrEmpty(valueResult.AttemptedValue)) { try { // Tries to figure out how many decimal characters we have after the decimal separator. string value = valueResult.AttemptedValue; int decimals = 0; // Make sure it will break the checking right after discovering how many decimal characters there is after the decimal character. while (true) { if (value[value.Length - 3] == ',' || value[value.Length - 3] == '.') { decimals = 2; break; } if (value[value.Length - 4] == ',' || value[value.Length - 4] == '.') { decimals = 3; break; } if (value[value.Length - 5] == ',' || value[value.Length - 5] == ',') { decimals = 4; break; } break; } // Replace all special characters in order to make the proper conversion from the string to the decimal. string final_value; final_value = value.Replace(",", "").Replace(".", ""); // Insert the decimal character at the correct position given the ammount of decimal characters we retrieved. final_value = final_value.Insert(final_value.Length - decimals, "."); // Converts the actual decimal. actualValue = Convert.ToDecimal(final_value, CultureInfo.InvariantCulture); } catch (FormatException e) { modelState.Errors.Add(e); } } bindingContext.ModelState.Add(bindingContext.ModelName, modelState); return(actualValue); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { throw new NotImplementedException(); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { IDictionary <string, string> dicts = controllerContext.RequestContext.HttpContext.Request.QueryString.ToDictionary(); return(dicts); }
public Task BindModelAsync(ModelBindingContext bindingContext) { return(Task.CompletedTask); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); return(new ObjectId(result.AttemptedValue)); }
private async Task BindModelCoreAsync(ModelBindingContext bindingContext) { // Create model first (if necessary) to avoid reporting errors about properties when activation fails. if (bindingContext.Model == null) { bindingContext.Model = CreateModel(bindingContext); } var modelMetadata = bindingContext.ModelMetadata; var attemptedPropertyBinding = false; for (var i = 0; i < modelMetadata.Properties.Count; i++) { var property = modelMetadata.Properties[i]; if (!CanBindProperty(bindingContext, property)) { continue; } // Pass complex (including collection) values down so that binding system does not unnecessarily // recreate instances or overwrite inner properties that are not bound. No need for this with simple // values because they will be overwritten if binding succeeds. Arrays are never reused because they // cannot be resized. object propertyModel = null; if (property.PropertyGetter != null && property.IsComplexType && !property.ModelType.IsArray) { propertyModel = property.PropertyGetter(bindingContext.Model); } var fieldName = property.BinderModelName ?? property.PropertyName; var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName); ModelBindingResult result; using (bindingContext.EnterNestedScope( modelMetadata: property, fieldName: fieldName, modelName: modelName, model: propertyModel)) { await BindProperty(bindingContext); result = bindingContext.Result; } if (result.IsModelSet) { attemptedPropertyBinding = true; SetProperty(bindingContext, modelName, property, result); } else if (property.IsBindingRequired) { attemptedPropertyBinding = true; var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName); bindingContext.ModelState.TryAddModelError(modelName, message); } } // Have we created a top-level model despite an inability to bind anything in said model and a lack of // other IsBindingRequired errors? Does that violate [BindRequired] on the model? This case occurs when // 1. The top-level model has no public settable properties. // 2. All properties in a [BindRequired] model have [BindNever] or are otherwise excluded from binding. // 3. No data exists for any property. if (!attemptedPropertyBinding && bindingContext.IsTopLevelObject && modelMetadata.IsBindingRequired) { var messageProvider = modelMetadata.ModelBindingMessageProvider; var message = messageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName); bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message); } bindingContext.Result = ModelBindingResult.Success(bindingContext.Model); _logger.DoneAttemptingToBindModel(bindingContext); }
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { bindingContext.Model = actionContext.Request.ODataProperties(); return(true); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); return(value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture)); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { return(new PluginInstallInput(controllerContext.HttpContext.Request.Form["virtualPath"])); }
public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var allValues = bindingContext.HttpContext.Request.Query; // Retrieve request data var draw = Convert.ToInt32(allValues.FirstOrDefault(a => a.Key == "draw").Value); var start = Convert.ToInt32(allValues.FirstOrDefault(a => a.Key == "start").Value); var length = Convert.ToInt32(allValues.FirstOrDefault(a => a.Key == "length").Value); // Search var search = new DTSearch { Value = allValues.FirstOrDefault(a => a.Key == "search[value]").Value, Regex = Convert.ToBoolean(allValues.FirstOrDefault(a => a.Key == "search[regex]").Value) }; // Order var o = 0; var order = new List<DTOrder>(); while (allValues.Any(a => a.Key == "order[" + o + "][column]")) { Enum.TryParse(allValues.FirstOrDefault(a => a.Key == "order[" + o + "][dir]").Value.ToString().ToUpperInvariant(), out DTOrderDir dir); order.Add(new DTOrder { Column = Convert.ToInt32(allValues.FirstOrDefault(a => a.Key == "order[" + o + "][column]").Value), Dir = dir }); o++; } // Columns var c = 0; var columns = new List<DTColumn>(); while (allValues.Any(a => a.Key == "columns[" + c + "][name]")) { columns.Add(new DTColumn { Data = allValues.FirstOrDefault(a => a.Key == "columns[" + c + "][data]").Value, Name = allValues.FirstOrDefault(a => a.Key == "columns[" + c + "][name]").Value, Orderable = Convert.ToBoolean(allValues.FirstOrDefault(a => a.Key == "columns[" + c + "][orderable]").Value), Searchable = Convert.ToBoolean(allValues.FirstOrDefault(a => a.Key == "columns[" + c + "][searchable]").Value), Search = new DTSearch { Value = allValues.FirstOrDefault(a => a.Key == "columns[" + c + "][search][value]").Value, Regex = Convert.ToBoolean(allValues.FirstOrDefault(a => a.Key == "columns[" + c + "][search][regex]").Value) } }); c++; } // Additional Values var p = 0; var additionalValues = new List<string>(); while (allValues.Any(a => a.Key == "additionalValues[" + p + "]")) { additionalValues.Add(allValues.FirstOrDefault(a => a.Key == "additionalValues[" + p + "]").Value); p++; } var model = new JqueryDataTablesParameters { Draw = draw, Start = start, Length = length, Search = search, Order = order.ToArray(), Columns = columns.ToArray(), AdditionalValues = additionalValues.ToArray() }; bindingContext.Result = ModelBindingResult.Success(model); return Task.CompletedTask; }
// Parses custom parameters sent with the request. public IDictionary <string, object> DataTablesParser(ControllerContext controllerContext, ModelBindingContext bindingContext) { var values = new Dictionary <string, object>(); var sampleParameter = bindingContext.ValueProvider.GetValue("p1"); values.Add("p1", sampleParameter.FirstValue); return(values); }
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext) { if (!typeof(BlockFeature).IsAssignableFrom(bindingContext.ModelType)) { return(false); } ValueProviderResult val = bindingContext.ValueProvider.GetValue( bindingContext.ModelName); if (val == null) { return(true); } string key = val.RawValue as string; if (key == null) { bindingContext.Model = null; return(true); } BlockFeature feature = BlockFeature.Parse(key); bindingContext.Model = feature; return(true); }
private bool CanValueBindAnyModelProperties(ModelBindingContext bindingContext) { // If there are no properties on the model, there is nothing to bind. We are here means this is not a top // level object. So we return false. if (bindingContext.ModelMetadata.Properties.Count == 0) { _logger.NoPublicSettableProperties(bindingContext); return(false); } // We want to check to see if any of the properties of the model can be bound using the value providers, // because that's all that MutableObjectModelBinder can handle. // // However, because a property might specify a custom binding source ([FromForm]), it's not correct // for us to just try bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName), // because that may include other value providers - that would lead us to mistakenly create the model // when the data is coming from a source we should use (ex: value found in query string, but the // model has [FromForm]). // // To do this we need to enumerate the properties, and see which of them provide a binding source // through metadata, then we decide what to do. // // If a property has a binding source, and it's a greedy source, then it's not // allowed to come from a value provider, so we skip it. // // If a property has a binding source, and it's a non-greedy source, then we'll filter the // the value providers to just that source, and see if we can find a matching prefix // (see CanBindValue). // // If a property does not have a binding source, then it's fair game for any value provider. // // If any property meets the above conditions and has a value from ValueProviders, then we'll // create the model and try to bind it. OR if ALL properties of the model have a greedy source, // then we go ahead and create it. // var hasBindableProperty = false; var isAnyPropertyEnabledForValueProviderBasedBinding = false; for (var i = 0; i < bindingContext.ModelMetadata.Properties.Count; i++) { var propertyMetadata = bindingContext.ModelMetadata.Properties[i]; if (!CanBindProperty(bindingContext, propertyMetadata)) { continue; } hasBindableProperty = true; // This check will skip properties which are marked explicitly using a non value binder. var bindingSource = propertyMetadata.BindingSource; if (bindingSource == null || !bindingSource.IsGreedy) { isAnyPropertyEnabledForValueProviderBasedBinding = true; var fieldName = propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName; var modelName = ModelNames.CreatePropertyModelName( bindingContext.ModelName, fieldName); using (bindingContext.EnterNestedScope( modelMetadata: propertyMetadata, fieldName: fieldName, modelName: modelName, model: null)) { // If any property can be bound from a value provider then continue. if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(true); } } } } if (hasBindableProperty && !isAnyPropertyEnabledForValueProviderBasedBinding) { // All the properties are marked with a non value provider based marker like [FromHeader] or // [FromBody]. return(true); } _logger.CannotBindToComplexType(bindingContext); return(false); }
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var model = base.BindModel(controllerContext, bindingContext); return(model); }
public virtual void BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { }
private bool CanBindAnyModelProperties(ModelBindingContext bindingContext) { // If there are no properties on the model, there is nothing to bind. We are here means this is not a top // level object. So we return false. if (bindingContext.ModelMetadata.Properties.Count == 0) { _logger.NoPublicSettableProperties(bindingContext); return(false); } // We want to check to see if any of the properties of the model can be bound using the value providers or // a greedy binder. // // Because a property might specify a custom binding source ([FromForm]), it's not correct // for us to just try bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName); // that may include other value providers - that would lead us to mistakenly create the model // when the data is coming from a source we should use (ex: value found in query string, but the // model has [FromForm]). // // To do this we need to enumerate the properties, and see which of them provide a binding source // through metadata, then we decide what to do. // // If a property has a binding source, and it's a greedy source, then it's always bound. // // If a property has a binding source, and it's a non-greedy source, then we'll filter the // the value providers to just that source, and see if we can find a matching prefix // (see CanBindValue). // // If a property does not have a binding source, then it's fair game for any value provider. // // Bottom line, if any property meets the above conditions and has a value from ValueProviders, then we'll // create the model and try to bind it. Of, if ANY properties of the model have a greedy source, // then we go ahead and create it. // for (var i = 0; i < bindingContext.ModelMetadata.Properties.Count; i++) { var propertyMetadata = bindingContext.ModelMetadata.Properties[i]; if (!CanBindProperty(bindingContext, propertyMetadata)) { continue; } // If any property can be bound from a greedy binding source, then success. var bindingSource = propertyMetadata.BindingSource; if (bindingSource != null && bindingSource.IsGreedy) { return(true); } // Otherwise, check whether the (perhaps filtered) value providers have a match. var fieldName = propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName; var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName); using (bindingContext.EnterNestedScope( modelMetadata: propertyMetadata, fieldName: fieldName, modelName: modelName, model: null)) { // If any property can be bound from a value provider, then success. if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(true); } } } _logger.CannotBindToComplexType(bindingContext); return(false); }
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType != typeof(coreModel.SearchCriteria)) { return(false); } var qs = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query as string); var result = new coreModel.SearchCriteria(); result.Keyword = qs["q"].EmptyToNull(); var respGroup = qs["respGroup"].EmptyToNull(); if (respGroup != null) { result.ResponseGroup = EnumUtility.SafeParse <coreModel.ResponseGroup>(respGroup, coreModel.ResponseGroup.Default); } result.StoreIds = qs.GetValues("stores"); result.CustomerId = qs["customer"].EmptyToNull(); result.EmployeeId = qs["employee"].EmptyToNull(); result.Count = qs["count"].TryParse(20); result.Start = qs["start"].TryParse(0); bindingContext.Model = result; return(true); }
/// <summary> /// For internal and testing use only. /// Binds request data/parameters/values into a 'IDataTablesRequest' element. /// </summary> /// <param name="controllerContext">Controller context for execution.</param> /// <param name="bindingContext">Binding context for data/parameters/values.</param> /// <param name="options">DataTables.AspNet global options.</param> /// <returns>An IDataTablesRequest object or null if binding was not possible.</returns> public virtual void BindModel(ModelBindingContext bindingContext, IOptions options, Func <ModelBindingContext, IDictionary <string, object> > parseAditionalParameters) { // Model binding is not set, thus AspNet5 will keep looking for other model binders. if (!bindingContext.ModelType.Equals(typeof(IDataTablesRequest))) { //return ModelBindingResult.NoResult; return; } // Binding is set to a null model to avoid unexpected errors. if (options == null || options.RequestNameConvention == null) { //return ModelBindingResult.Failed(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(); return; } var values = bindingContext.ValueProvider; // Accordingly to DataTables docs, it is recommended to receive/return draw casted as int for security reasons. // This is meant to help prevent XSS attacks. var draw = values.GetValue(options.RequestNameConvention.Draw); int _draw = 0; if (options.IsDrawValidationEnabled && !Parse <Int32>(draw, out _draw)) { //return ModelBindingResult.Failed(bindingContext.ModelName); // Null model result (invalid request). bindingContext.Result = ModelBindingResult.Failed(); return; } var start = values.GetValue(options.RequestNameConvention.Start); int _start = 0; Parse <int>(start, out _start); var length = values.GetValue(options.RequestNameConvention.Length); int _length = options.DefaultPageLength; Parse <int>(length, out _length); var searchValue = values.GetValue(options.RequestNameConvention.SearchValue); string _searchValue = null; Parse <string>(searchValue, out _searchValue); var searchRegex = values.GetValue(options.RequestNameConvention.IsSearchRegex); bool _searchRegex = false; Parse <bool>(searchRegex, out _searchRegex); var search = new Search(_searchValue, _searchRegex); // Parse columns & column sorting. var columns = ParseColumns(values, options.RequestNameConvention); var sorting = ParseSorting(columns, values, options.RequestNameConvention); if (options.IsRequestAdditionalParametersEnabled && parseAditionalParameters != null) { var aditionalParameters = parseAditionalParameters(bindingContext); var model = new DataTablesRequest(_draw, _start, _length, search, columns, aditionalParameters); { //return ModelBindingResult.Success(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(model); return; } } else { var model = new DataTablesRequest(_draw, _start, _length, search, columns); { //return ModelBindingResult.Success(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(model); return; } } }
public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } _logger.AttemptingToBindModel(bindingContext); var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { _logger.FoundNoValueInRequest(bindingContext); // no entry _logger.DoneAttemptingToBindModel(bindingContext); return(Task.CompletedTask); } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { var value = valueProviderResult.FirstValue; object?model; if (bindingContext.ModelType == typeof(string)) { // Already have a string. No further conversion required but handle ConvertEmptyStringToNull. if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && string.IsNullOrWhiteSpace(value)) { model = null; } else { model = value; } } else if (string.IsNullOrWhiteSpace(value)) { // Other than the StringConverter, converters Trim() the value then throw if the result is empty. model = null; } else { model = _typeConverter.ConvertFrom( context: null, culture: valueProviderResult.Culture, value: value); } CheckModel(bindingContext, valueProviderResult, model); _logger.DoneAttemptingToBindModel(bindingContext); return(Task.CompletedTask); } catch (Exception exception) { var isFormatException = exception is FormatException; if (!isFormatException && exception.InnerException != null) { // TypeConverter throws System.Exception wrapping the FormatException, // so we capture the inner exception. exception = ExceptionDispatchInfo.Capture(exception.InnerException).SourceException; } bindingContext.ModelState.TryAddModelError( bindingContext.ModelName, exception, bindingContext.ModelMetadata); // Were able to find a converter for the type but conversion failed. return(Task.CompletedTask); } }
/// <summary> /// Perform additional actions for binding the model /// </summary> /// <param name="bindingContext">Model binding context</param> /// <remarks>Developers can override this method in custom partial classes in order to add some custom model binding</remarks> public virtual void BindModel(ModelBindingContext bindingContext) { }
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext) { var jsonString = actionContext.Request.Content.ReadAsStringAsync().Result; var json = JObject.Parse(jsonString); var customEntityDefinitionCodeProperty = json.GetValue("CustomEntityDefinitionCode", StringComparison.OrdinalIgnoreCase); JsonConverter dataModelConverter; if (customEntityDefinitionCodeProperty == null) { dataModelConverter = new NullCustomEntityDataModelJsonConverter(); } else { dataModelConverter = GetModuleDataTypeConverter(customEntityDefinitionCodeProperty.Value <string>()); } var result = JsonConvert.DeserializeObject(jsonString, bindingContext.ModelType, dataModelConverter); bindingContext.Model = result; return(true); }
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var incomingData = bindingContext.ValueProvider.GetValue("DayDate").AttemptedValue; return(DayDate.FromString(incomingData)); }
private async Task BindProperty(ModelBindingContext bindingContext) { var complexTypeModelBinder = new ComplexTypeModelBinder(_propertyBinders, _loggerFactory); await complexTypeModelBinder.BindModelAsync(bindingContext); }
/// <summary> /// Attempts to bind a property of the model. /// </summary> /// <param name="bindingContext">The <see cref="ModelBindingContext"/> for the model property.</param> /// <returns> /// A <see cref="Task"/> that when completed will set <see cref="ModelBindingContext.Result"/> to the /// result of model binding. /// </returns> protected virtual Task BindProperty(ModelBindingContext bindingContext) { var binder = _propertyBinders[bindingContext.ModelMetadata]; return(binder.BindModelAsync(bindingContext)); }
/// <summary> /// Initializes the <see cref="NestedScope"/> for a <see cref="ModelBindingContext"/>. /// </summary> /// <param name="context"></param> public NestedScope(ModelBindingContext context) { _context = context; }
public new async Task BindModelAsync(ModelBindingContext bindingContext) { var modelType = bindingContext.ModelType; var controllerContext = bindingContext.ActionContext; if (modelType.As <IEntity>()) { var fact = EntityFactory.CreateOperate(modelType); if (fact != null) { var rvs = controllerContext.RouteData.Values; var pks = fact.Table.PrimaryKeys; var uk = fact.Unique; IEntity entity = null; if (uk != null) { // 查询实体对象用于编辑 if (rvs[uk.Name] != null) { entity = //GetEntity(fact.EntityType, rvs[uk.Name]) ?? fact.FindByKeyForEdit(rvs[uk.Name]); // 从session取回来的实体全部被设置了脏属性,每次保存所有数据,因此从数据查找 } if (entity == null) { entity = fact.Create(); } } else if (pks.Length > 0) { // 查询实体对象用于编辑 var vs = pks.Select(e => rvs[e.Name]).ToArray(); entity = GetEntity(fact.EntityType, vs); if (entity == null) { var req = controllerContext.HttpContext.Request; var exp = new WhereExpression(); foreach (var item in pks) { exp &= item.Equal(req.GetRequestValue(item.Name).ChangeType(item.Type)); } entity = fact.Find(exp); } if (entity == null) { entity = fact.Create(); } } if (entity != null) { var req = controllerContext.HttpContext.Request; if (req.HasFormContentType) { var fs = req.Form; // 提前填充动态字段的扩展属性 foreach (var item in fact.Fields) { if (item.IsDynamic && fs.ContainsKey(item.Name)) { entity.SetItem(item.Name, fs[item.Name]); } } } bindingContext.Result = ModelBindingResult.Success(entity); } if (entity == null) { bindingContext.Result = ModelBindingResult.Success(fact.Create()); } // 为Model赋值,为下面BindProperty方法做准备 bindingContext.Model = bindingContext.Result.Model; // 使用复杂类型模型绑定器ComplexTypeModelBinder填充Model await BindProperty(bindingContext); } } }
public BindResult BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { IKeyedModelBinder binder = GetKeyedModelBinder(bindingContext.ModelType); return(binder.BindModel(controllerContext, bindingContext)); }
/// <inheritdoc /> public async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } // Special logic for body, treat the model name as string.Empty for the top level // object, but allow an override via BinderModelName. The purpose of this is to try // and be similar to the behavior for POCOs bound via traditional model binding. string modelBindingKey; if (bindingContext.IsTopLevelObject) { modelBindingKey = bindingContext.BinderModelName ?? string.Empty; } else { modelBindingKey = bindingContext.ModelName; } var httpContext = bindingContext.HttpContext; var allowEmptyInputInModelBinding = _options?.AllowEmptyInputInBodyModelBinding == true; var formatterContext = new InputFormatterContext( httpContext, modelBindingKey, bindingContext.ModelState, bindingContext.ModelMetadata, _readerFactory, allowEmptyInputInModelBinding); var formatter = (IInputFormatter)null; for (var i = 0; i < _formatters.Count; i++) { if (_formatters[i].CanRead(formatterContext)) { formatter = _formatters[i]; _logger?.InputFormatterSelected(formatter, formatterContext); break; } else { _logger?.InputFormatterRejected(_formatters[i], formatterContext); } } if (formatter == null) { _logger?.NoInputFormatterSelected(formatterContext); var message = Resources.FormatUnsupportedContentType(httpContext.Request.ContentType); var exception = new UnsupportedContentTypeException(message); bindingContext.ModelState.AddModelError(modelBindingKey, exception, bindingContext.ModelMetadata); return; } try { var result = await formatter.ReadAsync(formatterContext); var model = result.Model; if (result.HasError) { // Formatter encountered an error. Do not use the model it returned. return; } if (result.IsModelSet) { bindingContext.Result = ModelBindingResult.Success(model); } else { // If the input formatter gives a "no value" result, that's always a model state error, // because BodyModelBinder implicitly regards input as being required for model binding. // If instead the input formatter wants to treat the input as optional, it must do so by // returning InputFormatterResult.Success(defaultForModelType), because input formatters // are responsible for choosing a default value for the model type. var message = bindingContext .ModelMetadata .ModelBindingMessageProvider .MissingRequestBodyRequiredValueAccessor(); bindingContext.ModelState.AddModelError(modelBindingKey, message); } } catch (Exception exception) when(exception is InputFormatterException || ShouldHandleException(formatter)) { bindingContext.ModelState.AddModelError(modelBindingKey, exception, bindingContext.ModelMetadata); } }
public bool ShouldBind(ControllerContext controllerContext, ModelBindingContext bindingContext) { return(typeof(KeyedObject).IsAssignableFrom(bindingContext.ModelType)); }
public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } _logger.AttemptingToBindModel(bindingContext); var modelName = bindingContext.ModelName; var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); if (valueProviderResult == ValueProviderResult.None) { _logger.FoundNoValueInRequest(bindingContext); // no entry _logger.DoneAttemptingToBindModel(bindingContext); return(Task.CompletedTask); } var modelState = bindingContext.ModelState; modelState.SetModelValue(modelName, valueProviderResult); var metadata = bindingContext.ModelMetadata; var type = metadata.UnderlyingOrModelType; try { var value = valueProviderResult.FirstValue; object?model; if (string.IsNullOrWhiteSpace(value)) { // Parse() method trims the value (with common NumberStyles) then throws if the result is empty. model = null; } else if (type == typeof(decimal)) { model = decimal.Parse(value, _supportedStyles, valueProviderResult.Culture); } else { // unreachable throw new NotSupportedException(); } // When converting value, a null model may indicate a failed conversion for an otherwise required // model (can't set a ValueType to null). This detects if a null model value is acceptable given the // current bindingContext. If not, an error is logged. if (model == null && !metadata.IsReferenceOrNullableType) { modelState.TryAddModelError( modelName, metadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor( valueProviderResult.ToString())); } else { bindingContext.Result = ModelBindingResult.Success(model); } } catch (Exception exception) { var isFormatException = exception is FormatException; if (!isFormatException && exception.InnerException != null) { // Unlike TypeConverters, floating point types do not seem to wrap FormatExceptions. Preserve // this code in case a cursory review of the CoreFx code missed something. exception = ExceptionDispatchInfo.Capture(exception.InnerException).SourceException; } modelState.TryAddModelError(modelName, exception, metadata); // Conversion failed. } _logger.DoneAttemptingToBindModel(bindingContext); return(Task.CompletedTask); }