1

I am working on a C# project which basically works on commands to perform certain operations. It uses CommandLineParser library to parse all these commands and respective argument.

As per the new business requirement, I need to parse an URL which contains verb and parameters.

Is there any built-in/easy way to parse URL in CommandLineParser library, that will avoid writing custom logic which I explained in below approach?


Here is my approach to solve this challenge:

Covert URL to command, then using CommandLine parser assign values to option properties.

e.g.

URL:

https://localhost:9000/Open?appId=123&appName=paint&uId=511a3434-37e0-4600-ab09-65728ac4d8fe

Implementation:

  • Custom logic to covert url to command

    open -appId 123 -name paint -uid 511a3434-37e0-4600-ab09-65728ac4d8fe
    
  • Then pass it to parser.ParseArguments

  • Here is the class structure

    [Verb("open", HelpText = "Open an application")]
    public class OpenOptions
    {
        [Option("id", "appId", Required = false, HelpText = "Application Id")]
        public int ApplicationId{ get; set; }
        [Option("name", "appName", Required = false, HelpText = "Application Name")]
        public string ApplicationName{ get; set; }
        [Option("uId", "userId", Required = true, HelpText = "User Id")]
        public Guid UserId{ get; set; }
    }
    
5
  • 1
    CommandLineParser can't easily parse the syntax of a URL. For that purpose you should take a look at the Uri class that is mentioned here. Commented Feb 14, 2023 at 7:12
  • The question is unclear. The job of CommandLineParser is to parse the command line, not the arguments themselves. You may (or may not) be able to create a custom argument parser to extract data from a specific argument. You didn't post any command line sample though, explain what you want to parse or what you want to do with it. Parsing a URL is the job of eg the Uri class or one of the many Http Utility methods in various .NET libraries Commented Feb 14, 2023 at 7:43
  • @PanagiotisKanavos, my questoin is can we parse url using command line parser? I guess I can't do it. I have to use Uri class as you said in the comment. Thanks Commented Feb 14, 2023 at 7:47
  • That's a bad question. Why not ask if you can use decimal.Parse? It's just as unrelated to URLs. You can parse URL arguments though. So what is the question? Why CommandLineParser specifically? Commented Feb 14, 2023 at 7:50
  • @PanagiotisKanavos My original question is Is there any built-in/easy way to parse URL in CommandLineParser library? If it is not there then that is ok. I have already written a code which converts url to command. Below answers also explain the same. My intension behind asking this question was to not break existing infrastructure of parsing command and just do some tweaks to support URL parsing as well. I don't think I will ever ask how to parse url using decimal.Parse Commented Feb 14, 2023 at 7:54

3 Answers 3

3

There is no out-of-the-box solution. Normally HttpUtility class (ref Get URL parameters from a string in .NET) can do the trick.

Here is the first approach:

var url = "https://localhost:9000/Open?appId=123&appName=paint&uId=511a3434-37e0-4600-ab09-65728ac4d8fe";
Uri uri = new Uri(url);
var @params = HttpUtility.ParseQueryString(uri.Query);
string? appId = @params.Get("appId");
Console.WriteLine(appId);

Will return 123, and so on with your other parameters.

The returned value will be a string type. You can eventually use Guid.TryParse to parse your Guid object and int.TryParse for an int value.

Sign up to request clarification or add additional context in comments.

9 Comments

Does that means, I need to write custom logic to get covert url to command, right? There is no straight forward way to use command line parser to parse the URL?
That is correct, a little method that takes URL and key and return the value
@PrasadTelkikar what's your actual question in the first place? A URL isn't a command line. There are a lot of classes that can parse URLs. Are you try to pass a URL as a command-line argument and have it parsed automatically? Why not use a Uri argument instead, and extract the parts afterwards?
@PanagiotisKanavos, thanks for the suggestion. Yes I will use Uri class to parse Url
If the question is how to parse query strings, there are several duplicate questions. Using HttpUtility.ParseQueryString is one option. It's still unclear what any of this has to do with command lines. It would make sense to parse a URL if you wanted to use a protocol handler for your application.
|
1

CommandLineParser is not made for parsing Uri's. But using the Uri class and Linq, this is quite easy:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var (verb, query) = ParseUri("https://localhost:9000/Open/appId=123&appName=paint&uId=511a3434-37e0-4600-ab09-65728ac4d8fe");

        var appId = query["appId"];
        var appName = query["appName"];
        var uId = query["uId"];

        Console.WriteLine($"verb='{verb}'");
        Console.WriteLine($"appId='{appId}', appName='{appName}', uId='{uId}'");
    }

    static (string verb, Dictionary<string, string> args) ParseUri(string strUri)
    {
        var uri = new Uri(strUri);

        // get the verb
        var verb = uri.Segments[1].TrimEnd('/');

        // get the query part as dictionary
        var args = uri.Segments[2].Split('&')
            .Select(s => s.Split('=')).ToDictionary(d => d[0], d => d[1]);

        return (verb, args);    
    }

}

First parsing happens by instantiating an Uri allowing to use the Segments property. Then split the query by using & and finally create a dictionary by using = to split the key/value pair.

Because query is a Dictionary, you can simply access individual query parameters like:

var appId = query["appId"];
var appName = query["appName"];
var uId = query["uId"];

Console.WriteLine($"verb='{verb}'");
Console.WriteLine($"appId='{appId}', appName='{appName}', uId='{uId}'");

which prints:

verb='Open'
appId='123', appName='paint', uId='511a3434-37e0-4600-ab09-65728ac4d8fe'


Note: In LinqPad, you can use query.Dump(verb); to visualize the result:

enter image description here

Comments

0
var link = "https://localhost:9000/Open?appId=123&appName=paint&uId=511a3434-37e0-4600-ab09-65728ac4d8fe";

var uri = new Uri(link);
var command = uri.LocalPath.TrimStart('/').ToLower();
var query = HttpUtility.ParseQueryString(uri.Query);

var sb = new StringBuilder($"{command} ");
foreach(string key in query)
{
    sb.Append($"-{key} {query.Get(key)} ");
}

var commandWithArgs = sb.ToString();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.