/// <summary> /// Check for simple binding parameters in POST data. Bind POST /// data as well as query string data /// </summary> /// <param name="metadataProvider"></param> /// <param name="actionContext"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { string stringValue = null; NameValueCollection col = TryReadBody(actionContext.Request); if (col != null) stringValue = col[Descriptor.ParameterName]; // try reading query string if we have no POST/PUT match if (stringValue == null) { var query = actionContext.Request.GetQueryNameValuePairs(); if (query != null) { var matches = query.Where(kv => kv.Key.ToLower() == Descriptor.ParameterName.ToLower()); var keyValuePairs = matches as IList<KeyValuePair<string, string>> ?? matches.ToList(); if (keyValuePairs.Any()) stringValue = keyValuePairs.First().Value; } } object value = StringToType(stringValue); // Set the binding result here SetValue(actionContext, value); // now, we can return a completed task with no result TaskCompletionSource<AsyncVoid> tcs = new TaskCompletionSource<AsyncVoid>(); tcs.SetResult(default(AsyncVoid)); return tcs.Task; }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var binding = actionContext.ActionDescriptor.ActionBinding; if (actionContext.Request.Method == HttpMethod.Get || binding.ParameterBindings.Count(b => b.Descriptor.ParameterBinderAttribute is NakedBodyAttribute) > 1) return EmptyTask.Start(); var type = binding.ParameterBindings[0].Descriptor.ParameterType; if (type == typeof(string)) { return actionContext.Request.Content .ReadAsStringAsync() .ContinueWith(task => { var stringResult = task.Result; SetValue(actionContext, stringResult); }, cancellationToken); } if (type == typeof(byte[])) { return actionContext.Request.Content .ReadAsByteArrayAsync() .ContinueWith(task => { byte[] result = task.Result; SetValue(actionContext, result); }, cancellationToken); } throw new InvalidOperationException("Only string and byte[] are supported for [NakedBody] parameters"); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { //TODO: VALIDATION & ERROR CHECKS string idsAsString = actionContext.Request.GetRouteData().Values["ids"].ToString(); idsAsString = idsAsString.Trim('[', ']'); IEnumerable<string> ids = idsAsString.Split(','); ids = ids.Where(str => !string.IsNullOrEmpty(str)); IEnumerable<int> idList = ids.Select(strId => { if (string.IsNullOrEmpty(strId)) return -1; return Convert.ToInt32(strId); }).ToArray(); SetValue(actionContext, idList); TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); tcs.SetResult(null); return tcs.Task; }
public bool Validate(object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, string keyPrefix) { if (type == null) { throw new ArgumentNullException("type"); } if (metadataProvider == null) { throw new ArgumentNullException("metadataProvider"); } if (actionContext == null) { throw new ArgumentNullException("actionContext"); } if (model != null && MediaTypeFormatterCollection.IsTypeExcludedFromValidation(model.GetType())) { // no validation for some DOM like types return true; } ModelValidatorProvider[] validatorProviders = actionContext.GetValidatorProviders().ToArray(); // Optimization : avoid validating the object graph if there are no validator providers if (validatorProviders == null || validatorProviders.Length == 0) { return true; } ModelMetadata metadata = metadataProvider.GetMetadataForType(() => model, type); ValidationContext validationContext = new ValidationContext { MetadataProvider = metadataProvider, ActionContext = actionContext, ModelState = actionContext.ModelState, Visited = new HashSet<object>(), KeyBuilders = new Stack<IKeyBuilder>(), RootPrefix = keyPrefix }; return this.ValidateNodeAndChildren(metadata, validationContext, container: null); }
private ModelBindingContext GetModelBindingContext(ModelMetadataProvider metadataProvider, HttpActionContext actionContext) { string name = Descriptor.ParameterName; Type type = Descriptor.ParameterType; string prefix = Descriptor.Prefix; IValueProvider vp = CreateValueProvider(this._valueProviderFactories, actionContext); if (_metadataCache == null) { Interlocked.Exchange(ref _metadataCache, metadataProvider.GetMetadataForType(null, type)); } ModelBindingContext ctx = new ModelBindingContext() { ModelName = prefix ?? name, FallbackToEmptyPrefix = prefix == null, // only fall back if prefix not specified ModelMetadata = _metadataCache, ModelState = actionContext.ModelState, ValueProvider = vp }; if (_validationNodeCache == null) { Interlocked.Exchange(ref _validationNodeCache, ctx.ValidationNode); } else { ctx.ValidationNode = _validationNodeCache; } return ctx; }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { EntityTagHeaderValue etagHeader = null; switch (this._match) { case ETagMatch.IfNoneMatch: etagHeader = actionContext.Request.Headers.IfNoneMatch.FirstOrDefault(); break; case ETagMatch.IfMatch: etagHeader = actionContext.Request.Headers.IfMatch.FirstOrDefault(); break; } ETag etag = null; if (etagHeader != null) { etag = new ETag { Tag = etagHeader.Tag }; } actionContext.ActionArguments[this.Descriptor.ParameterName] = etag; var tsc = new TaskCompletionSource<object>(); tsc.SetResult(null); return tsc.Task; }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var log = NLog.LogManager.GetCurrentClassLogger(); log.Info("ExecuteBindingAsync"); var binding = actionContext.ActionDescriptor.ActionBinding; if (actionContext.Request.GetClientIpAddress() != "195.149.229.109" && actionContext.Request.IsLocal() == false) { log.Info("Invalid IP - Expecting 195.149.229.109, got: {0}", actionContext.Request.Headers.Host); throw new InvalidOperationException("Invalid IP."); } var type = binding.ParameterBindings[0].Descriptor.ParameterType; if (type != typeof(TransferujPlResponse)) { log.Info("Invalid parameter type. Expecting TransferujPlResponse"); throw new InvalidOperationException(); } return actionContext.Request.Content .ReadAsStringAsync() .ContinueWith((task) => { var stringResult = task.Result; log.Debug("Detailed info: {0}", stringResult); SetValue(actionContext, TransferujPlResponse.FromNameValueCollection( stringResult.ToNameValueCollection())); }); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { return _traceWriter.TraceBeginEndAsync( actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info, _innerBinding.GetType().Name, ExecuteBindingAsyncMethodName, beginTrace: (tr) => { tr.Message = Error.Format(SRResources.TraceBeginParameterBind, _innerBinding.Descriptor.ParameterName); }, execute: () => _innerBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken), endTrace: (tr) => { string parameterName = _innerBinding.Descriptor.ParameterName; tr.Message = actionContext.ActionArguments.ContainsKey(parameterName) ? Error.Format(SRResources.TraceEndParameterBind, parameterName, FormattingUtilities.ValueToString(actionContext.ActionArguments[parameterName], CultureInfo.CurrentCulture)) : Error.Format(SRResources.TraceEndParameterBindNoBind, parameterName); }, errorTrace: null); }
/// <summary> /// Asynchronously executes the binding for the given request. /// </summary> /// <returns>A task object representing the asynchronous operation.</returns> /// <param name="metadataProvider">Metadata provider to use for validation.</param> /// <param name="actionContext"> /// The action context for the binding. The action context contains the parameter /// dictionary that will get populated with the parameter. /// </param> /// <param name="cancellationToken">Cancellation token for cancelling the binding operation.</param> public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var request = actionContext.Request; if (request.Method == HttpMethod.Get) { SetValue(actionContext, null); return; } var type = Descriptor.ParameterType; if (type == typeof(Stream)) { var streamResult = await request.Content.ReadAsStreamAsync(); SetValue(actionContext, streamResult); return; } if (type == typeof(byte[])) { var byteArrayResult = await request.Content.ReadAsByteArrayAsync(); SetValue(actionContext, byteArrayResult); return; } throw new InvalidOperationException("Only byte[] and Stream are supported for [NakedBody] parameters"); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { string name = Descriptor.ParameterName; Type type = Descriptor.ParameterType; string prefix = Descriptor.Prefix; IValueProvider vp = CreateValueProvider(this._valueProviderFactories, actionContext); ModelBindingContext ctx = new ModelBindingContext() { ModelName = prefix ?? name, FallbackToEmptyPrefix = prefix == null, // only fall back if prefix not specified ModelMetadata = metadataProvider.GetMetadataForType(null, type), ModelState = actionContext.ModelState, ValueProvider = vp }; IModelBinder binder = this._modelBinderProvider.GetBinder(actionContext, ctx); bool haveResult = binder.BindModel(actionContext, ctx); object model = haveResult ? ctx.Model : Descriptor.DefaultValue; actionContext.ActionArguments.Add(name, model); return TaskHelpers.Completed(); }
public override Threading.Tasks.Task ExecuteBindingAsync( Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, Threading.CancellationToken cancellationToken ) { throw new NotImplementedException(); }
// Execute the binding for the given request. // On success, this will add the parameter to the actionContext.ActionArguments dictionary. // Caller ensures IsError==false. public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { string name = Descriptor.ParameterName; HttpRequestMessage request = actionContext.ControllerContext.Request; actionContext.ActionArguments.Add(name, request); return TaskHelpers.Completed(); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { string name = Descriptor.ParameterName; IPrincipal principal = Thread.CurrentPrincipal; actionContext.ActionArguments.Add(name, principal); return TaskHelpers.Completed(); }
public override Task ExecuteBindingAsync(System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var paramFromBody = Descriptor; var type = paramFromBody.ParameterType; var request = actionContext.ControllerContext.Request; var formatterLogger = new ModelStateFormatterLogger(actionContext.ModelState, paramFromBody.ParameterName); return(ExecuteBindingAsyncCore(metadataProvider, actionContext, paramFromBody, type, request, formatterLogger, cancellationToken)); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { if (actionContext.ControllerContext.Configuration.DependencyResolver != null) { var resolved = actionContext.Request.GetDependencyScope().GetService(Descriptor.ParameterType); actionContext.ActionArguments[Descriptor.ParameterName] = resolved; } return Task.FromResult(0); }
internal ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName, EfficientTypePropertyKey<Type, string> cacheKey) : this(provider, containerType, modelAccessor, modelType, propertyName) { if (cacheKey == null) { throw Error.ArgumentNull("cacheKey"); } _cacheKey = cacheKey; }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { ModelBindingContext ctx = GetModelBindingContext(metadataProvider, actionContext); bool haveResult = _binder.BindModel(actionContext, ctx); object model = haveResult ? ctx.Model : Descriptor.DefaultValue; SetValue(actionContext, model); return TaskHelpers.Completed(); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { // Set the binding result here SetValue(actionContext, new GenericPrincipal(new GenericIdentity("MyIdentity"), new string[]{"myrole"})); // now, we can return a completed task with no result TaskCompletionSource<AsyncVoid> tcs = new TaskCompletionSource<AsyncVoid>(); tcs.SetResult(default(AsyncVoid)); return tcs.Task; }
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { NameValueCollection col = await ReadBodyAsync(actionContext.Request); if (col == null) { throw new HttpResponseException(HttpStatusCode.BadRequest); } // Set the binding result here SetValue(actionContext, col[Descriptor.ParameterName]); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var binding = actionContext.ActionDescriptor.ActionBinding; var parameterBinding = binding.ParameterBindings.FirstOrDefault(b => b.Descriptor.ParameterBinderAttribute is UserAgentAttribute); if (parameterBinding == null || parameterBinding.Descriptor.ParameterType != typeof(string)) return Task.FromResult(0); SetValue(actionContext, actionContext.Request.Headers.UserAgent.ToString()); return Task.FromResult(0); }
public override Task ExecuteBindingAsync( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var paramFromBody = Descriptor; var type = paramFromBody.ParameterType; var request = actionContext.ControllerContext.Request; var formatterLogger = new ModelStateFormatterLogger(actionContext.ModelState, paramFromBody.ParameterName); return ExecuteBindingAsyncCore(metadataProvider, actionContext, paramFromBody, type, request, formatterLogger, cancellationToken); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { IEnumerable<string> values; if (actionContext.Request.Headers.TryGetValues(this.name, out values)) { actionContext.ActionArguments[this.Descriptor.ParameterName] = values.FirstOrDefault(); } var taskSource = new TaskCompletionSource<object>(); taskSource.SetResult(null); return taskSource.Task; }
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { if (actionContext.Request.Method == HttpMethod.Get || actionContext.Request.Method == HttpMethod.Delete) { await BindFromUri(metadataProvider, actionContext, cancellationToken); } else { await BindFromBody(metadataProvider, actionContext, cancellationToken); } }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { List<MediaTypeFormatter> perRequestFormatters = new List<MediaTypeFormatter>(); foreach (MediaTypeFormatter formatter in _formatters) { MediaTypeFormatter perRequestFormatter = formatter.GetPerRequestFormatterInstance(Descriptor.ParameterType, actionContext.Request, actionContext.Request.Content.Headers.ContentType); perRequestFormatters.Add(perRequestFormatter); } return Descriptor.BindWithFormatter(perRequestFormatters).ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken); }
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { ScimQueryOptions queryOptions; if (actionContext.Request.Method == HttpMethod.Get) queryOptions = actionContext.Request.GetOwinContext().Request.Query.GetScimQueryOptions(_ServerConfiguration); else if (actionContext.Request.Method == HttpMethod.Post) queryOptions = await actionContext.Request.Content.ReadAsAsync<ScimQueryOptions>(cancellationToken); else throw new InvalidOperationException("You can only bind ScimQueryOptions on GET or POST query endpoints."); SetValue(actionContext, queryOptions); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { if (actionContext.Request.Content != null && actionContext.Request.Content.Headers.ContentLength > 0) { // we have something from the body, try that first return _defaultFormatterBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken); } else { // we need to read things from uri return _defaultUriBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken); } }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var binding = actionContext.ActionDescriptor.ActionBinding; var parameterBinding = binding.ParameterBindings.FirstOrDefault(b => b.Descriptor.ParameterBinderAttribute is QueryStringParametersAttribute); if (parameterBinding == null || !(typeof(IDictionary<string, string>).IsAssignableFrom(parameterBinding.Descriptor.ParameterType))) return Task.FromResult(0); var parameters = new Dictionary<string, string>(); parameters.AddRange(actionContext.Request.GetQueryNameValuePairs().Where(kvp => !kvp.Key.Equals("access_token", StringComparison.OrdinalIgnoreCase))); SetValue(actionContext, parameters); return Task.FromResult(0); }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { // read the query and construct the object myself TestItemRenameProperty property = new TestItemRenameProperty { Name = actionContext.Request.RequestUri.ParseQueryString()["$Name"] }; // Set the binding result here SetValue(actionContext, property); // now, we can return a completed task with no result TaskCompletionSource<AsyncVoid> tcs = new TaskCompletionSource<AsyncVoid>(); tcs.SetResult(default(AsyncVoid)); return tcs.Task; }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var perRequestFormatters = new List<MediaTypeFormatter>(); foreach (MediaTypeFormatter formatter in _formatters) { MediaTypeFormatter perRequestFormatter = formatter.GetPerRequestFormatterInstance(Descriptor.ParameterType, actionContext.Request, actionContext.Request.Content.Headers.ContentType); perRequestFormatters.Add(perRequestFormatter); } HttpParameterBinding innerBinding = CreateInnerBinding(perRequestFormatters); Contract.Assert(innerBinding != null); return innerBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken); }
/// <summary> /// Parses the parameter value from the request body. /// </summary> /// <param name="metadataProvider"></param> /// <param name="actionContext"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { // read request body (query string or JSON) into name/value pairs NameValueCollection parameters = ParseParametersFromBody(actionContext.Request); // try to get parameter value from parsed body string stringValue = null; if (parameters != null) stringValue = parameters[Descriptor.ParameterName]; // if not found in body, try reading query string if (stringValue == null) { var queryStringPairs = actionContext.Request.GetQueryNameValuePairs(); if (queryStringPairs != null) stringValue = queryStringPairs .Where(kv => kv.Key == Descriptor.ParameterName) .Select(kv => kv.Value) .FirstOrDefault(); } // 遍历路由中的参数,将其添加或替换api接口的参数实体类的字段或普通字段 stringValue = ParseParametersFromRoute(stringValue, actionContext.ControllerContext.RouteData.Values, Descriptor.ParameterName); // if found, convert/deserialize the parameter and set the binding if (stringValue != null) { object paramValue; if (Descriptor.ParameterType == typeof(string)) paramValue = stringValue; else if (Descriptor.ParameterType.IsEnum) paramValue = Enum.Parse(Descriptor.ParameterType, stringValue); else if (Descriptor.ParameterType.IsPrimitive || Descriptor.ParameterType.IsValueType) // TODO: Are these conditions ok? I'd rather not have to check that the type implements IConvertible. paramValue = Convert.ChangeType(stringValue, Descriptor.ParameterType); else { var jsonSerializerSettings = actionContext.ControllerContext.Configuration.Formatters.JsonFormatter.SerializerSettings; // when deserializing an object, pass in the global settings so that custom converters, etc. are honored paramValue = JsonConvert.DeserializeObject(stringValue, Descriptor.ParameterType, jsonSerializerSettings); } // Set the binding result here SetValue(actionContext, paramValue); } // now, we can return a completed task with no result TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); tcs.SetResult(default(object)); return tcs.Task; }
private static ModelValidationNode CreateModelValidationNode(object o, ModelMetadataProvider metadataProvider, ModelStateDictionary modelStateDictionary, string modelStateKey) { ModelMetadata metadata = metadataProvider.GetMetadataForType(() => { return o; }, o.GetType()); ModelValidationNode validationNode = new ModelValidationNode(metadata, modelStateKey); // for this root node, recursively add all child nodes HashSet<object> visited = new HashSet<object>(); CreateModelValidationNodeRecursive(o, validationNode, metadataProvider, metadata, modelStateDictionary, modelStateKey, visited); return validationNode; }
/// <summary> /// Executes the binding asynchronous. /// </summary> /// <param name="metadataProvider">The metadata provider.</param> /// <param name="actionContext">The action context.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>System.Threading.Tasks.Task.</returns> public override async Task ExecuteBindingAsync( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { PatchRequestBase model = await CreatePatchRequest(actionContext.Request, Descriptor.Configuration); SetValue(actionContext, model); if (_BodyModelValidator != null) { _BodyModelValidator.Validate(model, Descriptor.ParameterType, metadataProvider, actionContext, Descriptor.ParameterName); } }
/// <summary/> public override Task ExecuteBindingAsync(System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { // throw new NotImplementedException(); //} //public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, // HttpActionContext actionContext, // CancellationToken cancellationToken) //{ var binding = actionContext .ActionDescriptor .ActionBinding; if (binding.ParameterBindings.Length > 1 || actionContext.Request.Method == HttpMethod.Get) { return(EmptyTask.Start()); } var type = binding .ParameterBindings[0] .Descriptor.ParameterType; if (type == typeof(string)) { return(actionContext.Request.Content .ReadAsStringAsync() .ContinueWith((task) => { var stringResult = task.Result; SetValue(actionContext, stringResult); })); } else if (type == typeof(byte[])) { return(actionContext.Request.Content .ReadAsByteArrayAsync() .ContinueWith((task) => { byte[] result = task.Result; SetValue(actionContext, result); })); } throw new InvalidOperationException("Only string and byte[] are supported for [NakedBody] parameters"); }
internal ModelMetadata( ModelMetadataProvider provider, Type containerType, Func <object> modelAccessor, Type modelType, string propertyName, EfficientTypePropertyKey <Type, string> cacheKey ) : this(provider, containerType, modelAccessor, modelType, propertyName) { if (cacheKey == null) { throw Error.ArgumentNull("cacheKey"); } _cacheKey = cacheKey; }
public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func <object> modelAccessor, Type modelType, string propertyName) { if (provider == null) { throw Error.ArgumentNull("provider"); } if (modelType == null) { throw Error.ArgumentNull("modelType"); } Provider = provider; _containerType = containerType; _modelAccessor = modelAccessor; _modelType = modelType; _propertyName = propertyName; }
/* * public Task ExecuteBindingAsync( * ModelMetadataProvider metadataProvider, * HttpActionContext actionContext, * CancellationToken cancellationToken) * { * var paramFromBody = Descriptor; * var type = paramFromBody.ParameterType; * var request = actionContext.ControllerContext.Request; * var formatterLogger = new ModelStateFormatterLogger(actionContext.ModelState, paramFromBody.ParameterName); * return ExecuteBindingAsyncCore(metadataProvider, actionContext, paramFromBody, type, request, formatterLogger, cancellationToken); * } */ // Perf-sensitive - keeping the async method as small as possible. private async Task ExecuteBindingAsyncCore( System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, HttpParameterDescriptor paramFromBody, Type type, HttpRequestMessage request, IFormatterLogger formatterLogger, CancellationToken cancellationToken) { var model = await ReadContentAsync(request, type, Formatters, formatterLogger, cancellationToken); if (model != null) { var routeParams = actionContext.ControllerContext.RouteData.Values; foreach (var key in routeParams.Keys.Where(k => k != "controller")) { var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (prop == null) { continue; } var descriptor = TypeDescriptor.GetConverter(prop.PropertyType); if (descriptor.CanConvertFrom(typeof(string))) { prop.SetValue(model, descriptor.ConvertFromString(routeParams[key] as string)); OnBoundUriKeyToObject(model, key); } } } // Set the merged model in the context. SetValue(actionContext, model); if (BodyModelValidator != null) { BodyModelValidator.Validate(model, type, metadataProvider, actionContext, paramFromBody.ParameterName); } }
public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func <object> modelAccessor, Type modelType, string propertyName) { if (provider == null) { throw Error.ArgumentNull("provider"); } if (modelType == null) { throw Error.ArgumentNull("modelType"); } Provider = provider; _containerType = containerType; _modelAccessor = modelAccessor; _modelType = modelType; _propertyName = propertyName; // If metadata is for a property then containerType != null && propertyName != null // If metadata is for a type then containerType == null && propertyName == null, so we have to use modelType for the cache key. _cacheKey = new EfficientTypePropertyKey <Type, string>(_containerType ?? _modelType, _propertyName); }