I created the first method, which gets and displays all the links in a web page in a listView when a button is pressed. I found the second method on a site that supposedly checks to see if a link is valid. I need help on incorporating it into my program. I would like that after it checks the link, that it will tell me if it is valid or not beside the link in my listView box. I'm still pretty new to C# and programming overall. I have read several things and tried changing somethings around, but no luck. Can somebody please give me some pointers on this and tell me if this will work on what I'm doing?

private void toolStripButtonLinks_Click(object sender, EventArgs e)
        {
            foreach (HtmlElement link in webBrowser1.Document.Links)
                listViewLinks.Items.Add(link.GetAttribute("HREF").ToString());
        }

        private Boolean TestUrl(String url)
        {
            WebRequest req = null;
            WebResponse resp = null;
            try
            { // Create a request and get a response. If no exceptions were thrown, 
                // The link is good. 
                req = (WebRequest)WebRequest.Create(url);
                resp = req.GetResponse();
                return true;
            }
            catch (Exception e)
            {
                // An exception was thrown indicating a bad link. Check e for error. 
                return false;
            }
            finally
            {
                // Close the response object. 
                if (resp != null) resp.Close();
            }
        }

Recommended Answers

All 28 Replies

While having it in a separate function is best

Create a boolean variable, remove the returns and in their place, put the boolean variable = true or false accordingly.

Then move the whole block into the first and test the value of the boolean at the end as to wether it was true or false.

Ok. I tried doing what you said. I have changed it to this:

private void toolStripButtonLinks_Click(object sender, EventArgs e)
        {
            foreach (HtmlElement link in webBrowser1.Document.Links)
                listViewLinks.Items.Add(link.GetAttribute("HREF").ToString());

            bool testLink;
            WebRequest req = null;
            WebResponse resp = null;
            try
            {
                // Initialize the WebRequest.
                WebRequest myRequest = WebRequest.Create(listViewLinks.Items);

                // Return the response. 
                WebResponse myResponse = myRequest.GetResponse();
                testLink = true;
                Console.WriteLine("Good");
            }
            catch (Exception d)
            {
                // An exception was thrown indicating a bad link. Check e for error. 
                testLink = false;
            }
            finally
            {
                // Close the response object. 
                if (resp != null) resp.Close();
            
            }
        }

I know the WebRequest myRequest = WebRequest.Create(listViewLinks.Items); is wrong. I don't know how to get a response from all the items in my listViewLinks box. Am I on the right track and can you help me on getting a response from all my links in the box?

In your first code, the first function never called your second.

Perhaps you need to put down more on paper how your brain thinks this will work.

you first post was close, you just needed to make your for loop call the second method, if true add it to the list, if false don't do anything

I did mention it was the best way to do it. :)

yes you did, now hopefully he will go down that path

Ok guys, I must be really missing something. I've been working on this one spot for a couple of days now. I went back to the first code that I posted. I've tried adding a while loop and calling the second method, which is the testUrl.
Here is what I've changed the first method to.

private void toolStripButtonLinks_Click(object sender, EventArgs e)
        {
            int i = 0;
            foreach (HtmlElement link in webBrowser1.Document.Links)
            {
                string links = listViewLinks.Items;
                while (i <= Items)
                {
                    TestUrl(links);
                    i++;
                }
            }
        }

I know this has many things wrong with it, but is this any better? This doesn't even come close to compiling. I don't know how to send each individual link to the second function to get it checked.

Well.

You did a foreach which was probably right but then didnt use the link that you had. You'll probably slap yourself if you had looked more closely at what was the object of your foreach loop.

Hint: Look at the original code, it echoed out the URL right? in a STRING form..

Second. You then make up some stuff and pass a list of links to a function that takes a string. So, it wouldnt compile - but then lets assume you work out my first hint and changing it to the right thing.

You need to check the return value of the testurl to do something..

Hint 2: You need to turn a true/false to failed or succeed.

The object of the foreach loop was link right? Doesn't it output it in string because of the listViewLinks.Items.ToString()? Anyway, if I'm going to check the links, it probably needs to timeout after a few seconds so the user won't sit there all day waiting. I have changed the code yet again to this

private void toolStripButtonLinks_Click(object sender, EventArgs e)
        {
            foreach (HtmlElement link in webBrowser1.Document.Links)
            {
                listViewLinks.Items.Add(link.GetAttribute("HREF").ToString());

                Uri urlCheck = new Uri(listViewLinks.Items.ToString());
                WebRequest request = WebRequest.Create(urlCheck);
                request.Timeout = 10000;    // 10 seconds


                WebResponse response;
                try
                {
                    response = request.GetResponse();
                    Console.WriteLine("Good");
                }
                catch (Exception)
                {
                    Console.WriteLine("Bad"); //url does not exist
                }

            }

It compiles but crashes when I click on the "Check Links!" button. It seems to crash when it gets to the WebRequest request = WebRequest.Create(urlCheck); line. What am I doing wrong now?

are you meaning something like this?

foreach (HtmlElement link in webBrowser1.Document.Links)
            {
                bool isValid = false;
                string linkItem = link.GetAttribute("HREF").ToString();
                
                Uri urlCheck = new Uri(linkItem);
                WebRequest request = WebRequest.Create(urlCheck);
                request.Timeout = 10000;    // 10 seconds


                WebResponse response;
                try
                {
                    response = request.GetResponse();
                    isValid = true;
                    Console.WriteLine("Good");
                }
                catch (Exception)
                {
                    Console.WriteLine("Bad"); //url does not exist
                }
                
               if(isValid)
	   {
		listViewLinks.Items.Add(link.GetAttribute("HREF").ToString());
	   }
	}

Yeah, that's pretty much what I was meaning. Appears I had that at one time, just not at the same time! That code seems to work, but when I click the "Check Links!" button, I just get "A first chance exception of type 'System.Net.WebException' occurred in System.dll" for the links. I know that the links are good. Sometimes it also says "Bad" also.

what are the href's coming in as?

also capitalization

if it also says bad, then the exception didn't occur in that place, what are links coming in as, and what are they being resolved as?

In my first code, the links showed up in my listView as "http://www.webpage.com/." Now nothing is showing up in my box. I don't know if that is because it is waiting for it to check all the sites or what. It returned back "Good" on the very first link on the page, which also has the same url as the page that I was checking the links on, but it still didn't show up in my listView. Now every link, every 10 seconds is gives me "Bad", then "A first chance exception of type 'System.Net.WebException' occurred in System.dll" at the same time.

It doesn't leave the trailing / after the aspx, html, php, or anything else. I tried to check the links on microsoft.com and got an unhandled exceptions error. It said something about their being a wrong uri prefix here WebRequest request = WebRequest.Create(urlCheck); . I also tried adding an extra / and even a /r/n to the link, but it didn't make any difference.

try with httpresponse and httprequest

Tried it, no difference. I changed it back and now I'm getting alot more "Good" links. I still get alot of "first chance exceptions" though.

What does the exception say?
Have you allowed for redirection? Eg if you went to www.somesite.com chances are http is telling "hi thats nice for you, now ask for say index.html"

Here is the exception detail.

System.NotSupportedException was unhandled
  Message="The URI prefix is not recognized."
  Source="System"
  StackTrace:
       at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)
       at System.Net.WebRequest.Create(Uri requestUri)
       at linkchecker.Form1.toolStripButtonLinks_Click(Object sender, EventArgs e) in C:\Documents and Settings\sfrider0\My Documents\Visual Studio 2005\Projects\linkchecker\linkchecker\Form1.cs:line 73
       at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
       at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
       at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
       at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
       at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
       at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
       at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ToolStrip.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at linkchecker.Program.Main() in C:\Documents and Settings\sfrider0\My Documents\Visual Studio 2005\Projects\linkchecker\linkchecker\Program.cs:line 17
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

This is line 73.

WebRequest Request = HttpWebRequest.Create(urlCheck);

just to be sure we are still at the same place

what is the exact link that is passed in (what is linkItem)

I just tried it on facebook.com and it worked fine. It took it a little while, but when it finished it showed up in my listView with "Good" or "Bad" next to it.

right, but when that throws an exception, what is the linkItem?

"javascript:void(0)"

lol whoa, i thought you said it was microsoft

yeah, my bad. I was just looking at the console output the first time. Then I checked my locals and "javascript:void(0)" was in linkItem.

right, then the exception is correct

uri is expected to be a registered prefix, and javascript is not, things are working properly!!!

Yes!! Thank you for your help!! I just added this code in there just to get it to run.

if (!(linkItem.StartsWith("http://") || linkItem.StartsWith("https://")))
                    linkItem = "http://link.bad/";

It works perfect now. I'm not real familiar with exceptions so I don't know how to get it to throw an exception when I get javascript or some other type link.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.