1

I am working on a survey application with Asp.Net MVC.

I have a page named Index.cshtml which has a question table and a 'Add New' button.Once button clicked, a popup is opened with jQuery. I am calling a view from controller to fill jQuery dialog named as AddOrEdit.cshtml (child page). I am adding new question and options. Question is a textfield and its options are added in editable table. Once clicked submit button, Submit form event (save or update) is fired. Asp.Net MVC ajax sends empty object to Controller. My Question object has Option list.So one-to-many relation.

Index.cshtml and submit(ajax) function

@{
ViewBag.Title = "Soru Listesi";
}

<h2>Soru Oluşturma</h2>
<a class="btn btn-success" style="margin-bottom: 10px" 
onclick="PopupForm('@Url.Action("AddOrEdit","Question")')"><i class="fa fa-plus"></i> Yeni Soru 
Oluştur</a>
 <table id="questionTable" class="table table-striped table-bordered accent-blue" style="width: 
  100%">
<thead>
    <tr>
        <th>Soru No</th>
        <th>Soru Adı</th>
        <th>Oluşturma Tarihi</th>
        <th>Güncelleme Tarihi</th>
        <th>Güncelle/Sil</th>
    </tr>
</thead>
</table>
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
 <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />



@section Scripts{
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>

<script>


    var Popup, dataTable;
    $(document).ready(function() {

        dataTable = $("#questionTable").DataTable({
            "ajax": {
                "url": "/Question/GetData",
                "type": "GET",
                "datatype": "json"
            },
            "columnDefs": [
                { targets: 2 }
            ],
            "scrollX": true,
            "scrollY": "auto",
            "columns": [
                { "data": "QuestionId" },
                { "data": "QuestionName" },
                {
                    "data": "CreatedDate",
                    "render": function(data) { return getDateString(data); }
                },
                {
                    "data": "UpdatedDate",
                    "render": function(data) { return getDateString(data); }
                },
                {
                    "data": "QuestionId",
                    "render": function(data) {
                        return "<a class='btn btn-primary btn-sm' onclick=PopupForm('@Url.Action("AddOrEdit", "Question")/" +
                            data +
                            "')><i class='fa fa-pencil'></i> Güncelle</a><a class='btn btn-danger btn-sm' style='margin-left:5px' onclick=Delete(" +
                            data +
                            ")><i class='fa fa-trash'></i> Sil</a>";
                    },
                    "orderable": false,
                    "searchable": false,
                    "width": "150px"
                }
            ],
            "language": {
                "emptyTable":
                    "Soru bulunamadı, lütfen <b>Yeni Soru Oluştur</b> butonuna tıklayarak yeni soru oluşturunuz. "
            }
        });
    });


    function getDateString(date) {
        var dateObj = new Date(parseInt(date.substr(6)));
        let year = dateObj.getFullYear();
        let month = (1 + dateObj.getMonth()).toString().padStart(2, '0');
        let day = dateObj.getDate().toString().padStart(2, '0');
        return day + '/' + month + '/' + year;
    };


    function PopupForm(url) {
        var formDiv = $('<div/>');
        $.get(url)
            .done(function(response) {
                formDiv.html(response);
                Popup = formDiv.dialog({
                    autoOpen: true,
                    resizable: true,
                    title: 'Soru Detay',
                    modal: true,
                    height: 'auto',
                    width: '700',
                    close: function() {
                        Popup.dialog('destroy').remove();
                    }

                });
            });
    }

    function SubmitForm(form) {
        event.preventDefault();

        if (form.checkValidity() === false) {
            event.stopPropagation();
        }
        form.classList.add('was-validated');
        if ($(form).valid()) {
            var question = {};
            question.questionId = 1111;
            var options = new Array();
            $("#questionForm TBODY TR").each(function() {
                var row = $(this);
                var option = {};
                option.OptionId = row.find("TD").eq(0).html();
                option.OptionName = row.find("TD").eq(1).html();
                options.push(option);
            });
            question.options = options;
            question.responses = new Array();
            $.ajax({
                type: "POST",
                url: form.action,
                data: JSON.stringify(question),
                success: function(data) {
                    if (data.success) {
                        debugger;
                        Popup.dialog('close');
                        //dataTable.ajax.reload();
                        $.notify(data.message,
                            {
                                globalPosition: "top center",
                                className: "success",
                                showAnimation: "slideDown",
                                gap: 1000
                            });
                    }
                },
                error: function(req, err) {
                    debugger;
                    alert('req : ' + req + ' err : ' + err);
                },
                complete: function(data) {
                    alert('complete : ' + data.status);
                }
            });
        }
    }


    function ResetForm(form) {
        Popup.dialog('close');
        return false;
    }

    function Delete(id) {
        if (confirm('Bu soruyu silmek istediğinizden emin misiniz?')) {
            $.ajax({
                type: "POST",
                url: '@Url.Action("Delete", "Question")/' + id,
                success: function(data) {
                    if (data.success) {
                        dataTable.ajax.reload();
                        $.notify(data.message,
                            {
                                className: "success",
                                globalPosition: "top center",
                                title: "BAŞARILI"
                            })
                    }
                }

            });
        }
    }

</script>
}

QuestionController AddOrEdit action

    [HttpPost]
    public ActionResult AddOrEdit(Questions question)
    {

        using (MerinosSurveyEntities db = new MerinosSurveyEntities())
        {
            List<Options> options = (List<Options>) question.Options;
            List<Options> existingOptions =  new List<Options>(db.Options.Where(x => x.Status && x.IsActive && x.QuestionId == question.QuestionId));
            foreach (Options existingOption in existingOptions)
            {
                Options optionUpdated = options.FirstOrDefault(x => x.OptionId == existingOption.OptionId);
                if (optionUpdated != null)
                {
                    //Update
                    existingOption.UpdatedDate = DateTime.Now;
                    existingOption.OptionName = optionUpdated.OptionName;
                    existingOption.IsActive = true;
                    existingOption.Status = true;
                    db.Options.Attach(existingOption);
                    db.Entry(existingOption).State = EntityState.Modified;
                    db.SaveChanges();
                    options.RemoveAll(x => x.OptionId == existingOption.OptionId);
                }
                else
                {
                    //Delete
                    existingOption.Status = false;
                    existingOption.UpdatedDate = DateTime.Now;
                    db.Options.Attach(existingOption);
                    db.Entry(existingOption).State = EntityState.Modified;
                    db.SaveChanges();
                }
            }
            foreach (Options optionNew in existingOptions)
            {
                optionNew.IsActive = true;
                optionNew.Status = true;
                optionNew.CreatedDate = DateTime.Now;
                optionNew.UpdatedDate = DateTime.Now;
                db.Options.Add(optionNew);
                db.SaveChanges();
                return Json(new { success = true, message = "Soru ve seçenekleri başarılı şekilde oluşturuldu/güncellendi." }, JsonRequestBehavior.AllowGet);

            }                

          //  db.Questions.Attach(question);
            return Json(new { success = true, message = "Soru başarılı bir şekilde güncellendi." }, JsonRequestBehavior.AllowGet);
        }

    }

Question object

 //------------------------------------------------------------------------------
 // <auto-generated>
 //------------------------------------------------------------------------------

 namespace MerinosSurvey.Models
 {
 using System;
 using System.Collections.Generic;

 public partial class Questions
 {
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Questions()
    {
        this.Responses = new HashSet<Responses>();
        this.Options = new HashSet<Options>();
    }

    public int QuestionId { get; set; }
    public string QuestionName { get; set; }
    public int QuestionTypeId { get; set; }
    public System.DateTime CreatedDate { get; set; }
    public int CreatedUserId { get; set; }
    public bool IsActive { get; set; }
    public bool Status { get; set; }
    public System.DateTime UpdatedDate { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Responses> Responses { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Options> Options { get; set; }
  }
 }

Option class

 //------------------------------------------------------------------------------
 // <auto-generated>
 //------------------------------------------------------------------------------

namespace MerinosSurvey.Models
{
using System;
using System.Collections.Generic;

public partial class Options
{
    public int OptionId { get; set; }
    public string OptionName { get; set; }
    public int QuestionId { get; set; }
    public System.DateTime CreatedDate { get; set; }
    public System.DateTime UpdatedDate { get; set; }
    public bool IsActive { get; set; }
    public bool Status { get; set; }

    public virtual Questions Questions { get; set; }
}
}
8
  • Can you show what value you are getting at this line JSON.stringify(question) Commented Dec 27, 2019 at 13:43
  • In QuestionController AddOrEdit action code block you provided a lot of commented out code - either remove it or uncomment. Commented Dec 27, 2019 at 13:58
  • It often happens that due to default PascalCase serializers in C# and camelCase in JavaScript properites can't be matched. Check your serializer settings in C#. Commented Dec 27, 2019 at 14:02
  • @GrayCat sorry I uncommented code Commented Dec 27, 2019 at 14:35
  • @RajeshG "{"questionId":1111,"options":[{"OptionId":"2","OptionName":"Çok iyi"},{"OptionId":"3","OptionName":"Iyi"},{"OptionId":"4","OptionName":"Kötü"}],"responses":[]}" Commented Dec 27, 2019 at 14:38

1 Answer 1

1

I finally solved the problem. Because I forgot to add 'contentType' to the section where I sent an ajax request, 'ajax' was sending empty objects to the controller. But both Pascal case and camel case I tried with the result has not changed. I've seen Ajax work independently in Case.

I'm adding the section I'm editing. In this case, it works without problems.

function SubmitForm(form) {
        event.preventDefault();

        if (form.checkValidity() === false) {
            event.stopPropagation();
        }
        form.classList.add('was-validated');
        if ($(form).valid()) {
            var question = {};
            question.questionId = 1111;
            question.questionName = "Name";
            var options = new Array();
            $("#questionForm TBODY TR").each(function() {
                var row = $(this);
                var option = {};
                option.optionId = row.find("TD").eq(0).html();
                option.optionName = row.find("TD").eq(1).html();
                option.questionId = 0;
                option.isActive = true;
                option.status = true;
                options.push(option);
            });

            question.options = options;
            question.responses = new Array();
            $.ajax({
                type: "POST",
                url: form.action,
                data: JSON.stringify(question),
                contentType: "application/json",//this is the line I forgot to add.
                success: function(data) {
                    if (data.success) {
                        debugger;
                        Popup.dialog('close');
                        //dataTable.ajax.reload();
                        $.notify(data.message,
                            {
                                globalPosition: "top center",
                                className: "success",
                                showAnimation: "slideDown",
                                gap: 1000
                            });
                    }
                },
                error: function(req, err) {
                    debugger;
                    alert('req : ' + req + ' err : ' + err);
                },
                complete: function(data) {
                    alert('complete : ' + data.status);
                }
            });
        }
    }
Sign up to request clarification or add additional context in comments.

Comments