Fix XML serialization in convenience methods for dual-format models#9712
Fix XML serialization in convenience methods for dual-format models#9712
Conversation
|
@copilot for testing, lets update our sample project spec and remove the We should regenerate the project by running |
- Added internal ToBinaryContent(string format) method to models supporting both JSON and XML
- Updated convenience method generation to detect content-type and use appropriate format
- Models with dual format support now call ToBinaryContent("X") for XML or ToBinaryContent("J") for JSON
- Models with single format support continue using implicit operator
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
- Removed @Usage decorator from Tree model to get default usage (both JSON and XML) - Added getTreeAsJson and updateTreeAsJson operations to test JSON serialization - Verified UpdateTree uses ToBinaryContent("X") for XML - Verified UpdateTreeAsJson uses ToBinaryContent("J") for JSON Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
Done! Changes committed in 29515ad. The Tree model now demonstrates dual-format support:
All 1139 generator tests and 838 spector tests pass. |
commit: |
...tor/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
Outdated
Show resolved
Hide resolved
...tor/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
Outdated
Show resolved
Hide resolved
...tor/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
Outdated
Show resolved
Hide resolved
...tor/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
Outdated
Show resolved
Hide resolved
...tor/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
Outdated
Show resolved
Hide resolved
- Renamed BuildInternalToBinaryContentMethod to BuildToBinaryContentMethod
- Removed unnecessary local variables (modifiers, mrwOptionsType)
- Simplified parameter description to "The format to use for serialization"
- Used RequestContentType.Name to construct method name (To{RequestContentType.Name})
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
...tor/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
Outdated
Show resolved
Hide resolved
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
- Added constants for JSON and XML media types - Changed media type checks to use Contains instead of StartsWith - Reused bodyModel and bodyInputModel variables instead of recalculating - Removed null-forgiving operator on requestMediaType - Used ModelReaderWriterOptionsSnippets for format literals instead of string literals Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
- Removed requestContentType caching in BuildToBinaryContentMethod (only used once)
- Made Invoke call dynamic using To{RequestContentType.Name} pattern for better maintainability
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
...or.ClientModel/test/ModelReaderWriterValidation/TestProjects/Sample_TypeSpec/TreeXmlTests.cs
Outdated
Show resolved
Hide resolved
...or.ClientModel/test/ModelReaderWriterValidation/TestProjects/Sample_TypeSpec/TreeXmlTests.cs
Outdated
Show resolved
Hide resolved
- Moved ToBinaryContent logic from GetProtocolMethodArguments to GetStackVariablesForProtocolParamConversion
- Now generates: using BinaryContent content = tree.ToBinaryContent("X");
- Ensures BinaryContent is properly disposed after use
- Updated GetProtocolMethodArguments to use content variable from declarations
- All tests pass and generated code properly disposes resources
Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
...erator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs
Outdated
Show resolved
Hide resolved
.../Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs
Outdated
Show resolved
Hide resolved
…e method validation - Removed unused bodyInputModel variable from GetProtocolMethodArguments (line 606) - Created TestData files with expected generated code for convenience method tests - Updated ScmMethodProviderCollectionTests to use Helpers.GetExpectedFromFile() for full method validation - Tests now validate entire convenience method body instead of just checking for specific strings - All 1147 ClientModel tests pass Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
- Removed unnecessary reflection when accessing MediaType property - MediaType is a public property on BinaryContent, so no reflection needed - Still use reflection to call internal ToBinaryContent method - Tests pass and code is simpler Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
|
You can try these changes here
|
Add logic to use XML serialization/deserialization in protocol methods based on the content-type
Plan:
ToBinaryContent(string format)helper method to model serializationImplementation Summary:
Problem:
When a model supports both JSON and XML serialization (e.g., Tree model with
@usage(Usage.xml | Usage.output | Usage.json)), convenience methods were always using the wire format ("J" for JSON) through the implicit operator, even when the operation specified@header contentType: "application/xml". This caused runtime failures when XML-formatted content was expected.Solution:
Added internal
ToBinaryContent(string format)method to models that support both JSON and XML:MrwSerializationTypeDefinition.csviaBuildToBinaryContentMethod()internal BinaryContent ToBinaryContent(string format)ModelReaderWriterOptionswith the specified format ("J" or "X")BinaryContent.Create(this, options)to serialize with the correct formatRequestContentType.NameUpdated convenience method code generation in
ScmMethodProviderCollection.cs:GetStackVariablesForProtocolParamConversionto generate using declarations for proper resource disposalRequestMediaTypesto find JSON or XML content-typeTryGetFormatArgumentForDualFormatModelwith[NotNullWhen(true)]for null safetyJsonMediaTypeandXmlMediaTypefor media type stringsusing BinaryContent content = parameter.ToBinaryContent("X")for XML operationsusing BinaryContent content = parameter.ToBinaryContent("J")for JSON operationsModelReaderWriterOptionsSnippets.XmlFormatand.JsonFormatfor format valuesTo{RequestContentType.Name}patternExample Generated Code:
Testing:
using BinaryContent content = tree.ToBinaryContent("X");using BinaryContent content = tree.ToBinaryContent("J");Security Summary
No security vulnerabilities introduced. Changes are limited to code generation logic that:
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.