public void EncodesAllTypicalCharactersInUrl() { var charactersToEncode = "http://*****:*****@abcdefgh.ijk/lmnop?qrs=tuvwxyz#0123456789"; var encoder = new HtmlEncoder(); var result = encoder.HtmlEncodeEveryCharacter(charactersToEncode); Assert.AreEqual("http://user:password@abcdefgh.ijk/lmnop?qrs=tuvwxyz#0123456789", result); }
/// <summary> /// Formats the specified HTML. /// </summary> /// <param name="html">The HTML.</param> /// <returns></returns> public string Format(string html) { var encoder = new HtmlEncoder(); return(String.IsNullOrEmpty(html) ? html : Regex.Replace(html, @"([A-Za-z0-9-.]+@[A-Za-z0-9-.]+\.[A-Za-z]+)", match => encoder.HtmlEncodeEveryCharacter(match.Groups[1].Value))); }
/// <summary> /// Build the contact details into two paras of info /// </summary> protected override void CreateChildControls() { // Remember we can't be sure if any property will be supplied, but for hCard // we must label something as the "fn"... bool fnFound = false; using (HtmlGenericControl part1 = new HtmlGenericControl("p")) { using (HtmlGenericControl part2 = new HtmlGenericControl("p")) { // Add name if (this.name != null && this.name.Length > 0) { ContactInfoControl.AddString(HttpUtility.HtmlEncode(this.name), part1, "fn"); fnFound = true; } // Add description if (this.description != null && this.description.Length > 0) { ContactInfoControl.StartOnNewLine(part1); if (fnFound) { ContactInfoControl.AddString( HttpUtility.HtmlEncode(this.Description).Replace(Environment.NewLine, "<br />"), part1); } else { ContactInfoControl.AddString( HttpUtility.HtmlEncode(this.Description).Replace(Environment.NewLine, "<br />"), part1, "fn"); fnFound = true; } } // street address if (this.bs7666Address != null) { // Get XHTML of correctly-cased address if (this.bs7666Address.HasAddress()) { ContactInfoControl.StartOnNewLine(part1); using (this.addressControl = new SimpleAddressControl(this.bs7666Address)) { // control implements hCard/adr microformat this.addressControl.CssClass = "location"; // hCalendar this.addressControl.Separator = SimpleAddressControl.SeparatorHCalendar; part1.Controls.Add(this.addressControl); } // link to map if (this.showMap) { string mapPageUrl = null; if (this.mapUrl != null) { mapPageUrl = this.mapUrl.ToString(); } else { // handle backToUrl separately to ensure the page is valid. GetWebsiteMapUri correctly UrlEncodes it, // but it returns it as a Uri object which UrlDecodes it again mapPageUrl = GetWebsiteMapUrl(this.bs7666Address, this.pageDisplayName, this.PageUrl); //if (gisMapUrl != null) gisMapUrl.ToString() + "&backToUrl=" + Uri.EscapeDataString(.ToString()); } if (mapPageUrl != null) { ContactInfoControl.StartOnNewLine(part1); using (var mapLink = new HtmlAnchor()) { mapLink.InnerText = this.MapLinkText; mapLink.HRef = HttpUtility.HtmlEncode(mapPageUrl); mapLink.Attributes["data-unpublished"] = "false"; // disable website CMS warning about internal links part1.Controls.Add(mapLink); } } } } } // phones property (house style doesn't say how to present multiple phone numbers) int phonesDone = 0; foreach (var phone in this.telephones) { if (phonesDone == 0) { ContactInfoControl.StartOnNewLine(part2); } HtmlControl telContainer = null; try { if (Mobile) { telContainer = new HtmlAnchor(); ((HtmlAnchor)telContainer).HRef = "tel:" + phone.ToString(); } else { telContainer = new HtmlGenericControl("span"); } telContainer.Attributes["class"] = "tel"; // hCard // always label phone number if there's also a fax number if (!Mobile || !String.IsNullOrEmpty(this.fax)) { if (phonesDone == 0) { ContactInfoControl.AddString(Resources.TelephonePrefix, telContainer); ContactInfoControl.AddString(Resources.ContactPrefixSeparator, telContainer); } } if (phonesDone > 0) { ContactInfoControl.AddString(" or ", part2); } ContactInfoControl.AddString(ExpandAbbreviations(FormatTelephone(phone.NationalNumber)), telContainer, "value"); part2.Controls.Add(telContainer); } finally { telContainer.Dispose(); } phonesDone++; } // fax property if (this.fax != null && this.fax.Length > 0) { ContactInfoControl.StartOnNewLine(part2); HtmlGenericControl faxContainer = new HtmlGenericControl("span"); faxContainer.Attributes["class"] = "tel"; // hCard part2.Controls.Add(faxContainer); ContactInfoControl.AddString(Resources.FaxPrefix, faxContainer, "type"); ContactInfoControl.AddString(Resources.ContactPrefixSeparator, faxContainer); ContactInfoControl.AddString(ExpandAbbreviations(FormatTelephone(this.fax)), faxContainer, "value"); } // email property if (this.emailAddress != null && this.emailAddress.Length > 0) { ContactInfoControl.StartOnNewLine(part2); // Clickable text can be email address or custom text bool visibleAddress = (this.emailText == null || this.emailText.Length == 0); // Don't use HtmlAnchor because in ASP.NET 4 it URLEncodes the hashes used in entities, // making the result invalid XML which in turn breaks parsing of the page string emailLinkText; string emailHref; string emailClass = String.Empty; var encoder = new HtmlEncoder(); if (visibleAddress) { emailLinkText = encoder.HtmlEncodeEveryCharacter(this.emailAddress); } else { emailLinkText = HttpUtility.HtmlEncode(Resources.EmailPrefix + " " + this.emailText); } // Link can be to email address, or to email form if (EmailAddressTransformer != null) { var addressToTransform = new ContactEmail(this.emailAddress); if (!visibleAddress) { addressToTransform.DisplayName = this.emailText; } var transformedEmail = EmailAddressTransformer.TransformEmailAddress(addressToTransform); if (transformedEmail != null) { emailHref = HttpUtility.HtmlEncode(transformedEmail); } else { emailHref = encoder.HtmlEncodeEveryCharacter("mailto:" + this.emailAddress); } } else { emailHref = encoder.HtmlEncodeEveryCharacter("mailto:" + this.emailAddress); emailClass = "email"; // hCard } if (!fnFound) { emailClass = (emailClass + " fn").TrimStart(); fnFound = true; } // Only use prefix if email address is being shown if (visibleAddress && !Mobile) { ContactInfoControl.AddString(Resources.EmailPrefix + Resources.ContactPrefixSeparator, part2); } string emailLink = "<a href=\"" + emailHref + "\""; if (!String.IsNullOrEmpty(emailClass)) { emailLink += " class=\"" + emailClass + "\""; } emailLink += ">" + emailLinkText + "</a>"; part2.Controls.Add(new LiteralControl(emailLink)); } if (this.website != null && this.website.ToString().Length > 0) { ContactInfoControl.StartOnNewLine(part2); // Display text can be the URL or custom text bool showWebUrl = (this.websiteText == null || this.websiteText.Length == 0); // Different prefix depending on use of URL or custom text if (!Mobile) { if (showWebUrl) { ContactInfoControl.AddString(Resources.WebsitePrefix, part2); } else { ContactInfoControl.AddString(Resources.WebsiteLeadIn, part2); } } // Build link HtmlAnchor webLink = new HtmlAnchor(); webLink.HRef = HttpUtility.HtmlAttributeEncode(this.website.ToString()); webLink.Attributes["class"] = "url"; if (showWebUrl) { webLink.InnerHtml = new HtmlLinkFormatter().AbbreviateUrl(this.website); } else { webLink.InnerText = this.websiteText; } part2.Controls.Add(webLink); } // address URL if (this.addressUrl != null && this.addressUrl.ToString().Length > 0) { ContactInfoControl.StartOnNewLine(part2); HtmlAnchor addrLink = new HtmlAnchor(); addrLink.HRef = this.addressUrl.ToString(); if (this.addressUrlText != null && this.addressUrlText.Length > 0) { addrLink.InnerText = this.addressUrlText; } else { addrLink.InnerText = this.addressUrl.ToString(); } part2.Controls.Add(addrLink); } if (part1.Controls.Count > 0) { this.Controls.Add(part1); } if (part2.Controls.Count > 0) { this.Controls.Add(part2); } // hCard microformat requires "fn" property. If we marked up a suitable value, set this control to be an hCard. if (fnFound) { this.Attributes["class"] = "vcard"; } } } }