tôi phát triển của riêng tôi, đó là phù hợp hơn cho nhu cầu của tôi, cảm ơn vì mã của bạn:
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
}
}
@Josh: +1 cho nỗ lực. Bạn cũng có thể làm cho AddQuery một phương thức của lớp Uri hoặc UriBuilder (hiện có trong khung công tác) - chỉ là một gợi ý. – shahkalpesh
Yep cũng sẽ hoạt động, tôi đã thực sự nghĩ rằng điều này sẽ bao trùm UriBuilder, nhưng không có lý do cụ thể nào tôi đi theo cách tiếp cận này – JoshBerke
Josh, tôi thực sự đánh giá cao nỗ lực của bạn. Tôi chắc chắn sẽ sử dụng nó một lần. Thời gian cụ thể này tôi tìm thấy mã tôi đăng dưới đây thuận tiện hơn với nhu cầu của tôi. Cảm ơn rất nhiều! – Shimmy