2

I've stored all URLs in my application with "http://" - I now need to go through and replace all of them with "https:". Right now I have:

    foreach (var link in links)
        {
            if (link.Contains("http:"))
            {
                /// do something, slice or replace or what?
            }
        }

I'm just not sure what the best way to update the string would be. How can this be done?

SB2055
  • 12,272
  • 32
  • 97
  • 202

5 Answers5

15

If you're dealing with uris, you probably want to use UriBuilder since doing a string replace on structured data like URIs is not a good idea.

var builder = new UriBuilder(link);
builder.Scheme = "https";
Uri modified = builder.Uri;

It's not clear what the type of links is, but you can create a new collection with the modified uris using linq:

IEnumerable<string> updated = links.Select(link => {
    var builder = new UriBuilder(link);
    builder.Scheme = "https";
    return builder.ToString();
});
Lee
  • 142,018
  • 20
  • 234
  • 287
  • 2
    You beat me -- I was going to say the same thing. The question is really asking how to change the scheme of a URL, and while a string replacement is probably safe, this is the better way to accomplish the goal. – Ryan M Jul 30 '13 at 21:05
  • You can also use an object initializer to create the `UriBuilder` as an expression instead of as statements. That would let you, for example, use a query expression: `var updated = from link in links select new UriBuilder(link) { Scheme = "https" }.ToString();` – Quartermeister Jul 31 '13 at 13:39
  • 1
    @ranieuwe ist very correct. Easiest solution: Set `builder.Port=-1` after (!) changing the scheme to https. This will remove the port 80 information and the default https port will be used. – Jpsy Sep 24 '18 at 14:35
11

The problem is your strings are in a collection, and since strings are immutable you can't change them directly. Since you didn't specify the type of links (List? Array?) the right answer will change slightly. The easiest way is to create a new list:

links = links.Select(link => link.Replace("http://","https://")).ToList();

However if you want to minimize the number of changes and can access the string by index you can just loop through the collection:

for(int i = 0; i < links.Length; i++ )
{
    links[i] = links[i].Replace("http://","https://");
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
1

based on your current code, link will not be replace to anything you want because it is read only (see here: Why can't I modify the loop variable in a foreach?). instead use for

for(int a = 0; a < links.Length; a++ )
{
    links[a] = links[a].Replace("http:/","https:/")
}
Community
  • 1
  • 1
John Woo
  • 258,903
  • 69
  • 498
  • 492
1

http://myserver.xom/login.aspx?returnurl=http%3a%2f%2fmyserver.xom%2fmyaccount.aspx&q1=a%20b%20c&q2=c%2b%2b

What about the urls having also url in the querystring part? I think we should also replace them. And because of the url encoding-escaping this is the hard part of the job.

private void BlaBla()
{
    // call the replacing function
    Uri myNewUrl = ConvertHttpToHttps(myOriginalUrl);
}

private Uri ConvertHttpToHttps(Uri originalUri)
{
    Uri result = null;
    int httpsPort = 443;// if needed assign your own value or implement it as parametric 

    string resultQuery = string.Empty;
    NameValueCollection urlParameters = HttpUtility.ParseQueryString(originalUri.Query);

    if (urlParameters != null && urlParameters.Count > 0)
    {
        StringBuilder sb = new StringBuilder();
        foreach (string key in urlParameters)
        {
            if (sb.Length > 0)
                sb.Append("&");

            string value = urlParameters[key].Replace("http://", "https://");
            string valuEscaped = Uri.EscapeDataString(value);// this is important
            sb.Append(string.Concat(key, "=", valuEscaped));
        }
        resultQuery = sb.ToString();
    }

    UriBuilder resultBuilder = new UriBuilder("https", originalUri.Host, httpsPort, originalUri.AbsolutePath);
    resultBuilder.Query = resultQuery;

    result = resultBuilder.Uri;
    return result;
}
yvzman
  • 150
  • 1
  • 4
0

Use string.Replace and some LINQ:

var httpsLinks = links.Select(l=>l.Replace("http://", "https://");
zmbq
  • 38,013
  • 14
  • 101
  • 171