Skip to content

Commit c4c828a

Browse files
committed
simplify parsing and validation doc, add config doc, polish other docs
1 parent f8dbb31 commit c4c828a

File tree

12 files changed

+196
-265
lines changed

12 files changed

+196
-265
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: How to configure the parser in System.CommandLine
3+
description: "Learn how to configure the parser in System.CommandLine."
4+
ms.date: 16/06/2025
5+
no-loc: [System.CommandLine]
6+
helpviewer_keywords:
7+
- "command line interface"
8+
- "command line"
9+
- "System.CommandLine"
10+
ms.topic: how-to
11+
---
12+
13+
# How to configure the parser in System.CommandLine
14+
15+
[!INCLUDE [scl-preview](../../../includes/scl-preview.md)]
16+
17+
<xref:System.CommandLine.CommandLineConfiguration> is a class that provides properties to configure the parser. It's an optional argument for every `Parse` method such as <xref:System.CommandLine.Command.Parse> or <xref:System.CommandLine.Parsing.CommandLineParser.Parse>. When it's not provided, default configuration is used.
18+
19+
Every <xref:System.CommandLine.ParseResult> instance has a <xref:System.CommandLine.ParseResult.Configuration> property that returns the configuration used for parsing.
20+
21+
## Standard output and error
22+
23+
<xref:System.CommandLine.CommandLineConfiguration> makes testing as well as many extensibility scenarios easier than using `System.Console`. It exposes two `TextWriter` properties: `Output` and `Error`. They can be set to any `TextWriter` instance, such as a `StringWriter`, which can be used to capture output for testing.
24+
25+
Let's define a simple command that writes to standard output:
26+
27+
:::code language="csharp" source="snippets/configuration/csharp/Program.cs" id="setaction" :::
28+
29+
And let's use `CommandLineConfiguration` to capture the output:
30+
31+
:::code language="csharp" source="snippets/configuration/csharp/Program.cs" id="captureoutput" :::
32+
33+
## EnablePosixBundling
34+
35+
[Bundling](syntax.md#bundling-options) of single-character options is enabled by default, but you can disable it by setting the <xref:System.CommandLine.CommandLineConfiguration.EnablePosixBundling> property to `false`.
36+
37+
## ProcessTerminationTimeout
38+
39+
[Process termination timeout](parse-and-invoke.md#process-termination-timeout) can be configured via the <xref:System.CommandLine.CommandLineConfiguration.ProcessTerminationTimeout> property. The default value is 2 seconds.
40+
41+
## ResponseFileTokenReplacer
42+
43+
[Response files](syntax.md#response-files) are enabled by default, but you can disable them by setting the <xref:System.CommandLine.CommandLineConfiguration.ResponseFileTokenReplacer> property to `null`. You can also provide a custom implementation to customize how response files are processed.
44+
45+
## EnableDefaultExceptionHandler
46+
47+
By default, all unhandled exceptions thrown during invocation of a command are caught and reported to the user. This behavior can be disabled by setting the <xref:System.CommandLine.CommandLineConfiguration.EnableDefaultExceptionHandler> property to `false`. This is useful when you want to handle exceptions in a custom way, such as logging them or providing a different user experience.
48+
49+
## Derived classes
50+
51+
<xref:System.CommandLine.CommandLineConfiguration> is not sealed, so you can derive from it to add custom properties or methods. This is useful when you want to provide additional configuration options specific to your application.
52+
53+
## See also
54+
55+
[System.CommandLine overview](index.md)

docs/standard/commandline/dependency-injection.md

Lines changed: 0 additions & 37 deletions
This file was deleted.

docs/standard/commandline/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ To get started with System.CommandLine, see the following resources:
4545
To learn more, see the following resources:
4646

4747
* [How to parse and invoke the result](parse-and-invoke.md)
48-
* [How to bind arguments to handlers](model-binding.md)
49-
* [How to configure help in System.CommandLine](help.md)
48+
* [How to customize parsing and validation](parsing-and-validation.md)
49+
* [How to configure the parser](command-line-configuration.md)
50+
* [How to customize help](help.md)
5051
* [How to enable and customize tab completion](tab-completion.md)
51-
* [How to configure dependency injection](dependency-injection.md)
5252
* [Command-line design guidance](design-guidance.md)
5353
* [System.CommandLine API reference](xref:System.CommandLine)

docs/standard/commandline/model-binding.md

Lines changed: 0 additions & 165 deletions
This file was deleted.

docs/standard/commandline/parse-and-invoke.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
---
22
title: "How to parse and invoke the result"
33
description: "Learn how to get parsed values and define actions for your commands."
4-
ms.date: 04/07/2022
4+
ms.date: 16/06/2025
55
no-loc: [System.CommandLine]
66
helpviewer_keywords:
77
- "command line interface"
88
- "command line"
99
- "System.CommandLine"
1010
---
1111

12-
# Parsing and invocation
12+
# Parsing and invocation in System.CommandLine
1313

1414
[!INCLUDE [scl-preview](../../../includes/scl-preview.md)]
1515

@@ -37,9 +37,17 @@ The <xref:System.CommandLine.Parsing.ParseResult.GetValue%2A> method allows you
3737

3838
:::code language="csharp" source="snippets/model-binding/csharp/Program.cs" id="getvalue" :::
3939

40-
You can also get values by name, but this requires you to specify the type of the value you want to get:
40+
You can also get values by name, but this requires you to specify the type of the value you want to get.
4141

42-
:::code language="csharp" source="snippets/model-binding/csharp/Program.cs" id="getvaluebyname" :::
42+
The following example uses C# collection initializers to create a root command:
43+
44+
:::code language="csharp" source="snippets/model-binding/csharp/Program.cs" id="collectioninitializersyntax" :::
45+
46+
And then it uses the `GetValue` method to get the values by name:
47+
48+
:::code language="csharp" source="snippets/model-binding/csharp/Program.cs" id="lambdanames" :::
49+
50+
This overload of `GetValue` gets the parsed or default value for the specified symbol name, in the context of parsed command (not entire symbol tree). It accepts the symbol name, not an [alias](syntax.md#aliases).
4351

4452
### Parse errors
4553

@@ -108,3 +116,8 @@ The exit code is an integer value returned by an action indicating its success o
108116
Every `SetAction` method has an overload that accepts a delegate returning an `int` exit code where the exit code needs to be provided in explicit way and an overload that returns `0`.
109117

110118
:::code language="csharp" source="snippets/model-binding/csharp/ReturnExitCode.cs" id="returnexitcode" :::
119+
120+
## See also
121+
122+
[How to customize parsing and validation in System.CommandLine](parsing-and-validation.md)
123+
[System.CommandLine overview](index.md)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
title: How to customize parsing and validation in System.CommandLine
3+
description: "Learn how to customize parsing and validation with the System.Commandline library."
4+
ms.date: 06/16/2025
5+
no-loc: [System.CommandLine]
6+
helpviewer_keywords:
7+
- "command line interface"
8+
- "command line"
9+
- "System.CommandLine"
10+
ms.topic: how-to
11+
---
12+
# How to customize parsing and validation in System.CommandLine
13+
14+
[!INCLUDE [scl-preview](../../../includes/scl-preview.md)]
15+
16+
By default, System.CommandLine provides a set of built-in parsers that can parse many common types:
17+
18+
* `bool`
19+
* `byte` and `sbyte`
20+
* `short` and `ushort`
21+
* `int` and `uint`
22+
* `long` and `ulong`
23+
* `float` and `double`
24+
* `decimal`
25+
* `DateTime` and `DateTimeOffset`
26+
* `DateOnly`and `TimeOnly`
27+
* `Guid`,
28+
* <xref:System.IO.FileSystemInfo>, <xref:System.IO.FileInfo>, and <xref:System.IO.DirectoryInfo>
29+
* enums
30+
* **arrays and lists** of the above types
31+
32+
Other types are not supported, but you can create custom parsers for them. You can also validate the parsed values, which is useful when you want to ensure that the input meets certain criteria.
33+
34+
## Validators
35+
36+
Every option, argument, and command can have one or more validators. Validators are used to ensure that the parsed value meets certain criteria. For example, you can validate that a number is positive, or that a string is not empty. You can also create complex validators that check against multiple conditions.
37+
38+
Every symbol type in System.CommandLine has a `Validators` property that contains a list of validators. The validators are executed after the input is parsed, and they can report an error if the validation fails.
39+
40+
To provide custom validation code, call <xref:System.CommandLine.Option.Validators.Add%2A> on your option or argument (or command), as shown in the following example:
41+
42+
:::code language="csharp" source="snippets/model-binding/csharp/AddValidator.cs" id="delayOption" :::
43+
44+
System.CommandLine provides a set of built-in validators that can be used to validate common types:
45+
- `AcceptExistingOnly` - configures given option or argument to accept only values corresponding to an existing file or directory.
46+
- `AcceptLegalFileNamesOnly` - configures given option or argument to accept only values representing legal file names.
47+
- `AcceptOnlyFromAmong` - configures given option or argument to accept only values from a specified set of values.
48+
49+
## Custom parsers
50+
51+
Custom parsers are required to parse types with no default parser, such as complex types. They can also be used to parse supported types in a different way than the built-in parsers.
52+
53+
Suppose you have a `Person` type:
54+
55+
:::code language="csharp" source="snippets/model-binding/csharp/ComplexType.cs" id="persontype" :::
56+
57+
You can just read the values and create an instance of `Person` in the command action:
58+
59+
:::code language="csharp" source="snippets/model-binding/csharp/ComplexType.cs" id="setaction" :::
60+
61+
With the custom parser, you can get a custom type the same way you get primitive values:
62+
63+
:::code language="csharp" source="snippets/model-binding/csharp/ParseArgument.cs" id="personoption" :::
64+
65+
If you want to parse as well as validate the input, use the `CustomParser` delegate, as shown in the following example:
66+
67+
:::code language="csharp" source="snippets/model-binding/csharp/ParseArgument.cs" id="delayOption" :::
68+
69+
Here are some examples of what you can do with `CustomParser` that you can't do with a validator:
70+
71+
* Parsing of other kinds of input strings (for example, parse "1,2,3" into `int[]`).
72+
73+
* Dynamic arity. For example, you have two arguments that are defined as string arrays, and you have to handle a sequence of strings in the command line input. The <xref:System.CommandLine.Parsing.ArgumentResult.OnlyTake%2A?displayProperty=nameWithType> method enables you to dynamically divide up the input strings between the arguments.
74+
75+
## See also
76+
77+
[How to parse and invoke the result](parse-and-invoke.md)
78+
[System.CommandLine overview](index.md)

0 commit comments

Comments
 (0)