2009-05-26 15 views
8

मैं निम्न की तरह कुछ हासिल करना चाहता हूं:क्या कोई यूआरएल बिल्डर है जो अनुरोध पैरामीटर कॉन्सटेनेशन का भी समर्थन करता है?

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 में कुछ भी है, या मुझे अपना खुद का बनाना होगा?

उत्तर

11

कुछ भी मौजूद नहीं है जो मुझे पता है। यहां कुछ आसान है जो आप चाहते हैं। प्रयोग होगा:

 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; 
     } 
    } 
} 
+0

@ जोश: प्रयास के लिए +1। आप AddQuery को उड़ी या उरीबिल्डर वर्ग (ढांचे में मौजूदा) की एक विधि भी बना सकते हैं - बस एक सुझाव। – shahkalpesh

+0

हां जो भी काम करेगा, मैं वास्तव में सोच रहा था कि यह उरीबिल्डर को लपेटेगा, लेकिन किसी विशेष कारण के लिए मैं इस दृष्टिकोण को – JoshBerke

+0

जोश चला गया, मैं वास्तव में आपके प्रयास की सराहना करता हूं। मैं निश्चित रूप से इसे एक बार उपयोग करूँगा। यह विशेष समय मुझे लगता है कि मैंने जो कोड पोस्ट किया है, वह मेरी आवश्यकताओं के साथ अधिक सुविधा प्रदान करता है। धन्यवाद, बहुत सारे! – Shimmy

1

क्या UriBuilder कक्षा सहायता करता है?

इसमें क्वेरीस्ट्रिंग पैरामीटर जोड़ने की कोई विधि नहीं है। मान सेट करने के लिए क्वेरी गुण देखें।

संपादित करें: UriTemplate कक्षा देखें।

+0

आपके मूल प्रश्न के लिए, मुझे आपके लिए विशिष्ट कुछ भी नहीं मिला है। क्या आपको क्वेरीस्ट्रिंग पैरामीटर में शामिल होने की आवश्यकता नहीं है? – shahkalpesh

+0

ऐसा लगता है कि यह माइक्रोसॉफ्ट (आधा दिल वाला) है जो शिमी की कार्यक्षमता को कार्यान्वित करने का प्रयास करता है, यह केवल उपयोग करने योग्य होने से कम हो जाता है। – Abacus

1

मैं अपने ही विकसित की है, कि मेरी जरूरतों के लिए अधिक उपयुक्त है, अपने कोड के लिए धन्यवाद:

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 
    } 
} 
1

मैं आपको कोडप्रोजेक्ट पर this आलेख देखने की सलाह दूंगा।

लेखक ने System.UriBuilder कक्षा बढ़ा दी है और एक प्रश्नोत्तरी संपत्ति जोड़ा है जो 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 

यह एक fluent interfaceJosh's solution की तरह नहीं है लेकिन आसानी से एक में शामिल करने के लिए बढ़ाया जा सकता है। साथ

+1

उस लेख में कोड बहुत अच्छा नहीं है। यह क्वेरी स्ट्रिंग मानों का कोई एन्कोडिंग/डिकोडिंग नहीं करता है। तो आप इसके साथ परेशानी में भागने के लिए बाध्य हैं। –

0

Flurl [प्रकटीकरण: मैं लेखक हूँ]:

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

बुनियादी URL निर्माता NuGet के माध्यम से उपलब्ध है:

PM> Install-Package Flurl

वहाँ भी है, अपने उदाहरण इस प्रकार दिखाई देगा एक नया साथी lib जो fluent, testable HTTP:

के साथ Flurl को बढ़ाता है

संबंधित मुद्दे

 संबंधित मुद्दे