public Task <string> SerializeSchema(Type t, HttpDataSerializerOptions options = null) { options = options ?? new HttpDataSerializerOptions(); var schema = GetSchema(t, options, useStringEnums: false, requireReferenceTypes: false); return(Task.FromResult(schema.ToJson(Formatting.Indented))); }
public static JsonSerializerOptions CreateJsonSerializerOptions(HttpDataSerializerOptions options, bool debugMode) { options = options ?? new HttpDataSerializerOptions(); var opts = new JsonSerializerOptions { WriteIndented = debugMode, DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; opts.Converters.Add(new JsonTokenConverterFactory()); if (options.EnumSerializationMethod == EnumSerializationMethod.Object) { opts.Converters.Add(new JsonEnumConverterFactory()); } if (options.EnumSerializationMethod == EnumSerializationMethod.String) { opts.Converters.Add(new JsonStringEnumConverter()); } return(opts); }
public async Task <T> DeserializeResponse <T>(byte[] message, HttpDataSerializerOptions options = null) where T : new() { await Task.CompletedTask; var settings = JsonNetSerializerSettings.CreateJsonSerializerSettings(options, _debugMode); if (message.Length == 0) { throw new CodeWorksSerializationException("Cannot deserialize an empty payload"); } try { using (var ms = new MemoryStream(message)) { using (var reader = new StreamReader(ms, Encoding.UTF8)) { var result = JsonSerializer.Create(settings).Deserialize(reader, typeof(T)); return((T)result); } } } catch (JsonException ex) { var contents = Encoding.UTF8.GetString(message); if (string.IsNullOrWhiteSpace(contents)) { return(new T()); } _logger.LogError(ex, $"Cannot deserialize request payload {contents}"); throw new CodeWorksSerializationException($"Cannot parse payload as JSON. Payload={contents}", contents); } }
public static JsonSerializerSettings CreateJsonSerializerSettings(HttpDataSerializerOptions options, bool debugMode) { options = options ?? new HttpDataSerializerOptions(); var settings = new JsonSerializerSettings(); settings.Formatting = debugMode ? Formatting.Indented : Formatting.None; settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); settings.NullValueHandling = NullValueHandling.Ignore; settings.Converters.Add(new JsonTokenConverter()); switch (options.EnumSerializationMethod) { case EnumSerializationMethod.String: settings.Converters.Add(new StringEnumConverter()); break; case EnumSerializationMethod.Numeric: // NOTHING NEEDED NUMERIC CONVERSION BY DEFAULT break; case EnumSerializationMethod.Object: settings.Converters.Add(new JsonEnumObjectConverter()); break; default: throw new ArgumentOutOfRangeException(); } return(settings); }
public Task <string> SerializeExample(Type t, HttpDataSerializerOptions options = null) { options = options ?? new HttpDataSerializerOptions(); var schema = GetSchema(t, options, useStringEnums: true, requireReferenceTypes: true); var sample = schema.ToSampleJson(); var json = sample.ToString(Formatting.Indented); return(Task.FromResult(json)); }
private bool AllowAdditionalPropertiesForJsonSchemaValidation(HttpDataSerializerOptions options) { var allowProps = new[] { JsonValidationStrategy.DefaultAllowAdditionalProperties, JsonValidationStrategy.ForceAllowAdditionalProperties }; return(allowProps.Contains(options.JsonSchemaValidation)); }
private HttpDataSerializerOptions CreateOptionsFromHeaders(HttpRequestHeaders headers) { var opts = new HttpDataSerializerOptions { IncludeDependencyMetaData = ParseHeaderForEnum <IncludeDependencyMetaDataStrategy>(headers, "codeworks-prefs-dep-meta"), EnumSerializationMethod = ParseHeaderForEnum <EnumSerializationMethod>(headers, "codeworks-prefs-enum"), JsonSchemaValidation = ParseHeaderForEnum <JsonValidationStrategy>(headers, "codeworks-prefs-schema-check") }; return(opts); }
public async Task <T> DeserializeResponse <T>(byte[] message, HttpDataSerializerOptions options = null) where T : new() { var opts = TextJsonSerializerSettings.CreateJsonSerializerOptions(options, _debugMode); try { using (var ms = new MemoryStream(message)) { var result = await JsonSerializer.DeserializeAsync <T>(ms, opts); return(result); } } catch (JsonException ex) { _logger.LogError("Cannot deserialize response", ex); throw new CodeWorksSerializationException("Cannot deserialize JSON payload", ex); } }
public async Task <BaseRequest> DeserializeRequest( Type type, byte[] message, HttpDataSerializerOptions options = null) { var opts = TextJsonSerializerSettings.CreateJsonSerializerOptions(options, _debugMode); if (message.Length == 0) { return((BaseRequest)Activator.CreateInstance(type)); } try { using (var ms = new MemoryStream(message)) { var result = await JsonSerializer.DeserializeAsync(ms, type, opts); return((BaseRequest)result); } } catch (JsonException ex) { var contents = Encoding.UTF8.GetString(message); if (ex.StackTrace.Contains("JsonConverterEnum")) { // INVALID ENUM FOUND - TRY AND FIGURE IT OUT var property = ex.Path.Substring(2, ex.Path.Length - 2); throw new ValidationErrorException("Invalid enum value provided", property); } if (string.IsNullOrWhiteSpace(contents)) { return((BaseRequest)Activator.CreateInstance(type)); } _logger.LogError(ex, $"Cannot deserialize request payload {contents}"); throw new CodeWorksSerializationException($"Cannot parse payload as JSON. Payload={contents}", contents); } }
public JsonSchema GetSchema(Type t, HttpDataSerializerOptions options, bool useStringEnums, bool requireReferenceTypes) { var settings = GetSchemaSerializationSettings(useStringEnums); JsonSchema schema = JsonSchema.FromType(t, new JsonSchemaGeneratorSettings { FlattenInheritanceHierarchy = true, AlwaysAllowAdditionalObjectProperties = AllowAdditionalPropertiesForJsonSchemaValidation(options), GenerateEnumMappingDescription = true, DefaultReferenceTypeNullHandling = requireReferenceTypes ? ReferenceTypeNullHandling.NotNull : ReferenceTypeNullHandling.Null, SerializerSettings = settings, ReflectionService = new CustomReflectionService(), TypeMappers = new List <ITypeMapper> { new TokenStringTypeMapper(), new TokenDateTypeMapper(), new ClientTokenStringTypeMapper(), new ClientTokenDateTypeMapper() } }); return(schema); }
private bool ShouldValidateSchema(HttpDataSerializerOptions options) { if (_environmentResolver.Environment == CodeWorksEnvironment.Production) { var prodValidationOptions = new[] { JsonValidationStrategy.ForceStrict, JsonValidationStrategy.ForceAllowAdditionalProperties, }; return(prodValidationOptions.Contains(options.JsonSchemaValidation)); } var nonProdValidationOptions = new[] { JsonValidationStrategy.DefaultStrict, JsonValidationStrategy.DefaultAllowAdditionalProperties, JsonValidationStrategy.ForceStrict, JsonValidationStrategy.ForceAllowAdditionalProperties, }; return(nonProdValidationOptions.Contains(options.JsonSchemaValidation)); }
public async Task <BaseRequest> ConvertRequest(Type type, HttpRequestMessage request) { HttpDataSerializerOptions options = CreateOptionsFromHeaders(request.Headers); byte[] contents = await request.Content.ReadAsByteArrayAsync(); if (ShouldValidateSchema(options)) { var schemaErrors = await _serializationSchema.ValidateSchema(contents, type, options); if (schemaErrors.Any()) { throw new SchemaValidationException($"Cannot validate payload as type of {type.FullName}", schemaErrors); } BaseRequest validResult = await _serializer.DeserializeRequest(type, contents, options); return(validResult); } BaseRequest result = await _serializer.DeserializeRequest(type, contents, options); return(result); }
public async Task <ServiceResponse> DeserializeResponse(Type type, byte[] message, HttpDataSerializerOptions options = null) { var opts = TextJsonSerializerSettings.CreateJsonSerializerOptions(options, _debugMode); try { using (var ms = new MemoryStream(message)) { var result = await JsonSerializer.DeserializeAsync(ms, type, opts); return((ServiceResponse)result); } } catch (JsonException ex) { _logger.LogError("Cannot deserialize request", ex); throw; } }
public async Task <BaseRequest> DeserializeRequest(Type type, byte[] message, HttpDataSerializerOptions options = null) { await Task.CompletedTask; var settings = JsonNetSerializerSettings.CreateJsonSerializerSettings(options, _debugMode); if (message.Length == 0) { return((BaseRequest)Activator.CreateInstance(type)); } try { using (var ms = new MemoryStream(message)) { using (var reader = new StreamReader(ms, Encoding.UTF8)) { var result = JsonSerializer.Create(settings).Deserialize(reader, type); return((BaseRequest)result); } } } catch (JsonSerializationException ex) { var contents = Encoding.UTF8.GetString(message); if (ex.StackTrace.Contains("StringEnumConverter")) { // INVALID ENUM FOUND - TRY AND FIGURE IT OUT var property = ex.Path; throw new ValidationErrorException("Invalid value provided", property); } throw; } catch (JsonException ex) { var t = ex.GetType(); var contents = Encoding.UTF8.GetString(message); //StringEnumConverter if (ex.StackTrace.Contains("StringEnumConverter")) { // INVALID ENUM FOUND - TRY AND FIGURE IT OUT var property = ""; throw new ValidationErrorException("Invalid enum value provided", property); } if (string.IsNullOrWhiteSpace(contents)) { return((BaseRequest)Activator.CreateInstance(type)); } _logger.LogError(ex, $"Cannot deserialize request payload {contents}"); throw new CodeWorksSerializationException($"Cannot parse payload as JSON. Payload={contents}", contents); } catch (Exception ex) { _logger.LogError(ex, $"Cannot deserialize request payload"); throw new CodeWorksSerializationException($"Cannot parse payload as JSON"); } }
public async Task <T> DeserializeRequest <T>(byte[] message, HttpDataSerializerOptions options = null) where T : BaseRequest, new() { var r = await DeserializeRequest(typeof(T), message, options); return(r as T); }
public Task <string> SerializeResponse(ServiceResponse response, Type responseType, HttpDataSerializerOptions options = null) { var settings = JsonNetSerializerSettings.CreateJsonSerializerSettings(options, _debugMode); var res = JsonConvert.SerializeObject(response, settings); return(Task.FromResult(res)); }
public async Task <string> SerializeRequest(BaseRequest request, Type requestType, HttpDataSerializerOptions options = null) { var opts = TextJsonSerializerSettings.CreateJsonSerializerOptions(options, _debugMode); using (var stream = new MemoryStream()) { await JsonSerializer.SerializeAsync(stream, request, requestType, opts); stream.Position = 0; using (var reader = new StreamReader(stream)) { var result = await reader.ReadToEndAsync(); return(result); } } }
public async Task <string> SerializeRequest(BaseRequest request, Type requestType, HttpDataSerializerOptions options = null) { var settings = JsonNetSerializerSettings.CreateJsonSerializerSettings(options, _debugMode); string contents = ""; using (var stream = new MemoryStream()) { using (var writer = new StreamWriter(stream, Encoding.UTF8)) { var serializer = JsonSerializer.Create(settings); serializer.Serialize(writer, request, requestType); } stream.Position = 0; using (var reader = new StreamReader(stream, Encoding.UTF8)) { contents = await reader.ReadToEndAsync(); } } return(contents); }
public Task <IDictionary <string, string[]> > ValidateSchema(byte[] message, Type type, HttpDataSerializerOptions options = null) { options = options ?? new HttpDataSerializerOptions(); string contents = Encoding.UTF8.GetString(message); var schema = GetSchema( type, options, options.EnumSerializationMethod == EnumSerializationMethod.String, requireReferenceTypes: false); ICollection <ValidationError> errors = schema.Validate(contents, new EnumFormatValidator()); IDictionary <string, string[]> dict = new Dictionary <string, string[]>(); foreach (var err in errors) { RecursivelyGetErrors(dict, err, schema); } if (dict.Any()) { dict.AddOrAppendValue("errorType", "jsonSchemaValidation"); dict.AddOrAppendValue("schema", schema.ToJson(Formatting.None)); _logger.LogTrace(schema.ToJson()); } return(Task.FromResult(dict)); }
public async Task ConvertResponse(ServiceResponse response, Type responseType, HttpResponse httpResponse, HttpDataSerializerOptions options = null) { options ??= new HttpDataSerializerOptions(); var serializedData = await _serializer.SerializeResponse(response, responseType, options); var contentType = _serializer.ContentType; var encoding = _serializer.Encoding; httpResponse.StatusCode = response.MetaData.Result.HttpStatusCode(); httpResponse.ContentType = contentType; await httpResponse.WriteAsync(serializedData, encoding); }
public async Task <BaseRequest> ConvertRequest(Type requestType, HttpRequest request, HttpDataSerializerOptions options) { options ??= new HttpDataSerializerOptions(); BaseRequest result = null; if (request.ContentLength.GetValueOrDefault() > 0) { await using var ms = new MemoryStream(); await request.Body.CopyToAsync(ms); var message = ms.ToArray(); result = await _serializer.DeserializeRequest(requestType, message, options); } if (request.Query.Any()) { result ??= (BaseRequest)Activator.CreateInstance(requestType); PropertyInfo[] properties = requestType.GetProperties(); foreach (PropertyInfo property in properties) { StringValues qv = request.Query[property.Name]; if (!string.IsNullOrWhiteSpace(qv)) { try { var val = GetFromString(qv, property.PropertyType); property.SetValue(result, val); } catch (Exception) { throw new ValidationErrorException($"Cannot convert {qv} to {property.PropertyType.Name}", property.Name); } } } } return(result ?? (BaseRequest)Activator.CreateInstance(requestType)); }
public async Task ConvertResponse <T>(ServiceResponse <T> response, HttpResponse httpResponse, HttpDataSerializerOptions options) where T : new() { var serializedData = await _serializer.SerializeResponse(response, typeof(ServiceResponse <T>), options); var contentType = _serializer.ContentType; var encoding = _serializer.Encoding; httpResponse.StatusCode = response.MetaData.Result.HttpStatusCode(); httpResponse.ContentType = contentType; await httpResponse.WriteAsync(serializedData, encoding); }