0

I've got a weird issue here. I'll start by explaining my program:

I have a C# application. The main goal of the program is to get information about a book based on its ISBN. The ISBN is passed to the program via a TCP/IP scanner on an Android device. The ISBN is then put into a valid URL which is used to grab the XML data from ISBNDB.com.

The issue that I am having is this:

When I query an ISBN typed into a TextBox, the program works fine. When I query an ISBN scanned from the reader, it returns 'No Results'

I have implemented various ways to try and get to the bottom of this case. Right before the XML is read, I have a message box show me the XML that it received: Messagebox showing XML
As you can see, it shows no results. However, when I visit the URL (Also gotten from within the program):
MessageBox showing URL
I get this in Microsoft Edge:
enter image description here
Which, is exactly what I would think the application would get as well.

Does anyone know what is going on? If so, what can I do to fix it and how can my code be improved to eliminate this error?

For those interested, here is my code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Threading;
using System.Diagnostics;

namespace LibraryBookLister
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string XML = "";
        private void btnQuery_Click(object sender, EventArgs e)
        {

            GetXMLBarcodeData();

        }

        private void GetXMLBarcodeData()
        {
            string Barcode4 = textBarcode.Text;
            MessageBox.Show(Barcode4);
            string barcode = Barcode4;
            StringBuilder output = new StringBuilder();

            XmlUrlResolver resolver = new XmlUrlResolver();
            resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Set the reader settings object to use the resolver.
            if(barcode.Length > 13)
            {
                barcode = barcode.Remove(14);
                MessageBox.Show(barcode);
            }
            string xmlString = @"?access_key=IDC057UX&results=details&index1=isbn&value1=" + barcode;
            MessageBox.Show("GEttting book info for : "  + barcode);

            Uri baseUri = new Uri("https://isbndb.com/api/books.xml");
            Uri fulluri = resolver.ResolveUri(baseUri, xmlString);
            MessageBox.Show("Now Getting The URL: " + fulluri.ToString());
            Process.Start(fulluri.ToString());


            StringBuilder sb = new StringBuilder();
            XmlReader readesr = XmlReader.Create(fulluri.ToString());

            MessageBox.Show("REading data from " + fulluri.ToString());
            while (readesr.Read())
            {

                sb.AppendLine(readesr.ReadOuterXml());

            }
            string XMLs = sb.ToString();
            XML = XMLs;
            MessageBox.Show("XML : " + XML);
            GetXMLStuff();
        }
        public void GetXMLStuff()
        {
            tcplistener.Stop();
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(XML);

                        XmlNodeList nodes = doc.DocumentElement.SelectNodes("/ISBNdb/BookList");

            List<Book> books = new List<Book>();

            foreach (XmlNode node in nodes)
            {
                Book book = new Book();
                try
                {
                    if (node.SelectSingleNode("BookData/AuthorsText").InnerText == null)
                    {
                        MessageBox.Show("Could not find this book. Please enter data by hand.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        textBarcode.Clear();
                        return;
                    }
                }
                catch
                {
                    MessageBox.Show("Could not find this book. Please enter data by hand.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 //   textBarcode.Clear();
                    return;

                }
                book.author = node.SelectSingleNode("BookData/AuthorsText").InnerText;
                book.title = node.SelectSingleNode("BookData/Title").InnerText;

                book.ISBN = node.SelectSingleNode("BookData").Attributes["isbn"].Value;

                books.Add(book);
                MessageBox.Show(book.author);
                addInfo(book.author, book.title, book.ISBN);
                textBarcode.Clear();
            }

          //  MessageBox.Show("Total books: " + books.Count);
        }

        private void addInfo(string Author, string Title, string ISBN)
        {
            textAuthor.Text = Author;
            textTitle.Text = Title;
            textISBN.Text = ISBN;

        }
        class Book
        {
            public string ISBN;
            public string title;
            public string author;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }
        int time = 10;
        bool cancel = false;
        private void timer1_Tick(object sender, EventArgs e)
        {
            if(time > 0)
            {
                labelTime.Text = time.ToString();
                button1.Text = "Change Data";
                cancel = true;
                labelTime.Visible = true;
                time--;
            //   MessageBox.Show(time.ToString());
            }
            if(time <= 0)
            {
                cancel = false;
                button1.Text = "Add to List";
                timer1.Stop();
                time = 10;
                labelTime.Visible = false;
                MessageBox.Show("Submitting");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if(cancel)
            {
                timer1.Stop();
                labelTime.Visible = false;
                time = 10;
                cancel = false;
                button1.Text = "Add to List";
            }
            else
            {
                timer1.Start();

            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
           Thread tcpServer = new Thread(new ParameterizedThreadStart(TCPServerRun));
            //TCPServerRun();
           tcpServer.Start();

        }
        bool on = true;

        TcpListener tcplistener = new TcpListener(IPAddress.Any, 5004);
        private void TCPServerRun(object test)
        {


            try
            {
                MessageBox.Show("Starting Listener");

                tcplistener.Start();
            }
            catch { MessageBox.Show("COULDNT START TPCSERVER"); return; }



            while (on == true)
            {

                try
                {
                    TcpClient client = tcplistener.AcceptTcpClient();

                   Thread tcpHandlerThread = new Thread(new ParameterizedThreadStart(tcpHandler));
                  // tcpHandlerThread.Start(client);

                    tcpHandler(client);
                }
                catch
                {

                    tcplistener.Stop();
                  //  MessageBox.Show("Stopping Listener");


                }


            }



        }

        string bCode = "";
        private void tcpHandler(object client)
        {
            TcpClient mClient = (TcpClient)client;
            NetworkStream stream = mClient.GetStream();
            byte[] message = new byte[1024];

            stream.Read(message, 0, message.Length);
            bCode = Encoding.ASCII.GetString(message);

            stream.Close();
            mClient.Close();
            MessageBox.Show(bCode);
            this.textBarcode.Text = bCode;
            GetXMLBarcodeData();
        }
    }
}

Possible Hint:

Could it have something to do with how I have threads working?

*Edit: * **I have updated the code to have the barcode be put in a textBox and then used to fetch the data. This does not seem to work either because it 'Cannot access the control on a thread other than on which it was created'

Question Asker
  • 199
  • 2
  • 18
  • Could you add some logging method in tcpHandler to keep every bCode it received? It could be that several bCode are received in one scan, one of them contain blank or invalid code. – Martheen Aug 14 '15 at 03:16
  • I have done that in the time since posting the answer, but all that happens is that it shows one (1) instance of the Barcode. Also, I have included a piece of code that will shorten the length of the code to exactly 13 characters to eliminate any 'white space'. – Question Asker Aug 14 '15 at 03:18
  • How about setting textBarcode.Text with bCode, then invoke btnQuery Click event, thus simulating the manual typing – Martheen Aug 14 '15 at 03:23
  • Check [this](http://stackoverflow.com/questions/22356/cleanest-way-to-invoke-cross-thread-events) – Martheen Aug 14 '15 at 03:24
  • Being a little green as far as using Threads go, how would I implement this? Do I replace the Threading completely with [that](http://stackoverflow.com/questions/22356/cleanest-way-to-invoke-cross-thread-events?) ? – Question Asker Aug 14 '15 at 03:28
  • Nah, keep the threading. But in tcpHandler, right after mClient.Close(), replace the remaining lines with textBarcode.BeginInvoke(/*set the textbox value and call the button click here */ ) – Martheen Aug 14 '15 at 03:34
  • @Martheen (Not enough rep to move to chat) I am doing something wrong here for sure: `textBarcode.BeginInvoke( textBarcode.Text = bCode; GetXMLBarcodeData(); );` To me, this does not look right at all. – Question Asker Aug 14 '15 at 03:41
  • textBarcode.BeginInvoke(new Action(() => { textBarcode.Text = bCode; GetXMLBarcodeData();})); – Martheen Aug 14 '15 at 03:49
  • @Martheen Hey man, thank you so much for working with my lack of knowledge! It worked perfectly :) It'd be great if you could put that as an answer so I can wrap this question up and others can learn from it. – Question Asker Aug 14 '15 at 03:52

1 Answers1

1

If manual user input succeed while automated input fail, the simplest hack is just replacing the automated input to a call to manual control BeginInvoke. For your code this would be :

textBarcode.BeginInvoke(new Action(() => { 
   textBarcode.Text = bCode;
   GetXMLBarcodeData();
}));
Martheen
  • 5,198
  • 4
  • 32
  • 55