public static void PopulateFrom(this PartialSchema partialSchema, Schema schema) { if (schema == null) return; partialSchema.type = schema.type; partialSchema.format = schema.format; if (schema.items != null) { // TODO: Handle jagged primitive array and error on jagged object array partialSchema.items = new PartialSchema(); partialSchema.items.PopulateFrom(schema.items); } partialSchema.@default = schema.@default; partialSchema.maximum = schema.maximum; partialSchema.exclusiveMaximum = schema.exclusiveMaximum; partialSchema.minimum = schema.minimum; partialSchema.exclusiveMinimum = schema.exclusiveMinimum; partialSchema.maxLength = schema.maxLength; partialSchema.minLength = schema.minLength; partialSchema.pattern = schema.pattern; partialSchema.maxItems = schema.maxItems; partialSchema.minItems = schema.minItems; partialSchema.uniqueItems = schema.uniqueItems; partialSchema.@enum = schema.@enum; partialSchema.multipleOf = schema.multipleOf; }
public void Apply(Schema model, ModelFilterContext context) { model.Default = new { Id = "myCartId" }; }
private static void FixSchemaReference(SchemaRegistry registry, Schema schema, Type referencedType) { Contract.Requires(schema.@ref != null); var schemaIdSelector = registry.GetInstanceField<Func<Type, string>>("_schemaIdSelector", true); schema.@ref = "#/definitions/" + schemaIdSelector(referencedType); }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { if (schema == null || schema.properties == null || type == null) return; bool isPushTrigger = type.AssemblyQualifiedNameNoTypeParams() == typeof(TriggerInput<string, string>).AssemblyQualifiedNameNoTypeParams(); foreach (var propertyName in schema.properties.Keys) { var property = schema.properties[propertyName]; if (isPushTrigger && propertyName == Constants.CALLBACK_URL_PROPERTY_NAME) { #region Apply callback magic defaults // Apply trigger magic defaults: // "x-ms-scheduler-recommendation": "@accessKeys('default').primary.secretRunUri schema.SetChildPropertyRequired(Constants.CALLBACK_URL_PROPERTY_NAME); property.SetVisibility(VisibilityType.Internal); property.SetSchedulerRecommendation(Constants.CALLBACK_URL_MAGIC_DEFAULT); // This is what this will look like (pulled from HTTP Listener API Definition) // // "TriggerInput[TriggerPushParameters,TriggerOutputParameters]": { // "required": [ <-- SetChildPropertyRequired (on the parent model containing the callbackUrl property) // "callbackUrl" // ], // "type": "object", // "properties": { // "callbackUrl": { <-- SetSchedulerRecommendation (on the actual property) // "type": "string", // "x-ms-visibility": "internal", // "x-ms-scheduler-recommendation": "@accessKeys('default').primary.secretRunUri" // }, #endregion } // Apply friendly names and descriptions wherever possible // "x-ms-summary" - friendly name (applies to properties) // schema.properties["prop"].description - description (applies to parameters) var propertyInfo = type.GetRuntimeProperties().Where(p => p.Name == propertyName).FirstOrDefault(); if (propertyInfo == null) return; var propertyMetadata = propertyInfo.GetCustomAttribute<MetadataAttribute>(); if (propertyMetadata != null) { property.SetVisibility(propertyMetadata.Visibility); property.SetFriendlyNameAndDescription(propertyMetadata.FriendlyName, propertyMetadata.Description); } } }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="dataTypeRegistry"></param> /// <param name="type"></param> public void Apply(Schema model, SchemaRegistry dataTypeRegistry, Type type) { if (model != null && dataTypeRegistry != null && type != null) { var ignoredProperties = type.GetProperties().Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), false).FirstOrDefault() != null); foreach (var property in ignoredProperties) { model.properties.Remove(property.Name); } } }
private void ApplyPropertyComments(Schema propertySchema, PropertyInfo propertyInfo) { if (propertyInfo == null) return; var commentId = XmlCommentsIdHelper.GetCommentIdForProperty(propertyInfo); var propertyNode = _navigator.SelectSingleNode(string.Format(MemberXPath, commentId)); if (propertyNode == null) return; var propSummaryNode = propertyNode.SelectSingleNode(SummaryTag); if (propSummaryNode != null) { propertySchema.description = propSummaryNode.ExtractContent(); } }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { if (type == typeof(GetLobbyResponse)) schema.example = new GetLobbyResponse() { }; if (type == typeof(GetByResponse)) schema.example = new GetByResponse() { }; if (type == typeof(UpdateLobbyRequest)) schema.example = new UpdateLobbyRequest() { }; if (type == typeof(ChangeStatusRequest)) schema.example = new ChangeStatusRequest() { }; }
private void ApplyPropertyComments(Schema propertySchema, PropertyInfo propertyInfo) { if (propertyInfo == null) return; var propertyNode = _navigator.SelectSingleNode( String.Format(PropertyExpression, propertyInfo.DeclaringType.XmlLookupName(), propertyInfo.Name)); if (propertyNode == null) return; var propSummaryNode = propertyNode.SelectSingleNode(SummaryExpression); if (propSummaryNode != null) { propertySchema.description = propSummaryNode.ExtractContent(); } }
/// <summary> /// Example of updating enum definitions, strip trailing "Internal" before generating swagger doc /// </summary> /// <param name="schema"></param> /// <param name="type"></param> private void UpdateEnumDefinitions(Schema schema, Type type) { foreach (var property in schema.properties) { if (property.Value.@enum != null) { var clrType = type.GetProperty(property.Key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty).PropertyType; property.Value.vendorExtensions.Add("x-ms-enum", new { name = clrType.Name.TrimEnd("Internal"), modelAsString = bool.TrueString }); } } }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { var properties = type.GetProperties(); foreach (var property in properties) { object[] attrs = property.GetCustomAttributes(true); foreach (object attr in attrs) { JsonIgnoreAttribute authAttr = attr as JsonIgnoreAttribute; if (authAttr != null) { schema.properties.Remove(property.Name); break; } } } }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="dataTypeRegistry"></param> /// <param name="type"></param> public void Apply(Schema model, SchemaRegistry dataTypeRegistry, Type type) { if (model != null && dataTypeRegistry != null && type != null && model.properties != null) { bool isPushTrigger = false; // not taking dependency on runtime dll to avoid circular dependencies betwwen saas and enterprise repo if (!string.IsNullOrEmpty(type.AssemblyQualifiedName) && type.AssemblyQualifiedName.StartsWith("Microsoft.Azure.AppService.ApiApps.Service.TriggerInput", StringComparison.InvariantCultureIgnoreCase)) { isPushTrigger = true; } foreach (string property in model.properties.Keys) { Schema propSchema = model.properties[property]; propSchema.vendorExtensions = SetSummaryAndVisibility(type, property, propSchema.description, propSchema.vendorExtensions); if (isPushTrigger && property.Equals("callbackurl", StringComparison.InvariantCultureIgnoreCase)) { if (model.required == null) { model.required = new List<string>(); } if (!model.required.Contains(property)) { model.required.Add(property); } propSchema.vendorExtensions = SummaryAndVisibilityOperationFilter.SetVendorExtension(summary: null, visibility: Visibility.Internal, vendorExtensions: propSchema.vendorExtensions); if (!propSchema.vendorExtensions.ContainsKey(SummaryAndVisibilityOperationFilter.triggerRecommendation)) { propSchema.vendorExtensions.Add(SummaryAndVisibilityOperationFilter.triggerRecommendation, SummaryAndVisibilityOperationFilter.callbackRecommendationValue); } } } // in case of no properties inside the class or object, set the visibility/summary attributes on the class object. if (model.properties.Keys.Count == 0) { model.vendorExtensions = SetSummaryAndVisibility(type, model.description, model.vendorExtensions); } } }
private void ExtractAndAddQueryParams( Schema sourceSchema, string sourceQualifier, bool? sourceRequired, SchemaRegistry schemaRegistry, IList<Parameter> operationParams) { foreach (var entry in sourceSchema.properties) { var propertySchema = entry.Value; if (propertySchema.readOnly == true) continue; var required = (sourceRequired == true) && sourceSchema.required != null && sourceSchema.required.Contains(entry.Key); if (propertySchema.@ref != null) { var schema = schemaRegistry.Definitions[[email protected]("#/definitions/", "")]; ExtractAndAddQueryParams( schema, sourceQualifier + entry.Key.ToCamelCase() + ".", required, schemaRegistry, operationParams); } else { var param = new Parameter { name = sourceQualifier + entry.Key.ToCamelCase(), @in = "query", required = required, description = entry.Value.description, example = entry.Value.example }; param.PopulateFrom(entry.Value); if (param.type == "array") param.collectionFormat = "multi"; operationParams.Add(param); } } }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { var validator = GetValidator(type); if (validator == null) { return; } schema.required = new List<string>(); var validatorDescriptor = validator.CreateDescriptor(); foreach (var key in schema.properties.Keys) { foreach (var propertyValidator in validatorDescriptor.GetValidatorsForMember(key)) { if (propertyValidator is NotEmptyValidator) { schema.required.Add(key); } if (propertyValidator is LengthValidator) { var lengthValidator = (LengthValidator) propertyValidator; if (lengthValidator.Max > 0) { schema.properties[key].maxLength = lengthValidator.Max; } schema.properties[key].minLength = lengthValidator.Min; } if (propertyValidator is RegularExpressionValidator) { var regexExpressionValidator = (RegularExpressionValidator) propertyValidator; schema.properties[key].pattern = regexExpressionValidator.Expression; } } } }
public void Apply(Schema model, ModelFilterContext context) { var commentId = XmlCommentsIdHelper.GetCommentIdForType(context.SystemType); var typeNode = _navigator.SelectSingleNode(string.Format(MemberXPath, commentId)); if (typeNode != null) { var summaryNode = typeNode.SelectSingleNode(SummaryTag); if (summaryNode != null) model.description = summaryNode.ExtractContent(); } foreach (var entry in model.properties) { var jsonProperty = context.JsonObjectContract.Properties[entry.Key]; if (jsonProperty == null) continue; ApplyPropertyComments(entry.Value, jsonProperty.PropertyInfo()); } }
/// <summary> /// /// </summary> /// <param name="schema"></param> /// <param name="schemaRegistry"></param> /// <param name="type"></param> public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { if (schema != null && schemaRegistry != null && type != null && schema.properties != null) { foreach (string property in schema.properties.Keys) { Schema propSchema = schema.properties[property]; var newType = this.GetOverrideType(type, property); if (!string.IsNullOrEmpty(newType)) { // Only string, boolean and int data types are supported in OverideTypeAttribute. if (this.IsSupportedDataType(newType)) { propSchema.@ref = null; propSchema.type = newType; } } } } }
public void Apply(Schema model, ModelFilterContext context) { var typeNode = _navigator.SelectSingleNode( String.Format(TypeExpression, context.SystemType.XmlLookupName())); if (typeNode != null) { var summaryNode = this.GetSummaryNode(typeNode); if (summaryNode != null) model.description = summaryNode.ExtractContent(); } foreach (var entry in model.properties) { var jsonProperty = context.JsonObjectContract.Properties[entry.Key]; if (jsonProperty == null) continue; ApplyPropertyComments(entry.Value, jsonProperty.PropertyInfo()); } }
public void SchemaFilter_SetsPropsToReadOnly() { // Arrange var filter = new MobileAppSchemaFilter(); var schema = new Schema() { properties = new Dictionary<string, Schema>() { { "ReadWrite", new Schema() }, { "ReadOnly", new Schema() } } }; // Act filter.Apply(schema, null, typeof(TestType)); // Assert Assert.Null(schema.properties["ReadWrite"].readOnly); Assert.True(schema.properties["ReadOnly"].readOnly); }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { var name = type.FullName; if (type.IsGenericType) { // example of handling a generic resource type //if (type.GetGenericTypeDefinition() == typeof(Resource<>)) //{ // schema.vendorExtensions.Add("x-ms-azure-resource", true); //} } UpdateEnumDefinitions(schema, type); // filter some types out of the swagger doc //if (!(name.StartsWith("SwashApiTest.") || type == typeof(object))) //{ // schema.vendorExtensions.Add(SwaggerConstants.ToRemoveVendorExtension, ""); //} }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { if (schema == null) { throw new ArgumentNullException("schema"); } if (type == null) { throw new ArgumentNullException("type"); } foreach (PropertyInfo prop in type.GetProperties()) { foreach (var attr in prop.GetCustomAttributes(true)) { if (typeof(DatabaseGeneratedAttribute).IsAssignableFrom(attr.GetType())) { schema.properties[prop.Name].readOnly = true; } } } }
private void ExtractAndAddQueryParams( Schema sourceSchema, string sourceQualifier, bool sourceRequired, SchemaRegistry schemaRegistry, IList<Parameter> operationParams) { foreach (var entry in sourceSchema.properties) { var propertySchema = entry.Value; var required = sourceRequired && sourceSchema.required != null && sourceSchema.required.Contains(entry.Key); if (propertySchema.@ref != null) { var schema = schemaRegistry.Definitions[[email protected]("#/definitions/", "")]; ExtractAndAddQueryParams( schema, sourceQualifier + entry.Key.ToLowerInvariant() + ".", required, schemaRegistry, operationParams); } else { var param = new Parameter { name = sourceQualifier + entry.Key.ToLowerInvariant(), @in = "query", required = required, description = entry.Value.description }; param.PopulateFrom(entry.Value); operationParams.Add(param); } } }
private static void RegisterReferencedTypes(SchemaRegistry registry, IEdmModel edmModel, Schema schema) { Contract.Requires(registry != null); Contract.Requires(schema != null); while (true) { Contract.Assume(schema != null); var referencedType = schema.GetReferencedType(); if (referencedType != null) { registry.GetOrRegister(referencedType); FixSchemaReference(registry, schema, referencedType); ApplyEdmModelPropertyNamesToSchema(registry, edmModel, referencedType); return; } if (schema.properties != null && schema.properties.Any()) { foreach (var property in schema.properties) { RegisterReferencedTypes(registry, edmModel, property.Value); } return; } if (schema.items != null) { schema = schema.items; continue; } break; } }
public void Apply(Schema model, ModelFilterContext context) { model.Extensions.Add("X-property1", "value"); }
private Schema CreateObjectSchema(JsonObjectContract jsonContract) { var properties = jsonContract.Properties .Where(p => !p.Ignored) .Where(p => !(_ignoreObsoleteProperties && p.IsObsolete())) .ToDictionary( prop => prop.PropertyName, prop => CreateInlineSchema(prop.PropertyType).WithValidationProperties(prop) ); var required = jsonContract.Properties.Where(prop => prop.IsRequired()) .Select(propInfo => propInfo.PropertyName) .ToList(); var schema = new Schema { required = required.Any() ? required : null, // required can be null but not empty properties = properties, type = "object" }; foreach (var filter in _schemaFilters) { filter.Apply(schema, this, jsonContract.UnderlyingType); } // NOTE: In next major version, _modelFilters will completely replace _schemaFilters var modelFilterContext = new ModelFilterContext(jsonContract.UnderlyingType, jsonContract, this); foreach (var filter in _modelFilters) { filter.Apply(schema, modelFilterContext); } return schema; }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) { schema.vendorExtensions.Add("x-schema", "bar"); }
/// <summary> /// Called when generating the schema /// </summary> public void Apply(Schema model, ModelFilterContext context) { foreach (var dtProp in model.Properties.Where(x => x.Value.Format == "date-time")) dtProp.Value.Format = "date"; }
internal static IDictionary<string, Schema> GenerateSwaggerDefinitionsForEntities( IEnumerable<ArticleType> templateTypes) { var definitions = new Dictionary<string, Schema>(); var entityProperties = new Dictionary<string, Schema> { ["id"] = new Schema { type = "string", description = "unique identifier for the entity", }, ["parentid"] = new Schema { type = "string", description = "unique identifier for the parent entity", }, ["name"] = new Schema { type = "string", description = "name of the entity", } }; var articleRequired = new List<string> { "id", "parentid", "name" }; var knownEntities = templateTypes .SelectMany(t => t.Fields) .Where(f => !f.Name.StartsWith("a_")) .Where(f => !string.IsNullOrWhiteSpace(f.Entity?.Type)) .Select(f => f.Entity.Type) .Distinct() .ToList(); foreach (var entity in knownEntities) { var schema = new Schema { type = "object", required = articleRequired, properties = entityProperties }; var type = entity; definitions.Add($"{type}", schema); var resultSchema = new Schema { type = "object", properties = new Dictionary<string, Schema> { ["results"] = new Schema {type = "array", items = new Schema {@ref = type}} } }; definitions.Add($"ResultOf{type}", resultSchema); } return definitions; }
public void Apply(Schema schema, SchemaRegistry schemaRegistry, System.Type type) { SchemaHelper.Apply(schema, schemaRegistry, type); }
public static void Apply(Schema schema, SchemaRegistry schemaRegistry, System.Type type) { var workStr = type.ToString(); if (type.IsEnum) { EnumRegist(schemaRegistry, type); } if (IsNullableEnumType(type)) { var innerType = type.GetGenericArguments()[0]; EnumRegist(schemaRegistry, innerType); } if (schema.type == "array") { if (type.IsArray) { Apply(schema.items, schemaRegistry, type.GetElementType()); } else { Apply(schema.items, schemaRegistry, type.GetGenericArguments()[0]); } return; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { schema.vendorExtensions.Add("CsType", type.GetGenericArguments()[0].Name + "?"); schema.vendorExtensions.Add("CsNamespace", type.Namespace); } else { schema.vendorExtensions.Add("CsType", type.Name); schema.vendorExtensions.Add("CsNamespace", type.Namespace); } if (schema.properties != null) { foreach (var prop in schema.properties) { var pi = type.GetProperty(prop.Key); if (pi != null) { Apply(prop.Value, schemaRegistry, pi.PropertyType); } } } }
internal static IDictionary<string, Schema> GenerateSwaggerDefinitionsForArticles( IEnumerable<ArticleType> templateTypes) { var definitions = new Dictionary<string, Schema>(); var articleProperties = new Dictionary<string, Schema> { ["id"] = new Schema { type = "string", description = "unique identifier for the object", }, ["parentid"] = new Schema { type = "string", description = "unique identifier for the parent object", }, ["parenttype"] = new Schema { type = "string", description = "type of the parent object", } }; var articleRequired = new List<string> { "id", "parentid", "parenttype" }; foreach (var templateType in templateTypes) { var combinedProperties = articleProperties .Concat(GenerateTypeProperties(templateType).OrderBy(pair => pair.Key)) .ToDictionary(pair => pair.Key, pair => pair.Value); var schema = new Schema { type = "object", required = articleRequired, properties = combinedProperties }; var type = templateType.Type; definitions.Add($"{type}", schema); var resultSchema = new Schema { type = "object", properties = new Dictionary<string, Schema> { ["results"] = new Schema {type = "array", items = new Schema {@ref = type}} } }; definitions.Add($"ResultOf{type}", resultSchema); } var multiReferenceSchema = new Schema { type = "object", required = new[] { "values", "type" }, properties = new Dictionary<string, Schema> { ["type"] = new Schema { type = "string", description = "type of the reference" }, ["values"] = new Schema { type = "array", items = new Schema {type = "string", description = "The unique id of referenced objects"} } } }; var singleReferenceSchema = new Schema { type = "object", required = new[] {"values", "type"}, properties = new Dictionary<string, Schema> { ["type"] = new Schema { type = "string", description = "type of the reference" }, ["values"] = new Schema { type = "array", maxItems = 1, items = new Schema {type = "string", description = "The unique id of referenced objects"} } } }; definitions.Add("MultiReference", multiReferenceSchema); definitions.Add("SingleReference", singleReferenceSchema); return definitions; }
public ODataActionParameterDescriptor(string parameterName, Type parameterType, bool isOptional, Schema schema, HttpParameterDescriptor reflectedHttpParameterDescriptor) : base(parameterName, parameterType, isOptional, reflectedHttpParameterDescriptor) { Contract.Requires(schema != null); Schema = schema; }