WebApi
WebApi copied to clipboard
Confusing format of Metadata
I am getting metadata in JSON format, But there are $ characters and properties that are not a collection. Also, I want add new attributes and it is not in the same format
Assemblies affected
Microsoft.AspNetCore.OData 7.5.12
First confusing:
Reproduce steps
Get meta data in JSON format using: https://localhost:44383/odata/$metadata?$format=json
Expected result
I would expect metadata without $ character and properties are listed:
"Student": {
"Kind": "EntityType",
"Key": [
"Id"
],
"Properties": [
"Id": {
"Type": "Edm.Guid"
},
"Name": {
"Nullable": true
},
"Score": {
"Type": "Edm.Int32"
},
"Backpacks": {
"Kind": "NavigationProperty",
"Collection": true,
"Type": "ODataCoreTest.Backpack"
}
]
},
Actual result
Metadata format of an entity like this:
"Student": {
"$Kind": "EntityType",
"$Key": [
"Id"
],
"Id": {
"$Type": "Edm.Guid"
},
"Name": {
"$Nullable": true
},
"Score": {
"$Type": "Edm.Int32"
},
"Backpacks": {
"$Kind": "NavigationProperty",
"$Collection": true,
"$Type": "ODataCoreTest.Backpack"
}
},
Second confusing:
Reproduce steps
I want to add my custom attribute in the entity, for example, Label. I have the following methods to do this:
static void SetAttribute(string entityName, string attributeName, string stringValue, IEdmModel edmModel)
{
var entityType = edmModel.EntityContainer.FindEntitySet(entityName)?.EntityType();
var stringType = EdmCoreModel.Instance.GetString(true);
var value = new EdmStringConstant(stringType, stringValue);
edmModel.SetAnnotationValue(entityType, string.Empty, attributeName, value);
}
And usage:
SetAttribute("Student", "Label", "Student entity", model);
Get meta data in JSON format using: https://localhost:44383/odata/$metadata?$format=json
Expected result
The label is not with $ character
Actual result
The label will be shown, but it is not with $ character as $Kind, $BaseType, ...
I can add Label with $ like : SetAttribute("Student", "$Label", "Student entity", model);
, it will show label with $ in JSON format, but will throw exception on xml version:
An unhandled exception has occurred while executing the request.
System.ArgumentException: Invalid name character in '$Label'. The '$' character, hexadecimal value 0x24, cannot be included in a name.
at System.Xml.XmlWellFormedWriter.CheckNCName(String ncname)
at System.Xml.XmlWellFormedWriter.WriteStartAttribute(String prefix, String localName, String namespaceName)
at System.Xml.XmlAsyncCheckWriter.WriteStartAttribute(String prefix, String localName, String ns)
at System.Xml.XmlWriter.WriteAttributeString(String localName, String ns, String value)
at Microsoft.OData.Edm.Csdl.Serialization.EdmModelCsdlSchemaXmlWriter.WriteAnnotationStringAttribute(IEdmDirectValueAnnotation annotation)
at Microsoft.OData.Edm.Csdl.Serialization.EdmModelCsdlSerializationVisitor.VisitAttributeAnnotations(IEnumerable`1 annotations)
at Microsoft.OData.Edm.Csdl.Serialization.EdmModelCsdlSerializationVisitor.ProcessEntityType(IEdmEntityType element)
at Microsoft.OData.Edm.EdmModelVisitor.VisitSchemaType(IEdmType definition)
at Microsoft.OData.Edm.EdmModelVisitor.VisitSchemaElement(IEdmSchemaElement element)
at Microsoft.OData.Edm.EdmModelVisitor.VisitCollection[T](IEnumerable`1 collection, Action`1 visitMethod)
at Microsoft.OData.Edm.EdmModelVisitor.VisitSchemaElements(IEnumerable`1 elements)
at Microsoft.OData.Edm.Csdl.Serialization.EdmModelCsdlSerializationVisitor.VisitEdmSchema(EdmSchema element, IEnumerable`1 mappings)
Additional detail
It is not a big problem, but it will be good make this consistent
The json property names "$Kind", "$Key", "$Type", "$Nullable", "$Collection" are meta level properties as defined by the OData standard similar to keywords in a programing language. To avoid conflicts between model level JSON property names vs meta level JSON property names the standard decided that the CSDL JSON standard uses the $ prefix and does not allow to use property names starting with $ (hence the error message)
This is expected behavior and in conformance with the standard. Please reach out if you want to discuss further.
The interesting issue is that it appears legal to create an attribute with the "$" prefix in the JSON metadata. We should not be able to create a name in one format that's not legal in the other format.