Skip to content

Instantly share code, notes, and snippets.

@stephenlb
Last active Aug 29, 2015
Embed
What would you like to do?
ePoll Example using ASP.NET MVC

ePoll Example using ASP.NET MVC

Hey! Did you think of implementing C# PubNub API using ASP.NET MVC 4. There you go. You are in the right place. In this session, I am going to walkthrough a sample ePoll web application. ePoll can also be claimed as eVote.

ePoll Voting with C# .NET

ePoll is basically providing two or more responses or answers to the user/customer for a given question and allowing the user to choose a response.

This sample demo uses PubNub C# client SDK feature calls Publish() and DetailedHistory to demonstrate ePoll web application.

In real-time applications, we expect the question and the choice of answers/responses come from the database. To keep things easy, I am going to hard-code the questions/responses as xml string in GetActivePollQuestion() method of SampleData class. In real-time, you can return dynamic data as xml string.

Schemas

Two schemas PollQuestion.xsd and PollUserAnswer.xsd were created.

PollQuestion.cs and PollUserAnswer.cs class files were generated using xsd.exe tool using the following commands

XSD.EXE PollQuestion.xsd /c /l:cs /n:ePoll.Types

XSD.EXE PollUserAnswer.xsd /c /l:cs /n:ePoll.Types

Their schemas are listed below.

<xs:schema id="PollQuestion"
    targetNamespace="pubnub-csharp-demo-epoll-1.0"
    elementFormDefault="qualified"
    xmlns="pubnub-csharp-demo-epoll-1.0"
    xmlns:mstns="pubnub-csharp-demo-epoll-1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PollQuestion">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:string"></xs:element>
        <xs:element name="Question" type="xs:string"></xs:element>
        <xs:element name="Active" type="xs:boolean"></xs:element>
        <xs:element name="AnswerGroup">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Answer" type="xs:string" maxOccurs="unbounded" minOccurs="2"></xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>
<xs:schema id="PollUserAnswer"
    targetNamespace="pubnub-csharp-demo-epoll-1.0"
    elementFormDefault="qualified"
    xmlns="pubnub-csharp-demo-epoll-1.0"
    xmlns:mstns="pubnub-csharp-demo-epoll-1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PollUserAnswer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="QuestionID" type="xs:string"></xs:element>
        <xs:element name="Question" type="xs:string"></xs:element>
        <xs:element name="UserAnswer" type="xs:string"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Publish

The Publish<string>() method is being used to save the poll answers. The following code saves the answers.

        public bool SaveAnswer(PollUserAnswer answer)
        {
            bool ret = false;

            string pubnubChannel = answer.QuestionID;
            mrePublish.AddOrUpdate(pubnubChannel, new ManualResetEvent(false), (key, oldState) => new ManualResetEvent(false));
            messagePublished[pubnubChannel] = false;

            pubnub.Publish<string>(pubnubChannel, answer.UserAnswer, PollUserAnswerPublishRegularCallback, PollUserAnswerPublishErrorCallback);
            mrePublish[pubnubChannel].WaitOne(TimeSpan.FromSeconds(10));

            if (messagePublished[pubnubChannel])
            {
                ret = true;
            }

            return ret;
        }

        private static void PollUserAnswerPublishRegularCallback(string publishResult)
        {
            if (!string.IsNullOrEmpty(publishResult) && !string.IsNullOrEmpty(publishResult.Trim()))
            {
                object[] deserializedMessage = pubnub.JsonPluggableLibrary.DeserializeToObject(publishResult) as object[];
                if (deserializedMessage is object[] && deserializedMessage.Length == 3)
                {
                    long statusCode = Int64.Parse(deserializedMessage[0].ToString());
                    string statusMessage = (string)deserializedMessage[1];
                    string channelName = (string)deserializedMessage[2];
                    if (statusCode == 1 && statusMessage.ToLower() == "sent")
                    {
                        if (messagePublished.ContainsKey(channelName))
                        {
                            messagePublished[channelName] = true;
                        }
                    }
                    if (mrePublish.ContainsKey(channelName))
                    {
                        mrePublish[channelName].Set();
                    }
                }
            }
        }

Once the poll answers were submitted to the PubNub server, the success status of message publish will be displayed as view to the web user as below:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo ePoll</title>
    <link rel="Stylesheet" href="../../Content/demo.css" />
</head>
<body>
    <div id="votecontainer">
    <p class="welcome">PubNub ePoll</p>
    @if (ViewData["PollAnswerSaveStatus"] != null && (bool)ViewData["PollAnswerSaveStatus"])
    {
        if (ViewData["ID"] != null && ViewData["ID"].ToString() != "")
        {
            string questionID = ViewData["ID"].ToString();
            using (Html.BeginForm("PollResult", "Poll",FormMethod.Post))
            {
                <p class="thanks">Thank you for your participation in PubNub ePoll</p>

                @Html.Hidden("ID", questionID);
                <div id="divpollresult2">
                <button name="btnPollResult" id="btnPollResult" value="View Poll Results">View Poll Results</button>
                </div>
            }
        }
    }
    else
    {
        <p>Technical error occured. Please try again later.</p>
    }
    </div>
</body>
</html>

History

The DetailedHistory<string> method is being used to pull the poll results. The following code retrieves the poll results.

        public List<string> GetPollResults(string questionID)
        {
            List<string> ret = null;

            string pubnubChannel = questionID;

            mreDetailedHistory.AddOrUpdate(pubnubChannel, new ManualResetEvent(false), (key, oldState) => new ManualResetEvent(false));
            detailedHistoryReceived.AddOrUpdate(pubnubChannel, false, (key, oldState) => false);
            detailedHistoryStartTime.AddOrUpdate(pubnubChannel, 0, (key, oldState) => 0);
            channelDetailedHistory.AddOrUpdate(pubnubChannel, new List<string>(), (key, oldState) => new List<string>());

            detailedHistoryReceived[pubnubChannel] = false;

            long currentTimetoken = Pubnub.TranslateDateTimeToPubnubUnixNanoSeconds(DateTime.UtcNow);
            detailedHistoryStartTime[pubnubChannel] = 0; // currentTimetoken;

            while (!detailedHistoryReceived[pubnubChannel])
            {
                pubnub.DetailedHistory<string>(pubnubChannel, detailedHistoryStartTime[pubnubChannel], PollResultsRegularCallback, PollResultsErrorCallback, true);
                mreDetailedHistory[pubnubChannel].WaitOne();
                if (!detailedHistoryReceived[pubnubChannel])
                {
                    mreDetailedHistory[pubnubChannel].Reset();
                }
            }

            ret = channelDetailedHistory[pubnubChannel];

            return ret;
        }

Here you go, you reached the end of the session. You have seen the sample code for Publish and DetailedHistory calls of PubNub. Full working code of the demo is available at https://github.com/pubnub/c-sharp/tree/master/demos/ePoll . Feel free to expand or improve based on your business or hobby needs. To run the code, you need Visual Studio 2012/2013 (any edition) or latest. Third party library Json.NET is being used to parse messages from PubNub server.

Happy PubNub publish coding!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment