Detect and Activate Hyperlink in ASP.Net - asp.net

I have a ASP.Net page for user to post their comments. Now I want that once user posts comments if any hypelink is found in the posted text then how can we make the hyperlink clickable.
Right now we are displaying the text and hyperlikn is not clickable

Use regular expressions to find hyperlink patterns. Then re-save the content with the html a tags.
EDIT: Here is an example to get you started, Run this as a console app to see whats going on:
class Program
{
static void Main(string[] args)
{
string s = "http://www.google.com is the best site, followed then by http://www.yahoo.com";
string pattern = #"http(s)?://([\w+?\.\w+])+([a-zA-Z0-9\~\!\#\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?";
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(pattern);
System.Text.RegularExpressions.MatchCollection matches = regex.Matches(s);
for (int i = 0; i < matches.Count; i++)
{
Console.WriteLine(string.Format("{1}", matches[i].Value, matches[i].Value)); }
}
}
The regular expression pattern was taken from: http://weblogs.asp.net/farazshahkhan/archive/2008/08/09/regex-to-find-url-within-text-and-make-them-as-link.aspx

response.write("The Link")

Related

How to use the Vaadin Testbench with Rich Text Area?

I am using Vaadin Testbench (4.1.0-alpha) for designing some integration test for my application (designed in Vaadin 7.6.1).
In a window, I use a rich test area. The idea is to design a test where the value of this rich text element is changed simulating some user behaviour. But now I realize I cannot find any method for change the value of this element, neither get the current value of the element.
I have tested some methods.getHTML() gets the HTML for the component, no the HTML of the designer. getText() gets the list of elements (font colour, background and other options of the element, but not the content).
Then I expect to have specific class methods for retrieving the value. If I explore the class RichTextAreaElement, seems that no method is implemented. All code in this class is:
#ServerClass("com.vaadin.ui.RichTextArea")
public class RichTextAreaElement extends AbstractFieldElement {
}
As you can see, no method is declared.
How can I do a test where a user change the value of this rich text area? It is not implemented?
Hmm yeah, that looks like some work in progress, probably because it's a complex component with all the features it provides. Nonetheless we can workaround the limitations a bit, again making use of chrome developer tools (or similar) and some custom classes to select the components by (actually it's just the gwt-RichTextArea).
Of course this serves just as a starting point and can be further enhanced. Also I'd be very interested to see a more elegant solution if someone finds one...
Structure inspection
Test class
public class RichTextAreaTest extends TestBenchTestCase {
#Before
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "D:\\Kit\\chromedriver_win32\\chromedriver.exe");
setDriver(new ChromeDriver());
}
#After
public void tearDown() throws Exception {
// TODO uncomment below once everything works as expected
//getDriver().quit();
}
#Test
public void shouldModifyRichTextArea() throws InterruptedException {
// class to identify the editor area by
String editorClass = "gwt-RichTextArea";
// open the browser
getDriver().get("http://localhost:8080/");
// select the first rich text
RichTextAreaElement richTextArea = $(RichTextAreaElement.class).first();
// get the editor section which is where we're writing
WebElement richTextEditorArea = richTextArea.findElement(By.className(editorClass));
// click inside to make it "editable"
richTextEditorArea.click();
// send some keystrokes
richTextEditorArea.sendKeys(" + something else added by selenium");
}
}
Result:
Update for getting the value
If you simply want to get the text, the code below will do the trick:
// switch to the editor iframe
getDriver().switchTo().frame(richTextEditorArea);
// get the <body> section where the text is inserted, and print its text
System.out.println("Text =[" + findElement(By.xpath("/html/body")).getText() + "]");
Output
Text =[Some predefined text + something else added by selenium]
At the end, I was able to obtain the content of the element selecting the first iframe of the page, and searching for the body content. The final code looks like:
String currentWindow = getDriver().getWindowHandle();
getDriver().switchTo().frame(getDriver().findElement(By.tagName("iframe")));
WebElement webelement = this.findElement(By.xpath("/html/body"));
String text = webelement.getText();
getDriver().switchTo().window(currentWindow);
return text;
As I need to switch between the iframe and the window, I am only able to obtain the content of the element, not the element itself. If I return directly the element for future use, an org.openqa.selenium.StaleElementReferenceException: Element belongs to a different frame than the current one - switch to its containing frame to use it exception is obtained.
For changing the text, the solutions is very similar, only use the sendKey functions to first remove existing characters and later add the new text:
String currentWindow = getDriver().getWindowHandle();
getDriver().switchTo().frame(getDriver().findElement(By.tagName("iframe")));
WebElement webelement = this.findElement(By.xpath("/html/body"));
// Remove any previous text.
String previousText = webelement.getText();
for (int i = 0; i < previousText.length(); i++) {
webelement.sendKeys(Keys.DELETE);
}
// Set text.
webelement.sendKeys(text);
getDriver().switchTo().window(currentWindow);

sitecore wrapping for tags pipeline in fields are not working

I am using sitecore 7.2 & I have created pipeline for enclosing tags for single-line Text as below.
public class SingleLineFieldEnclosingTags
{
public void Process(RenderFieldArgs args)
{
if (args.FieldTypeKey != "single-line text" && args.FieldTypeKey != "multi-line text")
return;
args.Result.FirstPart = Helper.WrapInTags(args);
}
}
public static string WrapInTags(RenderFieldArgs args)
{
string keyInParam = args.Parameters.Where(x => x.Key.Contains("enclosingTag")).FirstOrDefault().Key;
string wrappedText = args.Result.FirstPart;
if (IsPageEditorMode)
{
return wrappedText;
}
if (keyInParam != null && keyInParam.Trim().Equals("enclosingTag"))
{
if (args.Parameters.ContainsKey(keyInParam))
{
string[] paramTags = args.Parameters[keyInParam].Split('|').Reverse().ToArray();
foreach (string tag in paramTags)
{
wrappedText = string.Concat("<", tag.Trim(), ">", wrappedText, "</", tag.Trim().Split(' ')[0], ">");
}
if (wrappedText.Contains("enclosingTag"))
{
// remove enclosing tag attribute from tags
wrappedText = Regex.Replace(wrappedText, #"enclosingTag\s*=\""\s*?.*\""", string.Empty, RegexOptions.IgnoreCase);
}
return wrappedText;
}
}
return wrappedText;
}
It is working fine, but problem comes when we edit or save any field then it save it as
<p class="intro">Do you need something specific?</p>
including enclosing tags too. and now in publish mode it display twice, thrice and so one like below.
<p class="intro"></p>
<p class="intro"></p>
<p class="intro"></p>
<p class="intro">Do you need something specific?</p>
<p></p>
<p></p>
<p></p>
I presume you have added this pipeline to Item:Saved. As you have found, publishing actually also creates/saves the item in the web database, the same event is fired on that server and hence the reason you are seeing the repeated tags. Add a check to make sure you are running in the master database in your process method:
public void Process(RenderFieldArgs args)
{
if (!args.Item.Database.Name.Equals("master", StringComparison.InvariantCultureIgnoreCase))
return;
if (args.FieldTypeKey != "single-line text" && args.FieldTypeKey != "multi-line text")
return;
args.Result.FirstPart = Helper.WrapInTags(args);
}
However, you may want to check if your text is already wrapped in the tag you are enclosing in (as well) - use HTMLAgilityPack or CsQuery instead of messing with regular expressions. In a simple scenario such as a single-line text field you could probably just get away with a StartsWith() check instead.
You should consider moving your code to the renderField pipeline instead (more info in this blog post or this one), or make use of the EnclosingTag attribute of the FieldRenderer. This way the tags are added at render time, rather than appearing in the content editor. There is some code in this SO answer I posted previously that you can use to pass the css class as well.

asp.net mobile/desktop site toggle button, switching masterpage, but styles "stuck"

Summary
I'm having style issues when flipping master pages via a button event in asp.net 4.0. The new master switches, but the css from the old master remains. I don't understand how this could happen as the styles are defined within the head of the old master, and i can clearly see via the markup the new master is being displayed with whats supposed to be a totally different set of styles. Also, viewing source shows all the new css declarations in the head. How can i get this to "refresh" or "reload"?
Some details
I'm implementing a mobile version of my asp.net site. If a mobile device is detected i set a cookie and switch the master page in the preinit to a mobile friendly one. This works fine:
protected virtual void Page_PreInit(Object sender, EventArgs e)
{
if (IsMobile)
this.Page.MasterPageFile = "m-" + this.Page.MasterPageFile;
}
I have a "full site" button at the bottom that allows you to flip back and forth between the mobile and desktop view. When clicking it, i change the value in the cookie. Then when the page redirects to itself, the value is checked, and it gives the respective masterpage. This also "works", i can tell the right masterpage is rendering via markup. Except the styles from the mobile version remain even when the desktop master is being displayed. I did the redirect thinking it would prevent this.
// desktop/mobile site toggle button click event
protected void viewMobileButton_Click(Object sender, EventArgs e)
{
HttpCookie isMobileCookie = Cookies.snatchCookie("isMobile");
if (bool.Parse(isMobileCookie.Value))
Cookies.bakeCookie("isMobile", "false");
else
Cookies.bakeCookie("isMobile", "true");
Response.Redirect(Request.RawUrl);
}
This is the first time I've done anything like this, and not sure if i'm even going about it the right way, or how to debug from here. Thanks in advance for any help.
Edit
Ok, so i figured out it's related to the JQuery Mobile Scripts. JQuery Mobile has this way of tying pages together. I don't fully understand it, i think they use it for page transitions, and it's preventing my new CSS from registering. When i turn it off, my masterpage flips fine with css included. I'm looking into a way to turn off JQuery Mobile before my redirect. Note sure how though yet.
The problem ended up being related to JQuery Mobile AJAX for page-transitions. JQuery Mobile does not load the head of the document on additional page requests after the first.
So when i'd switch the mobile master to the desktop master, the head of the document wouldn't load to bring in my styles. There are a few way's this can be fixed:
This way just turns off AJAX altogether, and fixes the problem, but then you can't benefit from it:
<form data-ajax="false">
This is a way to do it problematically, but remind you, it will not work via an event after initialization of JQuery Mobile, so again you can't benefit from it:
$.mobile.ajaxEnabled = false;
The above two solutions i support could work if you redirected through a page first if you have to use an onclick event and an event handler.
A better solution is to add rel="external" to the link to tell JQM it's and outgoing link.
<a href="myself.com?mobile=true" rel="external" >
But because i couldn't run some code i wanted to in order to change the cookie, i had to pass a query string parameter, check it on the preinit, then set the cookie which my page also looks at on the preinit and flips the master.
Here's my full solution below in case someone is out there doing the exact same thing. Note because my website is using aliasing, i had to read Request.RawUrl and parse it myself since the Request.QueryString object did not contain the values i passed.
// reusable function that parses a string in standard query string format(foo=bar&dave=awesome) into a Dictionary collection of key/value pairs
// return the reference to the object, you have to assign it to a local un-instantiated name
// will accept a full url, or just a query string
protected Dictionary<string, string> parseQueryString(string url)
{
Dictionary<string, string> d = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(url))
{
// if the string is still a full url vs just the query string
if (url.Contains("?"))
{
string[] urlArray = url.Split('?');
url = urlArray[1]; // snip the non query string business away
}
string[] paramArray = url.Split('&');
foreach (string param in paramArray)
{
if (param.Contains("="))
{
int index = param.IndexOf('=');
d.Add(param.Substring(0, index), param.Substring(++index));
}
}
}
return d;
}
Then i just use my dictionary object to evaluate and rebuild my url with the opposite mobile value, dynamically setting the href on the toggle link. Some code is obviosuly left out, but for perspective, base._iPage.QueryStringParams hold my dictionary object that was returned, and base._iPage.IsMobile is just a bool property i also have via the page interface i use, that all my pages, and user controls, ect, can talk to.
// get the left side fo the url, without querystrings
StringBuilder url = new StringBuilder(Request.RawUrl.Split('?')[0]);
// build link to self, preserving query strings, except flipping mobile value
if (base._iPage.QueryStringParams.Count != 0)
{
if (base._iPage.QueryStringParams.ContainsKey("mobile"))
{
// set to opposite of current
base._iPage.QueryStringParams["mobile"] = (!base._iPage.IsMobile).ToString();
}
int count = 0;
url.Append('?');
// loop through query string params, and add them back on
foreach (KeyValuePair<string, string> item in base._iPage.QueryStringParams)
{
count++;
url.Append(item.Key + "=" + item.Value + (count == base._iPage.QueryStringParams.Count ? "" : "&" ));
}
}
// assign rebuild url to href of toggle link
viewMobileButton.HRef = url.ToString();
}
Then on my pageinit this is where i actually check, first the quesry string, then the cookie, if neither of those are present, i run my mobile detection method, and set a cookie, and my interface bool property for easy access to conditionals that depends on it.
QueryStringParams = base.parseQueryString(Request.RawUrl);
if (QueryStringParams.ContainsKey("mobile") ? QueryStringParams["mobile"].ToLower().Equals("true") : false)
{
Cookies.bakeCookie("isMobile", "true"); // create a cookie
IsMobile = true;
}
else if (QueryStringParams.ContainsKey("mobile") ? QueryStringParams["mobile"].ToLower().Equals("false") : false)
{
Cookies.bakeCookie("isMobile", "false"); // create a cookie
IsMobile = false;
}
else
{
IsMobile = base.mobileDetection();
}
if (IsMobile)
this.Page.MasterPageFile = "m-" + this.Page.MasterPageFile;
}

Using SiteMapPath to create a dynamic page title?

I currently use SiteMapPath to generate a breadcrumb for my ASP.net 3.5 (vb.net) pages and it works great.
Now I am trying to figure out how I might be able to use the same control to build a dynamic page title (in the tag). I want a reverse path listed, but the SiteMapPath control includes links and bunch of styling spans. Is there any way to remove all of that, and just get a plain path with separators?
For example, Let's say we are on the "Press Releases" page inside of the "About" section of my site.
The breadcrumb shows up as:
Home > About > Press Releases
I want to have the page title be:
Press Releases - About - Company Name
So I need it to reverse the order, drop all spans, links and styling (since this is inside the tag) and drop the root node "Home" and then add the company name to the end. Since my menu nav and breadrumbs are all driven from the sitemap file, I thought it would make sense to try to make the title do the same.
Any thoughts? Thanks.
The best way to achieve your desired output is to ignore the SitePath control, and instead use the SiteMap's SiteMapNode's collection. The server parses the web.sitemap into a collection of SiteMapNodes and wires up the SiteMap.CurrentNode by finding a node that matches the current page's URL. Each SiteMapNode has a ParentNode property. Here is the reference page on MSDN.
So, all you need to do is check if the CurrentNode has a parent, if it does you add the ParentNode's title to the CurrentNode's title and keep going until you reach the RootNode (where you substitute your company name for the root node's title).
Below is a quick solution; it could go in the MasterPage if you are using one. I'm not sure your language, but this should be easy to rewrite in VB.Net. I gave it a simple test and it seemed to work.
You can customize the characters that separate the page titles.
protected void Page_Load(object sender, EventArgs e)
{
Page.Title = SiteMapTitle(SiteMap.CurrentNode, "", " - ");
}
private string GetNodeTitle(SiteMapNode oNode)
{
if (oNode == SiteMap.RootNode)
return "Company Name";
else
return oNode.Title;
}
private string SiteMapTitle(SiteMapNode oNode, string szTitle, string szItemSeparator)
{
if (szTitle != string.Empty)
szTitle = szTitle + szItemSeparator + GetNodeTitle(oNode);
else
szTitle = GetNodeTitle(oNode);
if (oNode.ParentNode != null)
szTitle = SiteMapTitle(oNode.ParentNode, szTitle, szItemSeparator);
return szTitle;
}
Hope that helps...

How to remove or disable hyperlink events from pdf file?

I can display a PDF file from byte[] in asp.net.
The problem is that it contains hyperlinks and I want to disable or remove these hyperlink events.
Docotic.Pdf, the library I am involved with, can be used to find hyperlinks in PDFs and remove them.
Here is the sample code that does exactly this:
public static void RemoveHyperlinks(string inputFile, string outputFile)
{
using (PdfDocument doc = new PdfDocument(inputFile))
{
foreach (PdfPage page in doc.Pages)
{
for (int i = 0; i < page.Widgets.Count; i++)
{
PdfWidget widget = page.Widgets[i];
PdfActionArea actionArea = widget as PdfActionArea;
if (actionArea != null)
{
PdfUriAction linkAction = actionArea.Action as PdfUriAction;
if (linkAction != null)
{
page.Widgets.RemoveAt(i);
i--;
}
}
}
}
doc.Save(outputFile);
System.Diagnostics.Process.Start(outputFile);
}
}
Please note that some viewers can detect hyperlinks from text and still present them as clickable areas even though there is not links defined in PDF itself. For example, Adobe Reader with certain settings can do just that.
P.S. I know this question is old, but maybe my answer will benefit new visitors.
You can libraries like this one to open and modify the PDF file and convert every hyperlink object to simple text.

Resources