/// <summary> /// Deserialize the request body to a model /// </summary> /// <param name="mediaRange">Content type to deserialize</param> /// <param name="bodyStream">Request body stream</param> /// <param name="context">Current context</param> /// <returns>Model instance</returns> public object Deserialize(MediaRange mediaRange, Stream bodyStream, BindingContext context) { if (bodyStream.CanSeek) { bodyStream.Position = 0; } var deserializedObject = this.serializer.Deserialize(new StreamReader(bodyStream), context.DestinationType); var properties = context.DestinationType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => new BindingMemberInfo(p)); var fields = context.DestinationType.GetFields(BindingFlags.Public | BindingFlags.Instance) .Select(f => new BindingMemberInfo(f)); if (properties.Concat(fields).Except(context.ValidModelBindingMembers).Any()) { return CreateObjectWithBlacklistExcluded(context, deserializedObject); } return deserializedObject; }
public void when_deserializing() { // Given JsonConvert.DefaultSettings = JsonApiSerializerFixture.GetJsonSerializerSettings; var guid = Guid.NewGuid(); string source = string.Format("{{\"someString\":\"some string value\",\"someGuid\":\"{0}\"}}", guid); var context = new BindingContext { DestinationType = typeof (TestData), ValidModelBindingMembers = typeof (TestData).GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(p => new BindingMemberInfo(p)), }; // When object actual; using (var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(source))) { IBodyDeserializer sut = new JsonApiBodyDeserializer(); actual = sut.Deserialize("application/vnd.api+json", bodyStream, context); } // Then var actualData = Assert.IsType<TestData>(actual); Assert.Equal("some string value", actualData.SomeString); Assert.Equal(guid, actualData.SomeGuid); }
public void when_deserializing_with_blacklisted_property() { // Given var guid = Guid.NewGuid(); string source = string.Format("{{\"SomeString\":\"some string value\",\"SomeGuid\":\"{0}\"}}", guid); var context = new BindingContext { DestinationType = typeof(TestData), ValidModelBindingMembers = typeof(TestData).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(propertyInfo => propertyInfo.Name != "SomeString").Select(p => new BindingMemberInfo(p)) }; // When object actual; using (var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(source))) { IBodyDeserializer jilBodyDeserializer = new JilBodyDeserializer(); actual = jilBodyDeserializer.Deserialize("application/json", bodyStream, context); } // Then Assert.IsInstanceOfType(actual, typeof(TestData)); var actualData = actual as TestData; Assert.IsNotNull(actualData); Assert.IsNull(actualData.SomeString); Assert.AreEqual(guid, actualData.SomeGuid); }
public object Deserialize(string contentType, System.IO.Stream bodyStream, BindingContext context) { object result = null; try { var settings = new JsonSerializerSettings(); settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); settings.Converters.Add(new StringEnumConverter()); settings.Converters.Add (new IsoDateTimeConverter() { DateTimeStyles = System.Globalization.DateTimeStyles.AssumeLocal }); var serializer = JsonSerializer.Create(settings); bodyStream.Position = 0; string bodyText; using (var bodyReader = new StreamReader(bodyStream)) { bodyText = bodyReader.ReadToEnd(); } result = serializer.Deserialize(new StringReader(bodyText), context.DestinationType); } catch(Exception ex) { Console.WriteLine(ex); } return result; }
/// <summary> /// Deserialize the request body to a model /// </summary> /// <param name="contentType">Content type to deserialize</param><param name="bodyStream">Request body stream</param><param name="context">Current <see cref="T:Nancy.ModelBinding.BindingContext"/>.</param> /// <returns> /// Model instance /// </returns> public object Deserialize(string contentType, Stream bodyStream, BindingContext context) { object deserializedObject; using (var inputStream = new StreamReader(bodyStream)) { // deserialize json deserializedObject = JSON.Deserialize(inputStream, context.DestinationType, Options); // .. then, due to NancyFx's support for blacklisted properties, we need to get the propertyInfo first (read from cache if possible) var comparisonType = GetTypeForBlacklistComparison(context.DestinationType); BindingMemberInfo[] bindingMemberInfo; if (CachedBindingMemberInfo.TryGetValue(comparisonType, out bindingMemberInfo) == false) { bindingMemberInfo = comparisonType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(p => new BindingMemberInfo(p)).ToArray(); // the following is somewhat dirty but oh well SpinWait.SpinUntil(() => CachedBindingMemberInfo.ContainsKey(comparisonType) || CachedBindingMemberInfo.TryAdd(comparisonType, bindingMemberInfo)); } // ... and then compare whether there's anything blacklisted if (bindingMemberInfo.Except(context.ValidModelBindingMembers).Any()) { // .. if so, take object and basically eradicated value(s) for the blacklisted properties. // this is inspired by https://raw.githubusercontent.com/NancyFx/Nancy.Serialization.JsonNet/master/src/Nancy.Serialization.JsonNet/JsonNetBodyDeserializer.cs // but again.. only *inspired*. // The main difference is, that the instance Jil returned from the JSON.Deserialize() call will be wiped clean, no second/new instance will be created. return CleanBlacklistedMembers(context, deserializedObject, bindingMemberInfo); } return deserializedObject; } }
public void when_deserializing_while_the_body_stream_was_not_at_position_zero() { // Repro of https://github.com/NancyFx/Nancy.Serialization.JsonNet/issues/22 // Given JsonConvert.DefaultSettings = JsonNetSerializerFixture.GetJsonSerializerSettings; var guid = Guid.NewGuid(); string source = string.Format("{{\"someString\":\"some string value\",\"someGuid\":\"{0}\"}}", guid); var context = new BindingContext { DestinationType = typeof(TestData), ValidModelBindingMembers = typeof(TestData).GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(p => new BindingMemberInfo(p)), }; // When object actual; using (var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(source))) { IBodyDeserializer sut = new JsonNetBodyDeserializer(); bodyStream.Position = 1; actual = sut.Deserialize("application/json", bodyStream, context); } // Then var actualData = Assert.IsType<TestData>(actual); Assert.Equal("some string value", actualData.SomeString); Assert.Equal(guid, actualData.SomeGuid); }
private object CreateCollectionInstance(BindingContext context, List<object> items) { Type destinationType = context.DestinationType; if (destinationType.IsList()) { IList list = (IList)Activator.CreateInstance(destinationType); foreach (var item in items) list.Add(item); return list; } if (destinationType.IsArray) { var array = Array.CreateInstance(destinationType.GetElementType(), items.Count); for (int i = 0; i < items.Count; i++) array.SetValue(items[i], i); return array; } return null; }
public void when_binding_to_a_collection_with_blacklisted_property() { // Given var guid = Guid.NewGuid(); string source = string.Format("{{\"SomeString\":\"some string value\",\"SomeGuid\":\"{0}\"}}", guid); var context = new BindingContext { DestinationType = typeof(Stuff), ValidModelBindingMembers = typeof(Stuff).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(propertyInfo => propertyInfo.Name != "SomeString").Select(p => new BindingMemberInfo(p)), }; // Given var module = new ConfigurableNancyModule(c => c.Post("/stuff", (_, m) => { var stuff = m.Bind<List<Stuff>>("SomeString"); return stuff.ToJSON(); })); var bootstrapper = new TestBootstrapper(config => config.Module(module)); // When var browser = new Browser(bootstrapper); var result = browser.Post("/stuff", with => { with.HttpRequest(); with.JsonBody(new List<Stuff> { new Stuff(1, "one"), new Stuff(2, "two") }, new JilSerializer()); }); // Then Assert.AreEqual("[{\"Id\":1,\"SomeString\":null},{\"Id\":2,\"SomeString\":null}]", result.Body.AsString()); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public CollectionConverterFixture() { this.converter = new CollectionConverter(); this.context = new BindingContext() { TypeConverters = new[] { new FallbackConverter() } }; this.mockStringTypeConverter = A.Fake<ITypeConverter>(); A.CallTo(() => mockStringTypeConverter.CanConvertTo(null, null)).WithAnyArguments().Returns(true); A.CallTo(() => mockStringTypeConverter.Convert(null, null, null)).WithAnyArguments().Returns(string.Empty); }
public void Collection_type_conversion_should_use_type_converter() { const string input = "one,two,three"; var mockContext = new BindingContext() { TypeConverters = new[] { this.mockStringTypeConverter } }; converter.Convert(input, typeof(List<string>), mockContext); A.CallTo(() => this.mockStringTypeConverter.Convert(null, null, null)).WithAnyArguments() .MustHaveHappened(Repeated.Exactly.Times(3)); }
/// <summary> /// Deserialize the request body to a model /// </summary> /// <param name="contentType">Content type to deserialize</param> /// <param name="bodyStream">Request body stream</param> /// <param name="context">Current context</param> /// <returns>Model instance</returns> public object Deserialize(string contentType, Stream bodyStream, BindingContext context) { var deserializedObject = JsonSerializer.DeserializeFromStream(context.DestinationType, bodyStream); if (context.DestinationType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Except(context.ValidModelProperties).Any()) { return this.CreateObjectWithBlacklistExcluded(context, deserializedObject); } return deserializedObject; }
private object CreateObjectWithBlacklistExcluded(BindingContext context, object deserializedObject) { var returnObject = Activator.CreateInstance(context.DestinationType); foreach (var property in context.ValidModelProperties) { this.CopyPropertyValue(property, deserializedObject, returnObject); } return returnObject; }
private object BuildInstance(BindingContext context, string[] lines) { if (lines.Length > 1) { string[] fieldNames = lines[0].Split(','); string[] fieldValues = lines[1].Split(','); return CreateInstance(fieldNames, fieldValues, context.DestinationType, context); } return null; }
public bool CanDeserialize(string contentType, BindingContext context) { if (String.IsNullOrEmpty(contentType)) { return false; } var contentMimeType = contentType.Split(';')[0]; return contentMimeType.Equals("application/csv", StringComparison.InvariantCultureIgnoreCase) || contentMimeType.Equals("text/csv", StringComparison.InvariantCultureIgnoreCase) || (contentMimeType.StartsWith("application/vnd", StringComparison.InvariantCultureIgnoreCase) && contentMimeType.EndsWith("+csv", StringComparison.InvariantCultureIgnoreCase)); }
private static object ConvertCollection(object items, Type destinationType, BindingContext context) { var returnCollection = Activator.CreateInstance(destinationType); var collectionAddMethod = destinationType.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance); foreach (var item in (IEnumerable)items) { collectionAddMethod.Invoke(returnCollection, new[] { item }); } return returnCollection; }
public DefaultBinderFixture() { this.defaultBindingContext = new BindingContext(); this.passthroughNameConverter = A.Fake<IFieldNameConverter>(); A.CallTo(() => this.passthroughNameConverter.Convert(null)).WithAnyArguments() .ReturnsLazily(f => (string)f.Arguments[0]); this.emptyDefaults = A.Fake<BindingDefaults>(); A.CallTo(() => this.emptyDefaults.DefaultBodyDeserializers).Returns(new IBodyDeserializer[] { }); A.CallTo(() => this.emptyDefaults.DefaultTypeConverters).Returns(new ITypeConverter[] { }); this.serializer = new JavaScriptSerializer(); this.serializer.RegisterConverters(JsonSettings.Converters); }
private static object CreateObjectWithBlacklistExcluded(BindingContext context, object deserializedObject) { var returnObject = Activator.CreateInstance(context.DestinationType); if (context.DestinationType.IsCollection()) { return ConvertCollection(deserializedObject, context.DestinationType, context); } foreach (var property in context.ValidModelProperties) { CopyPropertyValue(property, deserializedObject, returnObject); } return returnObject; }
public object Deserialize(string contentType, Stream bodyStream, BindingContext context) { Type destinationType = context.DestinationType; if (!IsValidDestinationType(destinationType)) return null; object model = null; string[] lines = bodyStream.AsString().FixLineEndings().Split('\n'); if (destinationType.IsList() || destinationType.IsArray) model = BuildCollection(context, lines); else model = BuildInstance(context, lines); if (model != null) context.Configuration.BodyOnly = true; return model; }
private object BuildCollection(BindingContext context, string[] lines) { var items = new List<object>(); if (lines.Length > 1) { string[] fieldNames = lines[0].Split(','); foreach (var line in lines.Skip(1).Where(l => l.Length > 0)) { string[] fieldValues = line.Split(','); object instance = CreateInstance(fieldNames, fieldValues, context.GenericType, context); items.Add(instance); } } var list = CreateCollectionInstance(context, items); return list; }
/// <summary> /// Deserialize the request body to a model /// </summary> /// <param name="contentType">Content type to deserialize</param> /// <param name="bodyStream">Request body stream</param> /// <param name="context">Current context</param> /// <returns>Model instance</returns> public object Deserialize(string contentType, Stream bodyStream, BindingContext context) { var deserializedObject = JsonSerializer.DeserializeFromStream(context.DestinationType, bodyStream); if (deserializedObject == null) { return null; } var properties = context.DestinationType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => new BindingMemberInfo(p)); var fields = context.DestinationType.GetFields(BindingFlags.Public | BindingFlags.Instance) .Select(p => new BindingMemberInfo(p)); if (properties.Concat(fields).Except(context.ValidModelBindingMembers).Any()) { return this.CreateObjectWithBlacklistExcluded(context, deserializedObject); } return deserializedObject; }
private static void UpdateModelWithDeserializedModel(object bodyDeserializedModel, BindingContext bindingContext) { if (bodyDeserializedModel.GetType().IsCollection() || bodyDeserializedModel.GetType().IsEnumerable() || bodyDeserializedModel.GetType().IsArray()) { var count = 0; foreach (var o in (IEnumerable)bodyDeserializedModel) { var model = (IList)bindingContext.Model; //if the instance specified in the binder contains the n-th element use that otherwise make a new one. object genericTypeInstance; if (model.Count > count) { genericTypeInstance = model[count]; } else { genericTypeInstance = Activator.CreateInstance(bindingContext.GenericType); model.Add(genericTypeInstance); } foreach (var modelProperty in bindingContext.ValidModelProperties) { var existingValue = modelProperty.GetValue(genericTypeInstance, null); if (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite) { CopyValue(modelProperty, o, genericTypeInstance); } } count++; } } else { foreach (var modelProperty in bindingContext.ValidModelProperties) { var existingValue = modelProperty.GetValue(bindingContext.Model, null); if (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite) { CopyValue(modelProperty, bodyDeserializedModel, bindingContext.Model); } } } }
private static string GetValue(string propertyName, BindingContext context, int index = -1) { if (index != -1) { if (context.RequestData.ContainsKey(propertyName + '_' + index)) { return context.RequestData[propertyName + '_' + index]; } if (context.RequestData.ContainsKey(propertyName + '[' + index + ']')) { return context.RequestData[propertyName + '[' + index + ']']; } return String.Empty; } return context.RequestData.ContainsKey(propertyName) ? context.RequestData[propertyName] : String.Empty; }
private static void BindProperty(PropertyInfo modelProperty, string stringValue, BindingContext context, object genericInstance) { var destinationType = modelProperty.PropertyType; var typeConverter = context.TypeConverters.FirstOrDefault(c => c.CanConvertTo(destinationType, context)); if (typeConverter != null) { try { SetPropertyValue(modelProperty, genericInstance, typeConverter.Convert(stringValue, destinationType, context)); } catch (Exception e) { throw new PropertyBindingException(modelProperty.Name, stringValue, e); } } else if (destinationType == typeof(string)) { SetPropertyValue(modelProperty, context.Model, stringValue); } }
private bool BindingValueIsValid(string bindingValue, object existingValue, BindingMemberInfo modelProperty, BindingContext bindingContext) { return(!string.IsNullOrEmpty(bindingValue) && (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite)); }
private static void UpdateModelWithDeserializedModel(object bodyDeserializedModel, BindingContext bindingContext) { var bodyDeserializedModelType = bodyDeserializedModel.GetType(); if (bodyDeserializedModelType.GetTypeInfo().IsValueType) { bindingContext.Model = bodyDeserializedModel; return; } if (bodyDeserializedModelType.IsCollection() || bodyDeserializedModelType.IsEnumerable() || bodyDeserializedModelType.IsArray()) { var count = 0; foreach (var o in (IEnumerable)bodyDeserializedModel) { var model = (IList)bindingContext.Model; if (o.GetType().GetTypeInfo().IsValueType || o is string) { HandleValueTypeCollectionElement(model, count, o); } else { HandleReferenceTypeCollectionElement(bindingContext, model, count, o); } count++; } } else { foreach (var modelProperty in bindingContext.ValidModelBindingMembers) { var existingValue = modelProperty.GetValue(bindingContext.Model); if (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite) { CopyValue(modelProperty, bodyDeserializedModel, bindingContext.Model); } } } }
/// <summary> /// Whether the deserializer can deserialize the content type /// </summary> /// <param name="contentType">Content type to deserialize</param> /// <param name="context">Current <see cref="BindingContext"/>.</param> /// <returns>True if supported, false otherwise</returns> public bool CanDeserialize(string contentType, BindingContext context) { return Helpers.IsJsonType(contentType); }
private static string GetValue(string propertyName, BindingContext context, int index = -1) { if (index != -1) { var indexindexes = context.RequestData.Keys.Select(IsMatch) .Where(i => i != -1) .OrderBy(i => i) .Distinct() .Select((k, i) => new KeyValuePair<int, int>(i, k)) .ToDictionary(k => k.Key, v => v.Value); if (indexindexes.ContainsKey(index)) { var propertyValue = context.RequestData.Where(c => { var indexId = IsMatch(c.Key); return c.Key.StartsWith(propertyName, StringComparison.OrdinalIgnoreCase) && indexId != -1 && indexId == indexindexes[index]; }) .Select(k => k.Value) .FirstOrDefault(); return propertyValue ?? string.Empty; } return string.Empty; } return context.RequestData.ContainsKey(propertyName) ? context.RequestData[propertyName] : string.Empty; }
private static void BindValue(BindingMemberInfo modelProperty, string stringValue, BindingContext context) { BindValue(modelProperty, stringValue, context, context.Model); }
private static void HandleReferenceTypeCollectionElement(BindingContext bindingContext, IList model, int count, object o) { // If the instance specified in the binder contains the n-th element use that otherwise make a new one. object genericTypeInstance; if (model.Count > count) { genericTypeInstance = model[count]; } else { genericTypeInstance = Activator.CreateInstance(bindingContext.GenericType); model.Add(genericTypeInstance); } foreach (var modelProperty in bindingContext.ValidModelBindingMembers) { var existingValue = modelProperty.GetValue(genericTypeInstance); if (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite) { CopyValue(modelProperty, o, genericTypeInstance); } } }
private static void UpdateModelWithDeserializedModel(object bodyDeserializedModel, BindingContext bindingContext) { var bodyDeserializedModelType = bodyDeserializedModel.GetType(); if (bodyDeserializedModelType.IsValueType) { bindingContext.Model = bodyDeserializedModel; return; } if (bodyDeserializedModelType.IsCollection() || bodyDeserializedModelType.IsEnumerable() || bodyDeserializedModelType.IsArray()) { var count = 0; foreach (var o in (IEnumerable)bodyDeserializedModel) { var model = (IList)bindingContext.Model; if (o.GetType().IsValueType || o.GetType() == typeof(string)) { HandleValueTypeCollectionElement(model, count, o); } else { HandleReferenceTypeCollectionElement(bindingContext, model, count, o); } count++; } } else { foreach (var modelProperty in bindingContext.ValidModelBindingMembers) { var existingValue = modelProperty.GetValue(bindingContext.Model); if (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite) { CopyValue(modelProperty, bodyDeserializedModel, bindingContext.Model); } } } }
private string GetValue(string propertyName, BindingContext context) { return(context.RequestData.ContainsKey(propertyName) ? context.RequestData[propertyName] : String.Empty); }
private static void BindValue(BindingMemberInfo modelProperty, string stringValue, BindingContext context, object targetInstance) { var destinationType = modelProperty.PropertyType; var typeConverter = context.TypeConverters.FirstOrDefault(c => c.CanConvertTo(destinationType, context)); if (typeConverter != null) { try { SetBindingMemberValue(modelProperty, targetInstance, typeConverter.Convert(stringValue, destinationType, context)); } catch (Exception e) { throw new PropertyBindingException(modelProperty.Name, stringValue, e); } } else if (destinationType == typeof(string)) { SetBindingMemberValue(modelProperty, targetInstance, stringValue); } }
private bool BindingValueIsValid(string bindingValue, object existingValue, PropertyInfo modelProperty, BindingContext bindingContext) { return (!String.IsNullOrEmpty(bindingValue) && (IsDefaultValue(existingValue, modelProperty.PropertyType) || bindingContext.Configuration.Overwrite)); }
private static void BindProperty(PropertyInfo modelProperty, string stringValue, BindingContext context) { var destinationType = modelProperty.PropertyType; var typeConverter = context.TypeConverters.FirstOrDefault(c => c.CanConvertTo(destinationType, context)); if (typeConverter != null) { try { SetPropertyValue(modelProperty, context.Model, typeConverter.Convert(stringValue, destinationType, context)); } catch (Exception e) { throw new PropertyBindingException(modelProperty.Name, stringValue, e); } } else if (destinationType == typeof(string)) { SetPropertyValue(modelProperty, context.Model, stringValue); } }
private object DeserializeRequestBody(BindingContext context) { if (context.Context == null || context.Context.Request == null) { return null; } var contentType = GetRequestContentType(context.Context); var bodyDeserializer = this.bodyDeserializers.FirstOrDefault(b => b.CanDeserialize(contentType)); if (bodyDeserializer != null) { return bodyDeserializer.Deserialize(contentType, context.Context.Request.Body, context); } bodyDeserializer = this.defaults.DefaultBodyDeserializers.FirstOrDefault(b => b.CanDeserialize(contentType)); return bodyDeserializer != null ? bodyDeserializer.Deserialize(contentType, context.Context.Request.Body, context) : null; }