-5

Im having trouble converting wpf to asp.net using mqtt. My code did not show any error but when i launch and input some text and a button click,it will show me an error "An exception of type 'System.NullReferenceException' occurred in WebApplication4.dll but was not handled in user code"

public partial class Testing : System.Web.UI.Page
    {
        MqttClient client;
        string clientId;
        protected void Page_Load(object sender, EventArgs e)
        {

        }


        public void MainWindow()
        {


            string BrokerAddress = "test.mosquitto.org";

            client = new MqttClient(BrokerAddress);

            // register a callback-function (we have to implement, see below) which is called by the library when a message was received
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            // use a unique id as client id, each time we start the application
            clientId = Guid.NewGuid().ToString();

            client.Connect(clientId);
        }




        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message);


                txtReceived.Text = ReceivedMessage;

        }

    protected void btnPublish_Click(object sender, EventArgs e)
            {
                if (txtTopicPublish.Text != "")
                {
                    // whole topic
                    string Topic = "" + txtTopicPublish.Text + "";

                    // publish a message with QoS 2
                    client.Publish(Topic, Encoding.UTF8.GetBytes(txtPublish.Text), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, true);
                }
                else
                {
                    Page.ClientScript.RegisterStartupScript(this.GetType(), "Scripts", "<script>alert('You have to enter a topic to publish!')</script>");
                }
            } 
Jovan
  • 13
  • 2
  • 8
  • 2
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Filburt Mar 22 '17 at 07:29
  • This is one of those "My code doesn't work, fix it for me" questions. You can avoid the downvotes by showing that you have made an effort to solve the problem before asking the question. – Heki Mar 22 '17 at 07:30
  • Where is `client` defined? Why are you composing a string `Topic` from `txtTopicPublish.Text` and never use it? Why are you using `txtPublish.Text` when testing if `txtTopicPublish.Text`isn't emtpy? – Filburt Mar 22 '17 at 07:33
  • @Heki Well, it works for my wpf, im only tried to convert it to asp.net, i tried and i couldnt find the code – Jovan Mar 22 '17 at 07:42
  • @Filburt MqttClient client; string clientId; public void MainWindow() { string BrokerAddress = "test.mosquitto.org"; client = new MqttClient(BrokerAddress); client.MqttMsgPublishReceived += client_MqttMsgPublishReceived; clientId = Guid.NewGuid().ToString(); client.Connect(clientId); } – Jovan Mar 22 '17 at 07:45
  • 1
    I'm willing to bet that `client` is `null` when `btnPublish_Click` is called. Is this right? – Heki Mar 22 '17 at 07:48
  • @Heki You're right, when i see the error after compile, client is null – Jovan Mar 22 '17 at 07:55
  • Moving everything from `MainWindow()`to `Page_Load()` would be a good start. Better however would be laer about the differences between a WPF and ASP.NET. – Filburt Mar 22 '17 at 07:59
  • Alright, this is likely due to the fact that asp.net is stateless. You expect `client` to have a reference to a `MqttClient`-instance, because `MainWindow` has been called (which I assume happens in `Page_Load`). You need to be aware of the lifecycle in asp.net versus that of a WPF application. In asp.net everything is disposed when the page is done rendering, which also means between button clicks and includes your `client` property. You can store a reference in the `Application` or `Session` objects depending on requirements and it will "stay alive" between page loads - or instantiate again. – Heki Mar 22 '17 at 08:05
  • @Heki Sorry im new to this, i didnt know there's so much to be done. How do i store reference in Application or Session? – Jovan Mar 22 '17 at 08:21
  • Well, first you need to figure out if that's what you want. If it would make sense to A: keep `MqttClient` always (`BrokerAddress` NEVER changes and you only always need that single connection. All your users may use the same connection), if B: `BrokerAddress` or any other property on `MqttClient` is unique to a user or if C: you can live with a new connection every time a message is sent. If A, `Application["MqttClient"] = new Mqtt...` in the `Global.asax`-file. If B, null-check and `Session["MqttClient"]....` if null. If C, `client = new Mqtt...` in the publish click. – Heki Mar 22 '17 at 08:27
  • @Heki all my users will be using the same connection. So i will choose A – Jovan Mar 22 '17 at 08:40
  • @Heki May i know what is Application["MqttClient"] = new Mqtt...? – Jovan Mar 22 '17 at 08:50
  • Obviously it would be `Application["MqttClient"] = new MqttClient(brokerAddress);` – Heki Mar 22 '17 at 09:18

1 Answers1

0

It seems to be a lack of understanding of the ASP.NET page lifecycle. In WPF, the lifecycle spans from when you run the program til when it is closed; it is statefull. ASP.NET is not; whatever you do in a Page_Load (and the other lifecycle events) will be disposed with the completion of rendering the page.

You have a few ways of solving your problem.

  1. You can keep the MqttClient instance in the Application object. This keeps the instance alive from when the AppPool starts (instantiate the client in the Application_Start event in Global.asax. It is fired when the AppPool starts) and until it shuts down (Application_End, where you get the opportunity to shut your MqttClient down gracefully if you want/need to). It is shared between all users and can be accessed anywhere with Application[key] where key is any string, "MqttClient" for example.
  2. You can keep it in the Session object the same way you would in the Application object. You can use Sesson_Start and Session_End in the same way. The Session object is unique to each user, in terms of it staying alive until the user stops browsing your website.
  3. You can instantiate MqttClient every time you need it or with every Page_Load.
Heki
  • 854
  • 2
  • 14
  • 30