开发者

What is the best way of performing a string concatenation in making a dynamic URL?

I am constructing a URL at runtime. So far I have done like

public string BuildURLAndNavigate(CodeType codeType)
{    
    string vURL = string.Empty; 

    string mstrNavServer = "http://some.com/nav";
    vURL = ConcatenateString(mstrNavServer , "/somepage.asp?app=myapp");

    //Build Code Type
    switch (codeType)
    {
   开发者_开发百科 case CodeType.Series:
        vURL = ConcatenateString(vURL , "&tools=ser");
        break; 
    case CodeType.DataType:
        vURL = ConcatenateString(vURL , "&tools=dt");
        break;
    }

    //build version 
    string VER_NUM = "5.0";
    vURL = ConcatenateString(vURL , ConcatenateString("&vsn=" , VER_NUM));         
    return vURL;
    }

    private string ConcatenateString(string expression1, string expression2)
    {
        return string.Concat(expression1 + expression2);
    }

But I am not happy with the one I am doing.

I am sure that there is definitely a best practice / better approach than this.

Kindly help me out in guiding for the same.

Thanks


You could use a StringBuilder:

public string BuildURLAndNavigate(CodeType codeType) 
{  
    StringBuilder vURL = new StringBuilder();

    vURL.Append("http://some.com/nav"); 
    vURL.Append("/somepage.asp?app=myapp"); 

    //Build Code Type 
    switch (codeType) 
    { 
        case CodeType.Series: 
            vURL.Append("&tools=ser"); 
            break;  
        case CodeType.DataType: 
            vURL.Append("&tools=dt"); 
            break; 
    } 

    //build version  
    string VER_NUM = "5.0"; 
    vURL.AppendFormat("&vsn={0}", VER_NUM);          

    return vURL.ToString(); 
} 


Never build urls using strings, string builders, string concatenations.

You could start by defining a custom collection which will take care of properly URL encoding any value being added to it:

public class HttpNameValueCollection : NameValueCollection
{
    public override void Add(string name, string value)
    {
        base.Add(name, HttpUtility.UrlEncode(value));
    }

    public override string ToString()
    {
        return string.Join("&", Keys.Cast<string>().Select(
            key => string.Format("{0}={1}", key, this[key])));
    }
}

And then simply:

public string BuildURLAndNavigate()
{
    var uriBuilder = new UriBuilder("http://some.com/nav/somepage.asp");
    var values = new HttpNameValueCollection();
    values.Add("app", "myapp");

    switch (codeType)
    {
        case CodeType.Series:
            values.Add("tools", "ser");
            break;
        case CodeType.DataType:
            values.Add("tools", "dt");
            break;
    }

    // You could even do things like this without breaking your urls
    values.Add("p", "http://www.example.com?p1=v1&p2=v2");


    string VER_NUM = "5.0";
    values.Add("vsn", VER_NUM);
    uriBuilder.Query = values.ToString();
    return uriBuilder.ToString();
}


Like Saxon Druce said: You could use a StringBuilder, but, depending on CodeType values, you could eliminate the switch too:

public string BuildURLAndNavigate(CodeType codeType) 
{  
    StringBuilder vURL = new StringBuilder();

    vURL.Append("http://some.com/nav"); 
    vURL.Append("/somepage.asp?app=myapp"); 

    //Build Code Type 
    vURL.Append(codeType == CodeType.Series ? "&tools=ser" : "&tools=dt");

    //build version  
    string VER_NUM = "5.0"; 
    vURL.AppendFormat("&vsn={0}", VER_NUM);          

    return vURL.ToString(); 
} 


Do

return string.Concat(expression1, expression2);

not

return string.Concat(expression1 + expression2);


wouldn't the right way to do that be to use the Uri-class or the UriBuilder class?

for example the Uri ctor overload Uri(Uri, string):

public Uri(
   Uri baseUri,
   string relativeUri
);


Uri baseUri = new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm");
Console.WriteLine(myUri.ToString());

http://msdn.microsoft.com/en-us/library/aa332624(v=VS.71).aspx


What you are doing is fine - it is simple and understandable. Anyone who reads the code can understand what you are doing.

In terms of performance - you are not doing much string manipulation, so unless you are building huge strings or doing this operation thousands of times a minute, you will not gain much by using StringBuilder. Before optimizing this code, test its performance. You will probably find that there are other bigger bottlenecks to work on first.

The only real comment I have is that your ConcatenateString function seems superfluous. It is not really adding anything to the code and all the call to it can simply be replaced by string.Concat. As mentioned in the answer from @abatishchev, you should be using (str1, str2) not (str1 + str2), as that defeats the reason for the call.


Yes, StringBuilder is the best solution here. You can find more information on MSDN page: http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx

StringBuilder contains very usefull methods:

StringBuilder.Append
Appends information to the end of the current StringBuilder.

StringBuilder.AppendFormat
Replaces a format specifier passed in a string with formatted text.

StringBuilder.Insert
Inserts a string or object into the specified index of the current StringBuilder.

StringBuilder.Remove
Removes a specified number of characters from the current StringBuilder.

StringBuilder.Replace
Replaces a specified character at a specified index.


I'd personally be inclined to just string.format something like that:

public string BuildURLAndNavigate(CodeType codeType)
{    
    string vURL = "http://some.com/nav/somepage.asp?app=myapp&tools={0}&vsn={1}"; 
    string codevalue = "";
    //Build Code Type
    switch (codeType)
    {
    case CodeType.Series:
        codevalue = "ser";
        break; 
    case CodeType.DataType:
        codevalue = "dt";
        break;
    }

    //build version 
    string version = "5.0";
    return string.Format(vURL, codevalue, version);
    }
}

Apologies if there are any mistakes in that, I wasn't in VS when writing it so there might be a few typos I didn't notice - you should get the idea though.

The reason I like this method is because you can immediately see what your url's overall form is which can make it a bit easier to understand roughly what the url being returned is.


In order to keep all variables at one place, could we use following solution

public string BuildURLAndNavigate(CodeType codeType) 
    {
        //code here - switch statement to calculate the codeValue

        //Anonymous type - To keep all variables at one place    
        var urlComponents = new {
                                server = "http://some.com/nav",
                                pageName="/somepage.asp?app=myapp",
                                codevalue = "", //Replace with the actual value calculated in switch statement
                                versionPart="&vsn=",
                                version = "5.0" 
                                };


        StringBuilder vURL = new StringBuilder();
        vURL.Append(urlComponents.server);
        vURL.Append(urlComponents.pageName);
        vURL.Append(urlComponents.codevalue);
        vURL.Append(urlComponents.versionPart);
        vURL.Append(urlComponents.version);
        return vURL.ToString();

    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜