2

I am using just mvc 3 with c# and ajax javascript and I have a view with a strongly typed model bound to it.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication2.Models.Car>" %>

And I am submitting via a ActionLink...

<%=Html.ActionLink("Add Car", "AddCar", "Car", new { id = "tester" })%>

this all goes through the ajax/javascript call...

$('#tester').click(function (e)
    {

        e.preventDefault();
        $(this).parents('form').first().submit();

        $.ajax({
            url: "Car/AddCar",
            type: "POST",
            data: { ID: $('#carid').val(), Manufacturer: "test", Model: "Test", Year: "01/01/2010" },
            success: function (data)
            {
                alert(data);
            }
        });
    }); 

The controller method gets the page data just fine...

[HttpPost]
    public ActionResult AddCar(Car newcar)
    {
        if (newcar.Passengers == null)//this is always null... data is not being persisted
            newcar.Passengers = new Dictionary<int, string>();

        newcar.Passengers.Add(newcar.ID, newcar.Model);
        IList<Car> cars = _carService.AddCarToGarage(newcar);
        return View("Index", newcar);            
    }

However I do not know how to persist the Passengers dictionary data after it has been created here in the controller. Everytime I click the Actionlink, the Passengers data is null...

How do I keep the Passengers data between ajax calls?

Thanks!

+++++++++++++++++++++++++++++++++++++++++++++++

EDIT:

I am updating this question with the format of the answer below that worked for me...

The View =

<form id="my-form" method="post" action="/Car/AddCar">
<h2>Index</h2>
<%
    Response.Write("<input type=\"hidden\" name=\"ID\" value=\"" + Model.ID + "\">");
    Response.Write("<input type=\"hidden\" name=\"Manufacturer\" value=\"" + Model.Manufacturer + "\">");
    Response.Write("<input type=\"hidden\" name=\"Model\" value=\"" + Model.Model + "\">");
    Response.Write("<input type=\"hidden\" name=\"Year\" value=\"" + Model.Year.ToShortDateString() + "\">");

    if (Model.Passengers != null)
    {
        for (int i = 0; i < Model.Passengers.Count; i++)
        {
            Response.Write("<input type=\"hidden\" name=\"newcar.Passengers[" + i + "].Id\" value=\"" + Model.Passengers[i].Id + "\">");
            Response.Write("<input type=\"hidden\" name=\"newcar.Passengers[" + i + "].Name\" value=\"" + Model.Passengers[i].Name + "\">");
        }
    }
     %>

<input type="button" value="Submit" id="form-submit" />

The Controller =

[HttpPost]
    public ActionResult AddCar(Car newcar)
    {
        if (newcar.Passengers == null)
            newcar.Passengers = new List<Passenger>();

        Passenger p = new Passenger();
        p.Id = newcar.ID;
        p.Name = "tester";
        newcar.Passengers.Add(p);
        return View("Index", newcar);            
    }

The javascript =

<script type="text/javascript">
    $(document).on('click', '#form-submit', function () {
        $.ajax({
            url: "Car/AddCar",
            type: "POST",
            data: $('form#my-form').serialize(),
            success: function (data) {
                alert(data);
                // put the data in the container where you have the form.
            }
        });
    });

4
  • The view must have the Passengers as well, and you must send into data at ajax call the Passengers data from the form, or its will be null every time! Commented Jun 24, 2013 at 17:49
  • How do I send a Dictionary<int,string> through the Data parameters? Do I need to create a .js variable of the existing dictionary values from the model in the view to then pass into the data parameter array? Commented Jun 24, 2013 at 18:11
  • Why are you submitting a form and performing an ajax request at the same time? Commented Jun 24, 2013 at 19:48
  • rossipedia is correct, i am calling it twice... i have removed the following line ... <%=Html.ActionLink("Add Car", "AddCar", "Car", new { id = "tester" })%> to be simply ... <div id="tester"> this is a test </div> However, i still get back a null Passengers dictionary in my model... any ideas as to why? Commented Jun 24, 2013 at 20:04

1 Answer 1

2

The usual approach is to have a form in your view. The form should have all inputs generated correctly. Given the model:

public class Car
{
    public int Id { get; set; }
    public string Manufacturer { get; set; }
    public string Model { get; set; }
    public DateTime Year { get; set; }
    public List<Passanger> Passangers { get; set; }
}

public class Passanger
{
    public int Id { get; set; }
    public string Name { get; set; }
}

The view should have approximately the following:

@model Car
@using(Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { id = "my-form" }))
{
    @Html.HiddenFor(x => x.Id)
    @Html.TextBoxFor(x => x.Manufacturer)
    @Html.TextBoxFor(x => x.Model)
    @Html.TextBoxFor(x => x.Year)

    for(int i = 0, i < Model.Passangers.Count(), i++)
    {
        @Html.HiddenFor(x => Model.Passangers[i].Id)
        @Html.HiddenFor(x => Model.Passangers[i].Name)
    }

    <input type="button" value="Submit" id="form-submit" />
}

<script type="text/javascript">
    $(document).on('click', '#form-submit', function(){
        $.ajax({
            url: "Car/AddCar",
            type: "POST",
            data: $('form#my-form').serialize(),
            success: function (data)
            {
                alert(data);
                // put the data in the container where you have the form.
            }
        });
    });
</script>

This way when your form is posted, the data posted will include passengers because their information was rendered in the hiddens on the View.

Sign up to request clarification or add additional context in comments.

5 Comments

I didnt think of a for-loop with the hidden html. If that maintains the dictioanry so that it passes in via mvc binder to the controller , then that might just work for me, let me give it a shot... i need to translate your post to non-razor syntax ....
note line data: $('form#my-form').serialize() in javascript. it might also make your coding easier.
How do I convert the following line = @using(Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { id = "my-form" })) Into standard html format?
I got the rest of this suggestion working, except that Passengers is still coming through null...
I am sorry, I was wrong - this suggestion works, I just forgot to re post the success data to the hidden fields. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.