Monday, 7 August 2017

Part 3 : Display of quiz and options on start quiz screen.



What we want to achieve?
  1. We want to simply display all quiz and quiz options (around random 10 quiz) on start quiz screen.
  2. We want to simply display quiz and quiz options on start quiz screen one by one with next button to move to next question.(We'll discuss in Next Session)
  3. We want to display quiz and quiz options on start quiz screen one by one with next and previous button to move to next question or previous question.(We'll discuss in Later Session)
In this session we want to simply display all quiz and quiz options (around random 10 quiz) on start quiz screen like as shown below.

Step 1) We have already created database table for quiz and quiz options management. Lets quickly go through the scripts.
Table Quiz : 
CREATE TABLE [dbo].[Quiz](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Question] [varchar](200) NULL,
 [AnswerType] [varchar](10) NULL,
PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Fill this table with sample questions and lets quickly test : 

select * from quiz

Table QuizOption :

CREATE TABLE [dbo].[QuizOption](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Questionid] [varchar](200) NULL,
 [Option] [varchar](200) NULL,
 [IsCorrect] [bit] NULL,
 [AnsType] [varchar](10) NULL,
PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Fill this table with sample quiz options and lets quickly test : 
select * from quizOption



Step 2) Create Procedures to Read Questions and its options.

Procedure Usp_ReadQuestions : 

CREATE PROCEDURE [dbo].[Usp_ReadQuestions]          
AS        
BEGIN      
 SELECT TOP(10)* FROM Quiz  
 ORDER BY NEWID()     
END 

Procedure Usp_ReadQuizOptionsById :
CREATE PROCEDURE [dbo].[Usp_ReadQuizOptionsById] @Id int AS BEGIN DECLARE @opts NVARCHAR(MAX); DECLARE @ids NVARCHAR(MAX); SELECT @opts = COALESCE(@opts+'*','') + qo.[Option], @ids = COALESCE(@ids+'*','') + CAST(qo.[Id] as varchar) FROM QuizOption qo WHERE qo.Questionid = @Id ORDER BY qo.[Id] SELECT @opts AS QuizOptions, @ids OptionIDs END
Lets quickly test this procedure by passing quiz id 9 and 10 to get its options by star separated: 
exec Usp_ReadQuizOptionsById 9
Output:

exec Usp_ReadQuizOptionsById 10
Output:

Step 3) We have already create models for quiz and its options in previous session i.e in part 2. Lets quickly check what we have done and enhanced in SampleMvc.Models :
Quiz Model :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SampleMvc.Models
{
    public class Quiz
    {
        public string Question { get; set; }
        public int QuestionId { get; set; }
        public string QuizOptions { get; set; }
        public string Answertype { get; set; }
    }
}
In QuizOptions Model :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SampleMvc.Models
{
    public class QuizOptions
    {
        public string Options { get; set; }
        public string IDs { get; set; }
    }
}
In QuizSet Model : We have created this model to retrieve quiz and all its
options to generate quiz set. In this model QuizOptions and OptionIDs will
hold star separated quiz options and all its options id. These Options and Ids will be splited and shown there on the screen.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SampleMvc.Models { public class QuizSet { public int QuestionId { get; set; } public string Question { get; set; } public string Answertype { get; set; } public string QuizOptions { get; set; } public string OptionIDs { get; set; } } }

Step 4) Create functions to call procedures to Read Questions and its options in SampleMvc.DA. 
Note : QuizDA inherits SQLHelper class(check for this class in previous session.)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SampleMvc.Models;
using System.Data.SqlClient;
using System.Data;

namespace SampleMvc.DA
{
    public class QuizDA : SQLHelper
    {
        public List<Quiz> ReadAllQuiz()
        {
            try
            {
                List<Quiz> questions = new List<Quiz>();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = "Usp_ReadQuestions";              
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = Connection;
                OpenConnection();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    Quiz quiz = new Quiz();
                    quiz.QuestionId = Convert.ToInt32(rdr["Id"]);
                    quiz.Question = rdr["Question"].ToString();
                    quiz.Answertype = rdr["AnswerType"].ToString();
                    questions.Add(quiz);
                }
                return questions;
            }
            catch
            {
                throw;
            }
            finally
            {
                CloseConnection();
            }
        }

        public QuizOptions ReadQuizOptions(int id)
        {
            try
            {
                QuizOptions quizoption = new QuizOptions();
                DataTable dt = new DataTable();
                dt = ExecDataTableProc("Usp_ReadQuizOptionsById", new SqlParameter("@Id", id));                
                quizoption.Options = dt.Rows[0]["QuizOptions"].ToString();
                quizoption.IDs = dt.Rows[0]["OptionIDs"].ToString();

                return quizoption;
            }
            catch
            {
                throw;
            }
            finally
            {
                CloseConnection();
            }
        }
    }
}

Step 5) Create action methods in controller class. We have created two action methods StartQuiz and ReadAllQuiz.

using SampleMvc.DA; using SampleMvc.Models; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Web; using System.Web.Mvc; namespace SampleMvc.Controllers { public class EmployeeTestController : Controller { public ActionResult StartQuiz() { return View(); } public JsonResult ReadAllQuiz() { List<QuizSet> quizSet = new List<QuizSet>(); QuizDA quizDA = new QuizDA(); List<Quiz> quizs = quizDA.ReadAllQuiz(); foreach (Quiz q in quizs) { QuizOptions options = quizDA.ReadQuizOptions(q.QuestionId); if (options != null) { quizSet.Add(new QuizSet { QuestionId = q.QuestionId, Question = q.Question ?? string.Empty, Answertype=q.Answertype, QuizOptions = options.Options, OptionIDs = options.IDs }); } } return Json(quizSet); }
}
}

Step 6) Create view for action method StartQuiz

@{ Layout = null; } <link href="~/Contents/CSS/QuizTemplate.css" rel="stylesheet" /> <link href="~/Contents/W3Css/w3.css" rel="stylesheet" /> <div id="divQuiz" class="displayQuiz w3-container w3-teal"> </div> <script src="~/Scripts/jquery-3.2.1.js"></script> <script> $(document).ready(function () { displayQuiz(); function displayQuiz() { $.ajax({ url: '/EmployeeTest/ReadAllQuiz/', type: 'POST', contentType: "application/json", dataType: "json", success: function (data) { var count = 1; if (data.length > 0) { $.each(data, function (i, q) { if (q.Answertype == 'R') { var Opts = q.QuizOptions.split("*"); var OptIds = q.OptionIDs.split("*"); var numOptions = Opts.length; $(".displayQuiz").append("<h1 style='background-color: lightseagreen;'><div class='quiz'><span class='quizno'>" + (count++) + ".</span><span class='quizTitle'>" + q.Question + "</span></div></h1>"); $(".displayQuiz").append("<ul class='quizOption' id='optionList" + count + "'></ul>") for (i = 0; i < numOptions; i++) { $("#optionList" + count).append('<li><input style="width:20px;" type="radio" value=' + OptIds[i] + ' name="dynradio" qid="' + q.QuestionId + '" /><div class="leftOpt";">' + Opts[i] + '</div></li>'); } } }); } else { } }, error: function (response) { console.log(response); } }); } }); </script>

Last Step (Optional) : Set css as per your requirements. Sample is given below :
Use <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> or import it.

In QuizTemplate.css

body {
}
ul {
    list-style: none;
}
.leftOpt {
    float: right;
    width:97%;
}
li {
    font-family: 'Roboto', sans-serif;
    padding: 10px 0;
    clear: both;
}
.quiz {
    padding-left: 10px;
}
.quizTitle {
    padding-left: 10px;

}




Sunday, 6 August 2017

Part 2 : Add Quiz and Quiz Options using ASP.NET MVC


We are using two tables:
1) Quiz
2) QuizOption




Step 1 : Create Function to split by passing split by like single comma or double comma etc.
  
CREATE FUNCTION [dbo].[func_Split]
    (
    @DelimitedString    varchar(8000),
    @Delimiter              varchar(100)
    )
RETURNS @tblArray TABLE
    (
    ElementID   int IDENTITY(1,1),  -- Array index
    Element     varchar(1000)               -- Array element contents
    )
AS
BEGIN

    -- Local Variable Declarations
    -- ---------------------------
    DECLARE @Index      smallint,
                    @Start      smallint,
                    @DelSize    smallint

    SET @DelSize = LEN(@Delimiter)

    -- Loop through source string and add elements to destination table array
    -- ----------------------------------------------------------------------
    WHILE LEN(@DelimitedString) > 0
    BEGIN

        SET @Index = CHARINDEX(@Delimiter, @DelimitedString)

        IF @Index = 0
            BEGIN

                INSERT INTO
                    @tblArray
                    (Element)
                VALUES
                    (LTRIM(RTRIM(@DelimitedString)))

                BREAK
            END
        ELSE
            BEGIN

                INSERT INTO
                    @tblArray
                    (Element)
                VALUES
                    (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1))))

                SET @Start = @Index + @DelSize
                SET @DelimitedString = SUBSTRING(@DelimitedString, @Start , LEN(@DelimitedString) - @Start + 1)

            END
    END

    RETURN
END

Step 2 : Creating Procedure to save question in Quiz table and list of answer options in QuizOption table.

CREATE PROC usp_InsertQuizData
(
@Question VARCHAR(100),
@QuizOption VARCHAR(MAX),
@AnswerType VARCHAR(10)
)
AS
BEGIN
 DECLARE @QId INT
 DECLARE @Option VARCHAR(MAX)
 INSERT INTO Quiz (Question) VALUES(@Question)
 SET @QId= @@IDENTITY
 -- As  we are getting list of option as double comma separated, we are using function func_split to split it from double
 -- comma and storing it in temp table. Also we are using cursor to fetch and save all list of option to table.
 -- Example list of options : Option1-&ture,,Option2-&false,,Option2-&false,,
 SELECT * INTO #TempQuizOption FROM dbo.func_split(@QuizOption, ',,')
 DECLARE TempQuizOption_Cursor Cursor FOR SELECT Element FROM #TempQuizOption
 OPEN TempQuizOption_Cursor
 FETCH NEXT FROM TempQuizOption_Cursor INTO @Option
 WHILE @@FETCH_STATUS = 0
 BEGIN
  INSERT INTO QuizOption (Questionid,[Option],IsCorrect,AnsType)
   VALUES(@QId,LEFT(@Option, charindex('-&', @Option) - 1),
  CAST(SUBSTRING(@Option, charindex('-&', @Option)+2, len(@Option) - CHARINDEX('-&', LEFT(@Option, charindex('-&', @Option) - 1))) AS BIT),@AnswerType)
  FETCH NEXT FROM TempQuizOption_Cursor INTO @Option
 END
 CLOSE TempQuizOption_Cursor;
 DEALLOCATE TempQuizOption_Cursor;
 DROP TABLE #TempQuizOption
END

Step 3 : Add Class Quiz in Models and Function AddQuiz in Class QuizDA. Note this class is inheriting by SQLHelper Class (Refer in Part 1 for SQLHelper.cs).

Adding Class Models :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SampleMvc.Models
{
    public class Quiz
    {
        public string Question { get; set; }
        public int QuestionId { get; set; }
        public string QuizOptions { get; set; }
        public string Answertype { get; set; }
    }

}

Adding Function in Data Access

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SampleMvc.Models;
using System.Data.SqlClient;
using System.Data;

namespace SampleMvc.DA
{
    public class QuizDA : SQLHelper
    {
        public void AddQuiz(Quiz quiz)
        {
            try
            {
                int i = ExecNonQueryProc("usp_InsertQuizData",
                new SqlParameter("@Question", quiz.Question),
                new SqlParameter("@QuizOption", quiz.QuizOptions),
                new SqlParameter("@Answertype", quiz.Answertype));
            }
            catch (Exception ex)
            {
                ErrorMessage = "Error : " + ex.Message;
                OperationStatus = false;
            }
            finally
            {
                CloseConnection();
            }
        }
    }
}

Step 4 : Adding EmployeeTest Controller 

using SampleMvc.DA;
using SampleMvc.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SampleMvc.Controllers
{
    public class EmployeeTestController : Controller
    {    
        public ActionResult AddQuiz()
        {
            return View();
        }
        [HttpPost]
        public ActionResult AddQuiz(Quiz quiz)
        {
            QuizDA quizDA = new QuizDA();
            quizDA.AddQuiz(quiz);
            return View();
        }
    }
}
Step 5 : Adding Empty View

@{
    Layout = null;
}

<script src="~/Scripts/jquery-3.2.1.js"></script>
<script>
    $(document).ready(function () {
        // We are creating list of radio button, checkbox or single textbox on selection of anstype from dropdown.
        // As many options we want we can add on option upon selecting radio button or checkbox.
        // Options are added to div havind id lstOptions.
        $('#btnAddQuiz').click(function () {
            if ($('#drpAnsType :selected').text() != "Select") {
                if ($('#drpAnsType').val() == "R") {
                    var radioBtn = $('<input type="radio" name="rbtnCount" value = "' + $("#txtAns").val() + '"/>' + $("#txtAns").val() + '<br/>');
                    $("#lstOptions").append(radioBtn);
                }
                else if ($('#drpAnsType').val() == "C") {
                    var radioBtn = $('<input type="checkbox" name="chkCount" value = "' + $("#txtAns").val() + '"/>' + $("#txtAns").val() + '<br/>');
                    $("#lstOptions").append(radioBtn);
                }              
            }
        });

        $('#btnsave').click(function () {
            var Option = "";
            if ($('#drpAnsType').val() == "R") {
                // Now we have to pass the list of options for particular question.
                // We passing list of option as double comma separated. We are separating it using double comma (,,) as there could be single comma in answers as well.
                // So we may to not get expected result while saving answers options in database.
                // Also we are appending status of option whether this option is correct or not separated by -& as there could also be single - and & in answer.
                // You may use what ever suits you.
                // Ex : Option1-&ture,,Option2-&false,,Option2-&false,,
                $('#lstOptions input:radio').each(function (index) {
                    Option = Option + $(this).attr('value') + "-&" + $(this).is(':checked') + ",,";
                });
            }
            else if ($('#drpAnsType').val() == "C") {              
                // Ex : Option1-&ture,,Option2-&true,,Option2-&false,,
                $('#lstOptions input:checkbox').each(function (index) {
                    Option = Option + $(this).attr('value') + "-&" + $(this).is(':checked') + ",,";
                });
            }
            else {
                Option = $("#txtAns").val() + "-&" + "true" + ",,";
            }
            // Passing values to controller using ajax.
            var quiz = {};
            quiz.Question = $('#txtQues').val();
            quiz.QuizOptions = Option.substring(0, Option.length - 2);
            quiz.Answertype = $('#drpAnsType option:selected').val();

            $.ajax({
                url: 'EmployeeTest/AddQuiz',
                method: 'post',
                data: '{quiz: ' + JSON.stringify(quiz) + '}',
                contentType: "application/json; charset=utf-8",
                success: function () {

                },
                error: function (err) {
                    alert(err);
                }
            });
        });


        $('#drpAnsType').change(function () {
            if ($('#drpAnsType').val() == "T") {
                $('#btnAddQuiz').hide();
            }
            else {
                $('#btnAddQuiz').show();
            }
        });
    });
</script>

<div style="padding: 30px;">
    Question<br />
    <input type="text" id="txtQues" /><br />
    Answer Type
    <br />
    <select id="drpAnsType">
        <option value="S">Select</option>
        <option value="R">Radio</option>
        <option value="C">Checkbox</option>
        <option value="T">Text</option>
    </select><br />
    Answer (Option) <br />
    <input type="text" id="txtAns" /><br />
    <br />
    <input type="button" value="Add Option" id="btnAddQuiz" />
    <div id="lstOptions" style="padding-top: 30px;">
    </div>
    <input type="button" value="Save" id="btnsave" />
</div>


Output : When selecting radio button type as options for answers

Output : When selecting check box type as options for answers

ExcelDataReader to read excel and upload bulk data in Asp.net MVC

What we want to achieve?
We want to insert bulk question and its options in question table and Option table respectively
using excel sheet as per given excel format. 

We'll be reading question and all options for that question question by question using excel data reader and implementing bulk insert.

Add library for ExcelDataReader :
  1. Install the ExcelDataReader base package to use the "low level" reader interface. 
  2. Install the ExcelDataReader.DataSet extension package to use the AsDataSet() method to populate a System.Data.DataSet. 

We'll passing all option as a single string using separator +|+ and *|* like as given below :
Option+|+true+|+1*|*Option2+|+false+|+2 that is Option+|+Iscorrect+|+OrderBy*|* to save in option table.

In View : 

@{
    ViewBag.Title = "BulkUpload";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="maincontainer">
    <div id="divExcel" class="divExcelUP">
        @using (Html.BeginForm("BulkUpload", "Question", FormMethod.Post, new { enctype = "multipart/form-data" }))
        {      
            <div class="editor-label">
                Select File :
            </div>
            <div class="editor-field">
                <input type="file" id="flExcel" name="postedFile" />
                <div id="errflExcel" class="divErr"></div>
            </div>
            <div class="editor-label">

            </div>
            <div class="editor-field">
                <input class="Button" id="btnUpload" type="submit" value="Upload" />
            </div>        
        }
    </div>
    <div class="clearfix"></div>
</div>

@section scripts{
    <script>
        $(document).ready(function () {
            $('div[id^="err"]').html("");

            var fileName = document.getElementById('flExcel').value;
            $("#btnUpload").click(function () {
                if ($("#flExcel").val() != "") {                
                }
                else {
                    $("#errflExcel").html("Please select file for bulk upload.");
                }
            });
        });
    </script>

}

In Controller : 

public ActionResult BulkUpload()
        {
            return View();
        }
        [HttpPost]
        public ActionResult BulkUpload(HttpPostedFileBase postedFile)
        {
            string ext = Path.GetExtension(postedFile.FileName);
            if (ext == ".xls" || ext == ".xlsx")
            {                
                string filePath = "";
                filePath = "/BulkUpload/" + "QA" + ext;
                string path = Server.MapPath(filePath);
                postedFile.SaveAs(path);
                // Reading excel file using excel data reader.
                using (var stream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read))
                {
                    using (var reader = ExcelReaderFactory.CreateReader(stream))
                    {
                        DataSet result = reader.AsDataSet();
                        DataTable dt = result.Tables[0];

                        int quesColumnCount = dt.Columns.Count;
                        int quesRowCount = dt.Rows.Count;
                        int quesID = Convert.ToInt32(dt.Rows[2][0]);
                        Question question = new Question();
                        QuestionDA questionDA = new QuestionDA();

                        string Option = string.Empty;

                        for (int row = 1; row <= quesRowCount - 1; row++)
                        {
                            if (quesID == Convert.ToInt32(dt.Rows[row][0]))
                            {                              
                                if (Convert.ToString(dt.Rows[row][1]) == "Q")
                                {
                                    question.Title = Convert.ToString(dt.Rows[row][2]);
                                    question.Description = Convert.ToString(dt.Rows[row][3]);
                                    question.QueImageURL = Convert.ToString(dt.Rows[row][4]);
                                    question.BaseValue = Convert.ToInt32(dt.Rows[row][5]);
                                    question.ModuleId = Convert.ToInt32(dt.Rows[row][6]);
                                    question.QuestionType = Convert.ToString(dt.Rows[row][7]);
                                }
                                else if (Convert.ToString(dt.Rows[row][1]) == "A")
                                {
                                    Option += Convert.ToString(dt.Rows[row][2]) + "+|+" + Convert.ToString(dt.Rows[row][3]) + "+|+";
                                    Option += Convert.ToInt32(dt.Rows[row][4]) + "*|*";
                                    if (row == quesRowCount - 1)
                                    {
                                        //Call function to save last set of record before exiting loop.
                                        Option = Option.Substring(0, Option.Length-3);                                     
                                        questionDA.CreateBulkQuestionOptions(question,Option);                                       
                                    }
                                }
                            }
                            else
                            {
                                //If Qid differs then call function to save data.
                                Option = Option.Substring(0, Option.Length - 3);
                                questionDA.CreateBulkQuestionOptions(question, Option);                               
                                quesID = Convert.ToInt32(dt.Rows[row][0]);
                                Option = "";
                                row--;
                            }
                        }
                    }
                }
            }
            return View();
        }

In Data Access : 

public void CreateBulkQuestionOptions(Question question, string Option)
        {
            try
            {
                int i = ExecNonQueryProc("Usp_QAModule_CreateBulkQuestionOptions",
                new SqlParameter("@Title", question.Title),
                new SqlParameter("@Description", question.Description),
                new SqlParameter("@QueImageURL", question.QueImageURL),
                new SqlParameter("@BaseValue", question.BaseValue),
                new SqlParameter("@ModuleId", question.ModuleId),
                new SqlParameter("@QuestionType", question.QuestionType),
                new SqlParameter("@CreatedOn", DateTime.Now.ToShortDateString()),
                new SqlParameter("@Options", Option));                
            }
            catch
            {
                throw;
            }
            finally
            {
                CloseConnection();
            }

        }

In Database we are using two procedures and one function in order achieve our goal with out using cursor : 

CREATE PROC [dbo].[Usp_QAModule_CreateBulkQuestionOptions]            
@Title TEXT,       
@Description TEXT,    
@QueImageURL VARCHAR(MAX),     
@BaseValue FLOAT,     
@ModuleId INT,    
@QuestionType VARCHAR(30),      
@CreatedOn DATETIME,     
@Options VARCHAR(MAX)                   
AS            
BEGIN     
  DECLARE @QId INT    
  DECLARE @Option VARCHAR(MAX)    
  
  INSERT jquestions      
  (  
  Title,     
  [Description],     
  QueImageURL,    
  BaseValue,     
  ModuleId,     
  QuestionType,     
  CreatedOn,    
  IsActive  
   )     
  VALUES    
  (  
  @Title,     
  @Description,     
  @QueImageURL,    
  @BaseValue,     
  @ModuleId,     
  @QuestionType,     
  @CreatedOn,    
  1  
   );  
  
 SET @QId= @@IDENTITY;  
  
 DECLARE @execQuery NVARCHAR(MAX);  
 SELECT @execQuery  = COALESCE(@execQuery +';' ,'') + 'EXEC [dbo].[usp_QaModule_CreateOptions] '+CAST(@QId AS VARCHAR)+', '''+ CAST(@CreatedOn AS VARCHAR) +''', '''+@QuestionType+''', ''' + Element+''', ''+|+'''  
 FROM dbo.func_split(@Options, '*|*');  
 --PRINT(@execQuery)  
 EXECUTE sp_executesql @execQuery;  
  
END

======================================================

CREATE PROCEDURE [dbo].[usp_QaModule_CreateOptions]  
    (  
  @qId INT,  
  @createdDate DATETIME,  
  @questionType VARCHAR(MAX),  
  @element    VARCHAR(MAX),  
  @delimiter VARCHAR(MAX)  
    )  
AS  
BEGIN  
 DECLARE @result BIT = 0;  
  
 ;WITH opt AS(  
  SELECT * FROM dbo.func_split(@element, '+|+')  
 )  
  
    INSERT INTO jquestionoptions            
 (  
  Id_Question,            
  [Option],            
  IsCorrect,            
  CreatedOn,            
  OptionType,        
  OrderBy  
 )            
   VALUES            
   (  
    @qId,            
    (select Element from opt where elementId = 1),                
    CAST((select Element from opt where elementId = 2) AS BIT),                
    @createdDate,         
    @questionType,  
    (select Element from opt where elementId = 3)  
   )    
  
    RETURN @result  
END

=============================================================

CREATE FUNCTION [dbo].[func_Split]  
    (  
    @DelimitedString    varchar(MAX),  
    @Delimiter              varchar(MAX)  
    )  
RETURNS @tblArray TABLE  
    (  
    ElementID   int IDENTITY(1,1),  -- Array index  
    Element     varchar(MAX)               -- Array element contents  
    )  
AS  
BEGIN  
  
    -- Local Variable Declarations  
    -- ---------------------------  
    DECLARE @Index      smallint,  
                    @Start      smallint,  
                    @DelSize    smallint  
  
    SET @DelSize = LEN(@Delimiter)  
  
    -- Loop through source string and add elements to destination table array  
    -- ----------------------------------------------------------------------  
    WHILE LEN(@DelimitedString) > 0  
    BEGIN  
  
        SET @Index = CHARINDEX(@Delimiter, @DelimitedString)  
  
        IF @Index = 0  
            BEGIN  
  
                INSERT INTO  
                    @tblArray  
                    (Element)  
                VALUES  
                    (LTRIM(RTRIM(@DelimitedString)))  
  
                BREAK  
            END  
        ELSE  
            BEGIN  
  
                INSERT INTO  
                    @tblArray  
                    (Element)  
                VALUES  
                    (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1))))  
  
                SET @Start = @Index + @DelSize  
                SET @DelimitedString = SUBSTRING(@DelimitedString, @Start , LEN(@DelimitedString) - @Start + 1)  
  
            END  
    END  
  
    RETURN  
END

Part 1 : Create Sample Application Using Asp.net MVC

Adding Employee and Retrieve it and show in table using Ajax in ASP.NET MVC

Application Name : SampleMVC
Database : NorthwindDb
Class Library : SampleMVC.DA
Class Library : SampleMVC.Models



Step 1 : Adding SQLHelper.cs Class in Class Library SampleMVC.DA

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Configuration;

namespace SampleMvc.DA
{
    /// <summary>
    /// Summary description for Class_SQLHelper
    /// </summary>
    public class SQLHelper
    {
        private SqlCommand cmd = new SqlCommand();
        private SqlConnection conn;
        private bool bool_Status;
        private string str_Error;

        public SQLHelper()
        {
            conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DBCS"].ToString());
        }

        protected void OpenConnection()
        {
            try
            {
                if (conn.State != ConnectionState.Open)
                    conn.Open();
            }
            catch (Exception ex)
            {
                OperationStatus = false;
                ErrorMessage = "Error : " + ex.Message;
            }
        }

        protected void CloseConnection()
        {
            try
            {
                if (conn.State != ConnectionState.Closed)
                    conn.Close();
            }
            catch (Exception ex)
            {
                OperationStatus = false;
                ErrorMessage = "Error : " + ex.Message;
            }
        }

        public SqlConnection Connection
        {
            get { return conn; }
        }

        public SqlCommand Command
        {
            get { return cmd; }
            set { cmd = value; }
        }

        public bool OperationStatus
        {
            get { return bool_Status; }
            set { bool_Status = value; }
        }

        public string ErrorMessage
        {
            get { return str_Error; }
            set { str_Error = value; }
        }

        /// <summary>
        /// Constructs a SqlCommand with the given parameters. This method is normally called
        /// from the other methods and not called directly. But here it is if you need access
        /// to it.
        /// </summary>
        /// <param name="qry">SQL query or stored procedure name</param>
        /// <param name="type">Type of SQL command</param>
        /// <param name="args">Query arguments. Arguments should be in pairs where one is the
        /// name of the parameter and the second is the value. The very last argument can
        /// optionally be a SqlParameter object for specifying a custom argument type</param>
        /// <returns></returns>
        public SqlCommand CreateCommand(string qry, CommandType type, params object[] args)
        {
            SqlCommand cmd = new SqlCommand(qry, conn);
            OpenConnection();
            // Set command type
            cmd.CommandType = type;

            // Construct SQL parameters
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] is string && i < (args.Length - 1))
                {
                    SqlParameter parm = new SqlParameter();
                    parm.ParameterName = (string)args[i];
                    parm.Value = args[++i];
                    cmd.Parameters.Add(parm);
                }
                else if (args[i] is SqlParameter)
                {
                    cmd.Parameters.Add((SqlParameter)args[i]);
                }
                else throw new ArgumentException("Invalid number or type of arguments supplied");
            }

            return cmd;
        }

        /// <summary>
        /// Executes a stored procedure that returns no results
        /// </summary>ExecNonQueryProc
        /// <param name="proc">Name of stored proceduret</param>
        /// <param name="args">Any number of parameter name/value pairs and/or SQLParameter arguments</param>
        /// <returns>The number of rows affected</returns>
        public int ExecNonQueryProc(string proc, params object[] args)
        {
               int result = 0;        
                using (SqlCommand cmd = CreateCommand(proc, CommandType.StoredProcedure, args))
                {
                    result= cmd.ExecuteNonQuery();
                    CloseConnection();
                    return result;
                }        
        }

        /// <summary>
        /// Executes a query that returns a single value
        /// </summary>
        /// <param name="proc">Name of stored proceduret</param>
        /// <param name="args">Any number of parameter name/value pairs and/or SQLParameter arguments</param>
        /// <returns>Value of first column and first row of the results</returns>
        public object ExecScalarProc(string qry, params object[] args)
        {
            using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
            {
                return cmd.ExecuteScalar();
            }
        }

        /// <summary>
        /// Executes a stored procedure and returns the results as a SqlDataReader
        /// </summary>
        /// <param name="proc">Name of stored proceduret</param>
        /// <param name="args">Any number of parameter name/value pairs and/or SQLParameter arguments</param>
        /// <returns>Results as a SqlDataReader</returns>
        public SqlDataReader ExecDataReaderProc(string qry, params object[] args)
        {
            using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
            {
                return cmd.ExecuteReader();
            }
        }

        /// <summary>
        /// Executes a stored procedure and returns the results as a Data Set
        /// </summary>
        /// <param name="proc">Name of stored proceduret</param>
        /// <param name="args">Any number of parameter name/value pairs and/or SQLParameter arguments</param>
        /// <returns>Results as a DataSet</returns>
        public DataSet ExecDataSetProc(string qry, params object[] args)
        {
            using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
            {
                SqlDataAdapter adapt = new SqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                adapt.Fill(ds);
                return ds;
            }
        }

        /// <summary>
        /// Executes a stored procedure and returns the results as a Data Set
        /// </summary>
        /// <param name="proc">Name of stored proceduret</param>
        /// <param name="args">Any number of parameter name/value pairs and/or SQLParameter arguments</param>
        /// <returns>Results as a DataTable</returns>
        public DataTable ExecDataTableProc(string qry, params object[] args)
        {
            using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure, args))
            {
                SqlDataAdapter adapt = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                adapt.Fill(dt);
                return dt;
            }
        }

        /// <summary>
        /// Executes a stored procedure and returns the results as a Data Set
        /// </summary>
        /// <param name="proc">Name of stored proceduret</param>
        /// <returns>Results as a DataTable</returns>
        public DataTable ExecDataTableProc(string qry)
        {
            using (SqlCommand cmd = CreateCommand(qry, CommandType.StoredProcedure))
            {
                SqlDataAdapter adapt = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                adapt.Fill(dt);
                return dt;
            }
        }
    }
}

Step 2 : Adding Class EmployeeDA.cs in Class Library SampleMVC.DA and inheriting it with SQLHelper.cs and call required function of SQLHelper Class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SampleMvc.Models;
using System.Data.SqlClient;
using System.Data;

namespace SampleMvc.DA
{
    public class EmployeeDA : SQLHelper
    {
        public void AddEmployee(Employee emp)
        {
            try
            {
                int i = ExecNonQueryProc("Usp_AddEmployee",
                new SqlParameter("@LastName", emp.LastName),
                new SqlParameter("@FirstName", emp.FirstName),
                new SqlParameter("@Title", emp.Title),
                new SqlParameter("@Birthdate", emp.BirthDate));
            }
            catch (Exception ex)
            {
                ErrorMessage = "Error : " + ex.Message;
                OperationStatus = false;
            }
            finally
            {
                CloseConnection();
            }
        }

        public DataTable GetAllEmployees()
        {
            DataTable dt = new DataTable();
            dt = ExecDataTableProc("Usp_GetAllEmployees");
            return dt;
        }
    }
}

Step 3 : Build And Add Class Libraries in SampleMVC

Step 4 : Adding EmployeeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SampleMvc.Models;
using SampleMvc.DA;
using System.Data;
using System.Web.Script.Serialization;

namespace SampleMvc.Controllers
{
    public class EmployeeController : Controller
    {      
        public ActionResult AddEmployee()
        {
            return View();
        }
        [HttpPost]
        public ActionResult AddEmployee(Employee emp)
        {
            EmployeeDA employeeDA = new EmployeeDA();
            employeeDA.AddEmployee(emp);
            return View();
        }
        public ActionResult GetAllEmployees()
        {
            DataTable dt = new DataTable();
            EmployeeDA employeeDA = new EmployeeDA();
            dt=employeeDA.GetAllEmployees();
            String emp = ConvertDataTableTojSonString(dt);
            return Json(emp);
        }

        public String ConvertDataTableTojSonString(DataTable dataTable)
        {
            System.Web.Script.Serialization.JavaScriptSerializer serializer =
                   new System.Web.Script.Serialization.JavaScriptSerializer();

            List<Dictionary<String, Object>> tableRows = new List<Dictionary<String, Object>>();

            Dictionary<String, Object> row;

            foreach (DataRow dr in dataTable.Rows)
            {
                row = new Dictionary<String, Object>();
                foreach (DataColumn col in dataTable.Columns)
                {
                    row.Add(col.ColumnName, dr[col]);
                }
                tableRows.Add(row);
            }
            return serializer.Serialize(tableRows);
        }
    }
}

Step 5 : Adding AddEmployee view

@{
    Layout = null;
}

<script src="~/Scripts/jquery-3.2.1.js"></script>
<script>
    $(document).ready(function () {
        getAllEmployees();
        $('#btnAddEmployee').click(function () {
            var employee = {};
            employee.LastName = $('#txtLastName').val();
            employee.FirstName = $('#txtFirstName').val();
            employee.Title = $('#txtTitle').val();
            employee.BirthDate = $('#txtDob').val();

            $.ajax({
                url: 'Employee/AddEmployee',
                method: 'post',
                data: '{emp: ' + JSON.stringify(employee) + '}',
                contentType: "application/json; charset=utf-8",
                success: function () {
                    getAllEmployees();
                },
                error: function (err) {
                    alert(err);
                }
            });
        });
        
        function getAllEmployees() {
            $.ajax({
                url: 'Employee/GetAllEmployees',
                dataType: "json",
                method: 'post',
                success: function (data) {
                    var employeeTable = $('#tblEmployee tbody');
                    employeeTable.empty();                 
                    $(JSON.parse(data)).each(function (index, emp) {
                       
                            employeeTable.append('<tr><td>' + emp.LastName + '</td><td>'
                            + emp.FirstName + '</td><td>' + emp.Title
                            + '</td><td>' + emp.BirthDate + '</td></tr>');
                    });
                },
                error: function (err) {
                    alert(err);
                }
            });
        }
    });
</script>

<div style="padding: 30px;">
    Last Name<br />
    <input type="text" id="txtLastName" /><br />
    First Name<br />
    <input type="text" id="txtFirstName" /><br />
    Title
    <br />
    <input type="text" id="txtTitle" /><br />
    DOB<br />
    <input type="text" id="txtDob" />
    <br />
    <br />
    <input type="button" value="Save" id="btnAddEmployee" />
</div>

@*Table to display data *@

    <table id="tblEmployee" border="1" style="border-collapse:collapse">
        <thead>
            <tr>
                <th>Last Name</th>
                <th>First Name</th>
                <th>Title</th>
                <th>DOB</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table> 

Monday, 24 July 2017

DropdownList in MVC Strongly Typed

View

 <div class="editor-label">
            Country
        </div>
        <div class="editor-field">
         
            @Html.DropDownListFor(model=>model.CountryId, new SelectList((ViewBag.Countries) as SelectList, "Value", "Text"), "Select")
        </div>


-----------------------------------
Controller
  CountryDA countryda = new CountryDA ();
 ViewBag.Countries =new SelectList(countryda.ReadAllCountry(), "CountryId", "CountryName", _country.CountryId);
     
-------------------------------
DATA Access

  public List<Country> ReadAllCountry()
        {
            List<Country> country = new List<Country>();
            try
            {
                using (SqlConnection con = new SqlConnection(connectionstring))
                {
                    SqlCommand com = new SqlCommand("Usp_ReadAllCountry", con);
                    com.CommandType = CommandType.StoredProcedure;
                    con.Open();
                    SqlDataReader dr = com.ExecuteReader();

                    while (dr.Read())
                    {
                        country.Add(new Country { CountryId = Convert.ToInt32(dr["CountryId"]), CountryName = Convert.ToString(dr["CountryName"]) });
                    }
                }
            }
            catch
            {
                throw;
            }
            return country;
        }

---------------------------------------
Model
   public class Country
    {
        public int CountryId { get; set; }
        public string CountryName { get; set; }
    }