Skip to content

[dotnet-svcutil] fix --internal inconsistent accessibility (XmlSerializer)#5895

Merged
imcarolwang merged 3 commits intodotnet:mainfrom
imcarolwang:issue5894
Apr 13, 2026
Merged

[dotnet-svcutil] fix --internal inconsistent accessibility (XmlSerializer)#5895
imcarolwang merged 3 commits intodotnet:mainfrom
imcarolwang:issue5894

Conversation

@imcarolwang
Copy link
Copy Markdown
Contributor

@imcarolwang imcarolwang commented Feb 3, 2026

For issue #5894 :

  • Fixed XmlSerializer DataSet-like WSDL imports so they generate System.Data.DataSet / System.Data.DataTable instead of placeholder ArrayOfXElement (via a new DataSetSchemaImporterExtension wired into the XmlSerializer import pipeline, with msdata + wrapper/diffgram pattern detection).

  • Addressed the --internal “inconsistent accessibility” problem where a public generated type exposed an internal helper (ArrayOfXElement): we now either avoid generating that helper (by mapping to DataSet) and/or make schema-generated types internal when --internal is used.

  • Added a CodeDOM pass (InternalTypeVisibilityFixer) so --internal consistently makes XmlSerializer-generated data types internal too; fixed the initial build error (override visibility mismatch).

Update (follow-up fix):

  • The InternalTypeVisibilityFixer approach was reverted because making XmlSerializer schema/message types internal can break WCF at runtime: XmlSerializerOperationBehavior generates serializer assemblies at runtime which cannot reference internal types, leading to XmlReflectionImporter failures when using the client.

  • Keeping the ArrayOfXElement helper type public under --internal is a separate compatibility tweak to prevent compile-time “inconsistent accessibility” (public members exposing an internal helper) in the remaining xsd:any/IXmlSerializable remap cases, while DataSet-like shapes are still mapped to System.Data types.

  • Added a regression test case for the DataSet-wrapper + --internal scenario.

Comment thread src/dotnet-svcutil/lib/src/ImportModule.cs Outdated
@mconnew
Copy link
Copy Markdown
Member

mconnew commented Feb 4, 2026

@imcarolwang, it looks like the problem is that we accept the /internal command line parameter when the service requires use of XmlSerializer and silently ignore it, and the ArrayOfXElement problem was because we were generating that as internal when it should also be public. Does that sound right?

@mconnew
Copy link
Copy Markdown
Member

mconnew commented Feb 4, 2026

@imcarolwang, do you think we should generate a warning when you specify internal and dotnet-svcutil has to ignore it due to using XmlSerializer?

@imcarolwang
Copy link
Copy Markdown
Contributor Author

@imcarolwang, it looks like the problem is that we accept the /internal command line parameter when the service requires use of XmlSerializer and silently ignore it, and the ArrayOfXElement problem was because we were generating that as internal when it should also be public. Does that sound right?

I think the second part is right: the ArrayOfXElement inconsistent-accessibility issue happened because we were generating ArrayOfXElement as internal while the schema wrapper types that referenced it were public. Making ArrayOfXElement public fixes that mismatch.

On the first part (“we accept /internal for XmlSerializer and silently ignore it”): it’s not being ignored everywhere. /internal still gets applied in the generators that actually support “generate internal types”:

  • ServiceContractGenerator: /internal maps to ServiceContractGenerationOptions.InternalTypes.
  • DataContract importer:/internalmaps to ImportOptions.GenerateInternal.

The XmlSerializer schema-import path is different: the XSD importer/exporter doesn’t really have a “generate internal schema types” option, so those wrapper types come out public by default. We can try to flip them to internal with a CodeDOM post-pass, but when we tried that it looked like it can break WCF XmlSerializer at runtime (serializer generation/reflection expects those message/schema types to be publicly accessible).

So I’d summarize it as:

  • /internal is honored where it’s supported (contract + DataContract),
  • XmlSerializer schema wrapper types stay public because of how that pipeline + runtime behavior works,
  • and in that setup it seems safest to keep ArrayOfXElement public too (plus the DataSet/DataTable schema importer mapping to avoid ArrayOfXElement for that common pattern).

@imcarolwang
Copy link
Copy Markdown
Contributor Author

@imcarolwang, do you think we should generate a warning when you specify internal and dotnet-svcutil has to ignore it due to using XmlSerializer?

@mconnew that makes sense. I’m thinking we can add a one-time warning when --internal is set and the generated client actually uses XmlSerializer (ideally detect that via XmlSerializerOperationBehavior, so it also covers the “Auto ended up using XmlSerializer” cases, not just --serializer XmlSerializer).

Proposed warning text:
--internal may be only partially applied when using XmlSerializer; some schema wrapper types are generated as public for runtime compatibility.

Does that message sound reasonable to you?

@imcarolwang imcarolwang marked this pull request as ready for review February 6, 2026 08:15
@mconnew mconnew requested a review from Copilot April 10, 2026 23:07
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates dotnet-svcutil’s XmlSerializer import pipeline to better handle DataSet-like schema wrapper patterns (avoiding placeholder ArrayOfXElement generation) and mitigates --internal “inconsistent accessibility” by keeping the XmlSerializer helper type public for runtime compatibility, with a new warning plus regression coverage.

Changes:

  • Added DataSetSchemaImporterExtension and wired it into the XmlSerializer schema import pipeline to map DataSet/DataTable-like shapes to System.Data types.
  • Emitted a one-time warning when --internal is used with XmlSerializer, documenting partial application for runtime compatibility.
  • Added a new WSDL test case and baselines to cover the DataSet-wrapper + --internal scenario; adjusted CodeDOM fixup to keep ArrayOfXElement helper public.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/dotnet-svcutil/lib/tests/TestCases/wsdl/InternalTypes_DataSetWrapper.wsdl New WSDL test input exercising the DataSet-wrapper (“schema + any”) pattern.
src/dotnet-svcutil/lib/tests/src/GlobalToolTests.cs Adds a global-tool regression test validating warning behavior and both --internal and non-internal baselines.
src/dotnet-svcutil/lib/tests/Baselines/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper/Reference.cs Baseline for --internal run showing DataSet mapping and adjusted visibilities.
src/dotnet-svcutil/lib/tests/Baselines/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper.csproj Baseline project artifact for --internal variation.
src/dotnet-svcutil/lib/tests/Baselines/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper/dotnet-svcutil.params.json Baseline params for --internal variation.
src/dotnet-svcutil/lib/tests/Baselines/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper_NoInternal/Reference.cs Baseline for non---internal run showing DataSet mapping.
src/dotnet-svcutil/lib/tests/Baselines/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper_NoInternal/InternalTypes_DataSetWrapper_NoInternal.csproj Baseline project artifact for non---internal variation.
src/dotnet-svcutil/lib/tests/Baselines/InternalTypes_DataSetWrapper/InternalTypes_DataSetWrapper_NoInternal/dotnet-svcutil.params.json Baseline params for non---internal variation.
src/dotnet-svcutil/lib/src/xlf/SR.zh-Hant.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.zh-Hans.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.tr.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.ru.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.pt-BR.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.pl.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.ko.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.ja.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.it.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.fr.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.es.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.de.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/xlf/SR.cs.xlf Adds localization entry for the new --internal + XmlSerializer warning.
src/dotnet-svcutil/lib/src/SR.resx Adds the new warning resource WrnInternalOptionPartiallyAppliedWithXmlSerializer.
src/dotnet-svcutil/lib/src/SchemaImporterExtensions/DataSetSchemaImporterExtension.cs New schema importer extension implementing DataSet/DataTable detection and mapping.
src/dotnet-svcutil/lib/src/ImportModule.cs Wires in the new schema importer extension and emits a one-time warning for --internal + XmlSerializer.
src/dotnet-svcutil/lib/src/CodeDomFixup/VisitorFixup.cs Forces ArrayOfXElement helper to remain public to avoid accessibility issues and XmlSerializer runtime failures.

@imcarolwang imcarolwang merged commit 003c2f0 into dotnet:main Apr 13, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants