0

I have a form that is flexible. Meaning that depending on what selection you make in a dropdownlist the fields will be different. Also, the controller action that is called will also change. I am trying to get this to work with just a simple example, but I can't find how to submit data to the controller and have the controller map it correctly to a defined class.

Clarification: When a user creates a new question that has only one choice this is the form/controller that they are using. However, when they create a question with multiple choices I would like to use the same form/controller. The error i am getting is that the object is null. Which i think means that whenever the data is being passed to the controller, it is not being properly mapped into the object. How can i map the data explicitly into my defined object? Or should i do this whole thing differently?

Here is the controller:

    [HttpPost]
    public ActionResult CreateSimpleQuestion(SimpleQuestion question)
    {
        if (ModelState.IsValid)
        {
            question.question.is_counted = true;
            question.question.DateCreated = DateTime.Now;
            db.Questions.Add(question.question);
            db.QuestionChoices.Add(question.choices[0]);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(question);
    }

Here is the class:

    [Serializable]
    public class SimpleQuestion
    {
        public Question question { get; set; }

        public QuestionChoices[] choices { get; set; }
    }

Here is the script that is calling the controller action:

<script type="text/javascript">
    $("form").on("submit", function (event) {
        event.preventDefault();
        var data = $('form').serialize();
        console.log(data);
        $.post('/Question/CreateSimpleQuestion/', data);
    });
</script>

This is the serialized data:

QuestionTitle=faketitle&Keywords=fakekeywords&Description=fakedescription&Comments=fakecomments&QuestionType=Simple&DisplayText=fakequestiontext&OrderNumber=fakeorder

And in case you need the specifics of the model:

public class Question
{
    public int QuestionId { get; set; }

    public string QuestionTitle { get; set; }

    public DateTime DateCreated { get; set; }

    public string QuestionType { get; set; }

    public string Keywords { get; set; }

    public bool is_counted { get; set; }

    public int? ParentId { get; set; }

    [Column(TypeName = "ntext")]
    [MaxLength]
    public string Description { get; set; }

    [Column(TypeName = "ntext")]
    [MaxLength]
    public string Comments { get; set; }

    //These define a one to many relationship
    public virtual ICollection<TeamQuestionRoster> TeamQuestionRosters { get; set; }

    public virtual ICollection<Response> Responses { get; set; }

    public virtual ICollection<QuestionChoices> QuestionChoices { get; set; }
}



public class QuestionChoices
{
    public int QuestionChoicesId { get; set; }

    public string DisplayText { get; set; }

    public int OrderNumber { get; set; }

    public bool is_correct { get; set; }

    //These are the FK properties
    public int QuestionId { get; set; }

    //This defines the FK Relationships
    public virtual Question Question { get; set; }

    //These define a one to many relationship
    public virtual ICollection<ResponseDetails> ResponsDetails { get; set; }
}
schumacherj
  • 1,284
  • 5
  • 18
  • 33
  • 1
    Can you please clarify your problem? I think that your are trying to have a single route for all permeations of your "flexible" form but possibly have different processing based on the object received. Is this correct? – Vinney Kelly Oct 31 '13 at 16:55
  • Sorry for the ambiguity. Let me know if i need to give a better example. – schumacherj Oct 31 '13 at 17:20

1 Answers1

1

I think you might be having a issue with your media type. Try posting JSON like this:

$.post('/Question/CreateSimpleQuestion', data, function() { /* success callback */ }, 'application/json');

EDIT: The $.post shorthand method might be expecting 'json' rather than 'application/json'. I typically use $.ajax instead.

TAKE 2: Based the JSON you posted, I can see that your data is not being serialized properly. You're getting name/value pairs instead of actual JSON objects. Your JSON data should like this:

{
    "QuestionId" : 0, 
    "QuestionTitle" : "My Title",
    "Description": "My Description"
}

Here's another SO post explaining how to convert the jQuery serialize results to an appropriate JSON object: Convert form data to JavaScript object with jQuery

Hope that helps :)

Community
  • 1
  • 1
Vinney Kelly
  • 4,975
  • 1
  • 25
  • 31
  • I'm not sending it as JSON, but I think i am going to try that. `json.stringify` – schumacherj Oct 31 '13 at 17:57
  • Still not working: ` Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    `
    – schumacherj Oct 31 '13 at 18:07
  • Here is the data that is being sent to the controller: {"name":"QuestionTitle","value":"Test5 with jquery"},{"name":"Keywords","value":"(keywords)"},{"name":"Description","value":"question"},{"name":"Comments","value":"comment"},{"name":"QuestionType","value":"Simple"},{"name":"DisplayText","value":"hi"},{"name":"OrderNumber","value":"1"}, – schumacherj Oct 31 '13 at 18:08
  • Please see my revised answer. – Vinney Kelly Oct 31 '13 at 18:29
  • I think that its getting closer to the right answer, but its still not serializing it correctly. `{ "QuestionTitle":["newQuestion",""], "Keywords":"Partial", "Description":"question", "Comments":"comment", "QuestionType":["Simple","Simple"], "DisplayText":"hi", "OrderNumber":"1" }` I'm not sure why its submitting two values in title and type. Also Display text and OrderNumber should be nested with a parent field of choice.... or something like that. – schumacherj Oct 31 '13 at 18:40
  • Here is a link to the test site.... Most links don't work yet, but click on the create tab to get to the form. https://drive0.azurewebsites.net/question – schumacherj Oct 31 '13 at 18:44
  • 1
    Do you happen to have duplicate form elements rendered? That would explain the array values being supplied. Try building a proper JSON element by hand and see if your model isn't null in the controller. From there, you just need to determine where your serialization issues are. – Vinney Kelly Oct 31 '13 at 18:46
  • I've stared at this too long to see the mistakes. I checked for duplicates, but i didn't see any. I prolly just passed over them. **Edit** Fixed that issue. – schumacherj Oct 31 '13 at 18:47