是否有一个 URL 生成器也支持请求参数串联?

发布于 2024-07-22 11:55:40 字数 301 浏览 5 评论 0原文

我想要实现如下目标:

UrlBuilder ub = new UrlBuilder("http://www.google.com/search");
ub.Parameters.Add("q","request");
ub.Parameters.Add("sourceid","ie8");

string uri = ub.ToString(); //http://www.google.com/search?q=request&sourceid=ie8

.NET 中有什么东西吗,或者我必须创建自己的东西?

I want to achieve something like the following:

UrlBuilder ub = new UrlBuilder("http://www.google.com/search");
ub.Parameters.Add("q","request");
ub.Parameters.Add("sourceid","ie8");

string uri = ub.ToString(); //http://www.google.com/search?q=request&sourceid=ie8

Is there anything in .NET, or I will have to create my own?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦毁影碎の 2024-07-29 11:55:40

据我所知,没有任何东西存在。 这是一些简单的东西,可以满足您的需求。 用法是:

        UrlBuilder ub = new UrlBuilder("www.google.com/search")
        .AddQuery("q", "request")
        .AddQuery("sourceid", "ie8");

        string url=ub.ToString();

==

代码是:

    public class UrlBuilder
    {
        private string _authority;
        private string _host;
        private int? _port;
        private Dictionary<string, object> _query = new Dictionary<string, object>();

        public UrlBuilder(string host)
            : this("http", host, null)
        {

        }
        public UrlBuilder(string authority, string host)
            : this(authority, host, null)
        {
        }
        public UrlBuilder(string authority, string host, int? port)
        {
            this._authority = authority;
            this._host = host;
            this._port = port;
        }

        public UrlBuilder AddQuery(string key, object value)
        {
            this._query.Add(key, value);
            return this;
        }

        public override string ToString()
        {
            string url = _authority + "://" + _host;
            if (_port.HasValue)
            {
                url += ":" + _port.ToString();
            }


            return AppendQuery(url);
        }

        private string AppendQuery(string url)
        {
            if (_query.Count == 0)
            {
                return url;
            }

            url += "?";
            bool isNotFirst = false;
            foreach (var key in this._query.Keys)
            {
                if (isNotFirst)
                {
                    url += "&";
                }
                url += HttpUtility.UrlEncode(key) + "=" + HttpUtility.UrlEncode(this._query[key].ToString());
                isNotFirst = true;
            }

            return url;
        }
    }
}

Nothing exists that I know of. Here's something simple which does what you want. Usage would be:

        UrlBuilder ub = new UrlBuilder("www.google.com/search")
        .AddQuery("q", "request")
        .AddQuery("sourceid", "ie8");

        string url=ub.ToString();

==

Code is:

    public class UrlBuilder
    {
        private string _authority;
        private string _host;
        private int? _port;
        private Dictionary<string, object> _query = new Dictionary<string, object>();

        public UrlBuilder(string host)
            : this("http", host, null)
        {

        }
        public UrlBuilder(string authority, string host)
            : this(authority, host, null)
        {
        }
        public UrlBuilder(string authority, string host, int? port)
        {
            this._authority = authority;
            this._host = host;
            this._port = port;
        }

        public UrlBuilder AddQuery(string key, object value)
        {
            this._query.Add(key, value);
            return this;
        }

        public override string ToString()
        {
            string url = _authority + "://" + _host;
            if (_port.HasValue)
            {
                url += ":" + _port.ToString();
            }


            return AppendQuery(url);
        }

        private string AppendQuery(string url)
        {
            if (_query.Count == 0)
            {
                return url;
            }

            url += "?";
            bool isNotFirst = false;
            foreach (var key in this._query.Keys)
            {
                if (isNotFirst)
                {
                    url += "&";
                }
                url += HttpUtility.UrlEncode(key) + "=" + HttpUtility.UrlEncode(this._query[key].ToString());
                isNotFirst = true;
            }

            return url;
        }
    }
}
桜花祭 2024-07-29 11:55:40

UriBuilder 类有帮助吗?

它没有任何方法来添加查询字符串参数。 查看查询属性来设置值。

编辑:请参阅 UriTemplate 类。

Does the UriBuilder class help?

It doesn't have any method to add querystring parameters. Look at Query property to set values.

EDIT: See UriTemplate class.

放赐 2024-07-29 11:55:40

我自己开发的,更适合我的需求,感谢您的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;

namespace Utils
{
    public class ParameterCollectionBuilder : NameValueCollection
    {
        #region NameValueCollection Implementation
        public ParameterCollectionBuilder() : base() { }
        public ParameterCollectionBuilder(string uri)
        {
            Init(uri);
        }
        public ParameterCollectionBuilder(Uri uri) : this(uri.OriginalString) { }
        public ParameterCollectionBuilder(NameValueCollection baseCollection)
        {
            foreach (string key in baseCollection.Keys) this[key] = baseCollection[key];
            Init(ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseCollection"></param>
        /// <param name="uri"></param>
        /// <remarks>Note: any existing params in the uri will override the params in the collection.</remarks>
        public ParameterCollectionBuilder(NameValueCollection baseCollection, string uri)
        {
            foreach (string key in baseCollection.Keys) this[key] = baseCollection[key];
            Init(uri);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseCollection"></param>
        /// <param name="uri"></param>
        /// <remarks>Note: any existing params in the uri will override the params in the collection.</remarks>
        public ParameterCollectionBuilder(NameValueCollection baseCollection, Uri uri) : this(baseCollection, uri.OriginalString) { }

        public override string ToString()
        {
            return Prefix + Query + Suffix;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <remarks>Overides existing values.</remarks>
        public new void Add(string name, object value)
        {
            Set(name, GetString(value));
        }

        /// <summary>
        /// Add an array of key-value pairs separated by colon char ':'.
        /// </summary>
        /// <param name="names">Invalid items will be ignored.</param>
        public void AddRange(string[] names)
        {
            rangeFlag = true;
            for (int i = 0; i < names.Length; i++)
            {
                string item = names[i];
                item = item.Replace("?", "");
                item = item.Replace("&", "");
                item = item.Replace("=", ":");
                string[] pair = item.Split(':');
                if (pair.Length == 2) Set(pair[0], pair[1]);                
            }
            InitUri(FullString);
            rangeFlag = false;
        }

        public void AppendQueryString(string query)
        {
            Add(BuildCollection(query));
        }

        public void RemoveRange(string[] keys)
        {
            rangeFlag = true;
            foreach (string key in keys)
            {
                Remove(key);  
            } 
            InitUri(FullString);
            rangeFlag = false;
        }


        bool rangeFlag = false;
        public new void Set(string name, object value)
        {
            base.Set(name, GetString(value));
            if (!rangeFlag && Uri != null) InitUri(FullString);
        }

        public override void Remove(string name)
        {
            base.Remove(name);
            if (!rangeFlag && Uri != null) InitUri(FullString);
        }

        public override void Clear()
        {
            base.Clear();
            if (Uri != null) InitUri(FullString);
        }

        #endregion NameValueCollection Implementation

        static string ParseQuery(string uri)
        {
            string query = "";

            if (!uri.Contains('=')) return query;

            int
                start = 0,
                end = uri.Length;

            if (uri.Contains('?')) start = uri.IndexOf('?');
            if (uri.Contains(':')) end = uri.LastIndexOf(':');

            query = uri.Substring(start, (start < end ? end : uri.Length) - start);
            return query;
        }

        void Init(string uri)
        {
            if (Uri == null)
            {
                InitUri(uri);
            }
            OriginalQuery = ParseQuery(uri);
            int qIndex = string.IsNullOrEmpty(OriginalQuery) ? uri.Length : uri.IndexOf(OriginalQuery);
            Prefix = uri.Substring(0, qIndex);
            Suffix = uri.Substring(qIndex + OriginalQuery.Length);
            Merge(OriginalQuery);
        }

        void Merge(string query)
        {
            NameValueCollection col = BuildCollection(query);
            foreach (string key in col.Keys)
            {
                string value = col[key];
                if (!string.IsNullOrEmpty(value)) this[key] = value;
            }
        }
        void InitUri(string uri)
        {
            try
            {
                Uri = new Uri(uri);
            }
            catch { }
        }

        static string GetString(object value)
        {
            return value is string ? value as string : value.ToString();
        }

        static NameValueCollection BuildCollection(string query)
        {
            NameValueCollection collection = new NameValueCollection();
            if (string.IsNullOrEmpty(query) || !query.Contains('=')) return new NameValueCollection();

            //Prepare string
            query = query.ToLower();
            if (!query.StartsWith("?"))
            {
                if (query.Contains('?')) query = query.Substring(query.IndexOf('?'));
            }
            query = query.Replace("?", "");

            foreach (string pair in query.Split('&'))
            {
                string[] separated = pair.Split('=');
                if (separated.Length == 2) collection[separated[0]] = separated[1];
            }

            return collection;
        }

        static string BuildQuery(NameValueCollection parameters)
        {
            string query = "";
            Char separator = '?';
            bool first = true;
            foreach (string key in parameters.Keys)
            {
                query += string.Format("{0}{1}={2}", separator, key, parameters[key]);
                if (first)
                {
                    first = false;
                    separator = '&';
                }
            }
            return query;
        }

        #region Properties
        public Uri Uri { get; private set; }

        public string Prefix { get; private set; }
        public string OriginalQuery { get; private set; }
        public string Suffix { get; private set; }
        public string OriginalString
        {
            get
            {
                return Prefix + OriginalQuery + Suffix;
            }
        }
        public string Query
        {
            get
            {
                return BuildQuery(this);
            }
        }
        public string FullString
        {
            get
            {
                return ToString();
            }
        }
        #endregion Properties
    }
}

I developed my own, that's more suitable for my needs, thanks for your code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;

namespace Utils
{
    public class ParameterCollectionBuilder : NameValueCollection
    {
        #region NameValueCollection Implementation
        public ParameterCollectionBuilder() : base() { }
        public ParameterCollectionBuilder(string uri)
        {
            Init(uri);
        }
        public ParameterCollectionBuilder(Uri uri) : this(uri.OriginalString) { }
        public ParameterCollectionBuilder(NameValueCollection baseCollection)
        {
            foreach (string key in baseCollection.Keys) this[key] = baseCollection[key];
            Init(ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseCollection"></param>
        /// <param name="uri"></param>
        /// <remarks>Note: any existing params in the uri will override the params in the collection.</remarks>
        public ParameterCollectionBuilder(NameValueCollection baseCollection, string uri)
        {
            foreach (string key in baseCollection.Keys) this[key] = baseCollection[key];
            Init(uri);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseCollection"></param>
        /// <param name="uri"></param>
        /// <remarks>Note: any existing params in the uri will override the params in the collection.</remarks>
        public ParameterCollectionBuilder(NameValueCollection baseCollection, Uri uri) : this(baseCollection, uri.OriginalString) { }

        public override string ToString()
        {
            return Prefix + Query + Suffix;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <remarks>Overides existing values.</remarks>
        public new void Add(string name, object value)
        {
            Set(name, GetString(value));
        }

        /// <summary>
        /// Add an array of key-value pairs separated by colon char ':'.
        /// </summary>
        /// <param name="names">Invalid items will be ignored.</param>
        public void AddRange(string[] names)
        {
            rangeFlag = true;
            for (int i = 0; i < names.Length; i++)
            {
                string item = names[i];
                item = item.Replace("?", "");
                item = item.Replace("&", "");
                item = item.Replace("=", ":");
                string[] pair = item.Split(':');
                if (pair.Length == 2) Set(pair[0], pair[1]);                
            }
            InitUri(FullString);
            rangeFlag = false;
        }

        public void AppendQueryString(string query)
        {
            Add(BuildCollection(query));
        }

        public void RemoveRange(string[] keys)
        {
            rangeFlag = true;
            foreach (string key in keys)
            {
                Remove(key);  
            } 
            InitUri(FullString);
            rangeFlag = false;
        }


        bool rangeFlag = false;
        public new void Set(string name, object value)
        {
            base.Set(name, GetString(value));
            if (!rangeFlag && Uri != null) InitUri(FullString);
        }

        public override void Remove(string name)
        {
            base.Remove(name);
            if (!rangeFlag && Uri != null) InitUri(FullString);
        }

        public override void Clear()
        {
            base.Clear();
            if (Uri != null) InitUri(FullString);
        }

        #endregion NameValueCollection Implementation

        static string ParseQuery(string uri)
        {
            string query = "";

            if (!uri.Contains('=')) return query;

            int
                start = 0,
                end = uri.Length;

            if (uri.Contains('?')) start = uri.IndexOf('?');
            if (uri.Contains(':')) end = uri.LastIndexOf(':');

            query = uri.Substring(start, (start < end ? end : uri.Length) - start);
            return query;
        }

        void Init(string uri)
        {
            if (Uri == null)
            {
                InitUri(uri);
            }
            OriginalQuery = ParseQuery(uri);
            int qIndex = string.IsNullOrEmpty(OriginalQuery) ? uri.Length : uri.IndexOf(OriginalQuery);
            Prefix = uri.Substring(0, qIndex);
            Suffix = uri.Substring(qIndex + OriginalQuery.Length);
            Merge(OriginalQuery);
        }

        void Merge(string query)
        {
            NameValueCollection col = BuildCollection(query);
            foreach (string key in col.Keys)
            {
                string value = col[key];
                if (!string.IsNullOrEmpty(value)) this[key] = value;
            }
        }
        void InitUri(string uri)
        {
            try
            {
                Uri = new Uri(uri);
            }
            catch { }
        }

        static string GetString(object value)
        {
            return value is string ? value as string : value.ToString();
        }

        static NameValueCollection BuildCollection(string query)
        {
            NameValueCollection collection = new NameValueCollection();
            if (string.IsNullOrEmpty(query) || !query.Contains('=')) return new NameValueCollection();

            //Prepare string
            query = query.ToLower();
            if (!query.StartsWith("?"))
            {
                if (query.Contains('?')) query = query.Substring(query.IndexOf('?'));
            }
            query = query.Replace("?", "");

            foreach (string pair in query.Split('&'))
            {
                string[] separated = pair.Split('=');
                if (separated.Length == 2) collection[separated[0]] = separated[1];
            }

            return collection;
        }

        static string BuildQuery(NameValueCollection parameters)
        {
            string query = "";
            Char separator = '?';
            bool first = true;
            foreach (string key in parameters.Keys)
            {
                query += string.Format("{0}{1}={2}", separator, key, parameters[key]);
                if (first)
                {
                    first = false;
                    separator = '&';
                }
            }
            return query;
        }

        #region Properties
        public Uri Uri { get; private set; }

        public string Prefix { get; private set; }
        public string OriginalQuery { get; private set; }
        public string Suffix { get; private set; }
        public string OriginalString
        {
            get
            {
                return Prefix + OriginalQuery + Suffix;
            }
        }
        public string Query
        {
            get
            {
                return BuildQuery(this);
            }
        }
        public string FullString
        {
            get
            {
                return ToString();
            }
        }
        #endregion Properties
    }
}
栀梦 2024-07-29 11:55:40

我建议您查看关于 CodeProject 的这篇文章。

作者扩展了 System.UriBuilder 类并添加了一个QueryString 属性的行为方式与 HttpRequest 大致相同.QueryString 属性。

使用此类,您的示例将变为:

UrlBuilder ub = new UrlBuilder("http://www.google.com/search");
ub.QueryString.Add("q", "request");
ub.QueryString.Add("sourceid", "ie8");
string uri = ub.ToString(); //http://www.google.com/search?q=request&sourceid=ie8

它没有像 流畅的界面 ="https://stackoverflow.com/questions/908507/is-there-a-url-builder-that-supports-request-paramater-concatenation-as-well/908552#908552">乔希的解决方案但是可以很容易地扩展到包括一个。

I would recommend you take a look at this article on CodeProject.

The author has extended the System.UriBuilder class and added a QueryString property that behaves in much the same way as the HttpRequest.QueryString property.

Using this class your example would become:

UrlBuilder ub = new UrlBuilder("http://www.google.com/search");
ub.QueryString.Add("q", "request");
ub.QueryString.Add("sourceid", "ie8");
string uri = ub.ToString(); //http://www.google.com/search?q=request&sourceid=ie8

It doesn't have a fluent interface like Josh's solution but could be easily extended to include one.

苹果你个爱泡泡 2024-07-29 11:55:40

使用 Flurl [披露:我是作者],您的示例将如下所示:

string uri = "http://www.google.com/search"
  .SetQueryParams(new { q = "request", sourceid = "ie8" });

基本 URL 生成器可通过 NuGet 获取:

PM> Install-Package Flurl

还有一个新的配套库,它使用 flutter 扩展了 Flurl ,可测试 HTTP:

PM>; 安装包 Flul.Http

With Flurl [disclosure: I'm the author], your example would look like this:

string uri = "http://www.google.com/search"
  .SetQueryParams(new { q = "request", sourceid = "ie8" });

The basic URL builder is available via NuGet:

PM> Install-Package Flurl

There's also a new companion lib that extends Flurl with fluent, testable HTTP:

PM> Install-Package Flurl.Http

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文