0

In a strongly-typed list-view, I am trying to pass the current data on (as a list of the model) to my controller via Ajax, so it can do something with it.

The problem I am facing, is that I cannot seem to pass the list of data in the current view to my controller. Using the AJAX method without parameter works (but I need to use the parameter, or if there is some other way to provide said information to my controller?).

I have also tried making a list (test) when the view is being constructed and then using that variable as a parameter but apparently after construction the variable is empty?

Index view

@model IEnumerable<databaseModel.cbms>

@{
    ViewBag.Title = "Cbms Home";
    List<databaseModel.cbms> test = Model.ToList();
}

@Ajax.ActionLink("productId", "AJX_SortByProductId", new { cbmsModel = test }, new AjaxOptions()
                    {
                        HttpMethod = "GET",
                        UpdateTargetId = "divCbms",
                        InsertionMode = InsertionMode.Replace
                    })

Controller

public PartialViewResult AJX_SortByProductId(List<cbms> cbmsModel)
        {            
            //Retrieves the data
            List<cbms> model = cbms.SortByProductId();
            //Returns the partial view
            return PartialView("_Cbms", model);
        }

So, when I get into the controller, the List cbmsModel is empty and I cannot use it as a parameter. I can pass on a string with no problem, but I want a list of the current model data on my view.

EDIT:

The following also does not work:

Model

@model IEnumerable<databaseModel.cbms>

@{
    ViewBag.Title = "Cbms Home";
    List<databaseModel.cbms> test = Model.ToList();  
    List<databaseModel.cbms> cbmsModel = new List<databaseModel.cbms>();    
    int i = 0;
    foreach (databaseModel.cbms value in test)
    {
        i++;
        TempData.Add(i.ToString(), value);
    }        
}


@Ajax.ActionLink("productId", "AJX_SortByProductId", new { cbmsModel = TempData.Values.ToList() }, new AjaxOptions()
               {
                   HttpMethod = "GET",
                   UpdateTargetId = "divCbms",
                   InsertionMode = InsertionMode.Replace
               })

This still results in the parameter being empty. I really do not get why...

tereško
  • 58,060
  • 25
  • 98
  • 150
DaGrooveNL
  • 177
  • 1
  • 1
  • 10
  • Either store the list in the ViewBag and use it inside the controller or stringify your data on view before sending it on the server. – Aditya Singh Sep 09 '14 at 11:18
  • I tried storing it in the Viewbag (for example Viewbag.Temp, ViewBag.Temp = test OR ViewBag.Temp = Model.ToList();), but the Viewbag.Temp is also empty when I pass it in my Ajax method. – DaGrooveNL Sep 09 '14 at 11:21
  • After some extensive debugging, I found out that cbmsModel gets disposed of afer the view is loaded, including every other variable except TempData. Now the question is, how do I use TempData to pass on the variable? Since using @Ajax.ActionLink("productId", "AJX_SortByProductId", new { cbmsModel = TempData.Values.ToList() }, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "divCbms", InsertionMode = InsertionMode.Replace }) does not work. – DaGrooveNL Sep 09 '14 at 12:14

2 Answers2

0

I see you use Ajax.ActionLink, it's dangerous, because it will generate a link => HTTP request GET and those requests have limitation: Get request limitations

If you want to send "complex" model by Ajax, I recommend to use POST requests which have no limitations. I see you don't have forms, if I understand well you want to have a view with the info displayed & a button to send those information to the next action. The only way I can think about that is using jquery ajax request & serializing the object in json. The serialization can be done directly in the view using some helpers or JSON.NET or you can display the result in a table and get your info using javascript.

$.ajax({
url : ""AJX_SortByProductId/productId",
type: "POST",
data : formData, //the data you want to send
success: function(data, textStatus, jqXHR)
{
    //data - response from server
}

});

If you still want to use @Ajax.ActionLink, you have to pay attention at the url and see if the model is serialized correctly, the generated html can help.

Community
  • 1
  • 1
Giu
  • 1,832
  • 2
  • 16
  • 31
  • Changing the method to: HttpMethod = "POST" does not resolve the issue. The data is currently being displayed fine, the issue is that a variable which I declare in the view which contains data, is filled upon creation of the view (so it does contain the data then), but when I click on the button associated with it (in this case an Ajax ActionLink), the variable is empty. – DaGrooveNL Sep 09 '14 at 11:27
  • Ajax.ActionLink is not really recommended to send complex objects, and it will generate a URL, so the property HttpMethod = "POST" will be useless. I Saved my answer too fast, I didn't give enough details. – Giu Sep 09 '14 at 11:29
  • The Ajax.ActionLink will generate a partialView, I just want to pass-on a variable to a method in my controller, which passes that variable on to a method in my model, which then returns a list of Model to my controller and then redirects that result to a partial view. Just to clarify: view (with data) > controller (data) > model (data) > controller (data) > partial view. Edit: no problem with saving your answer too fast ;-) – DaGrooveNL Sep 09 '14 at 11:31
  • I don't think that the "GET" limitation is being hit, since I can pass on a string variable with "test" in it if I declare it in the Ajax.ActionLink. But somehow the list of model on the current viewpage just becomes 0. – DaGrooveNL Sep 09 '14 at 11:34
  • ok, the best is to see what is generated using @Ajax.ActionLink – Giu Sep 09 '14 at 11:37
  • The "GET" request gives the following querystring (which looks alright to me, except for the fact that there is no data in it): cbmsModel=System.Collections.Generic.List`1[databaseModel.cbms] X-Requested-With=XMLHttpRequest – DaGrooveNL Sep 09 '14 at 11:44
  • The issue is in your querystring: you don't provide information, mapping cannot be done, please try using a post request with a body with your object inside otherwise the MVC mapping will not work – Giu Sep 09 '14 at 13:02
  • I tried a lot of different options, none of them work. The problem is that Ajax cannot send a list with variables in it through a link. All other variables work (even string arrays), but Lists with objects in them (in this case models) will not work. I don't know if this is a bug or intended. I solved the issue and I will post an answer. – DaGrooveNL Sep 09 '14 at 13:44
0

EDIT: Please see the comment below this answer before you read the answer, since the answer provided here will only work in a specific situation if only 1 user at most will interface with the website.

I solved the issue the following way. This is a dirty way, but does the trick. It passes the TempData to the controller and you just make a list of the items in the TempData.

View

@model IEnumerable

@{   
    ViewBag.Title = "Cbms Home";

    if (TempData != null)
    {
        TempData.Clear();
    }
    int i = 0;
    foreach (databaseModel.cbms value in Model.ToList())
    {
        i++;
        TempData.Add(i.ToString(), value);
    }    
}

Controller

public PartialViewResult AJX_SortByProductId()
    {            
        //Retrieves the data
        List<object> viewDataList = TempData.Values.ToList();
        TempData.Clear();
        List<cbms> dataList = new List<cbms>();
        if (viewDataList != null)
        {
            foreach (cbms cbmsEntry in viewDataList)
            {
                dataList.Add(cbmsEntry);
            }
        }
        List<cbms> model = cbms.SortByProductId(dataList);

        //Returns the partial view
        return PartialView("_Cbms", model);
    }
DaGrooveNL
  • 177
  • 1
  • 1
  • 10
  • I found out that, if you use this answer and you browse to the site via multiple ways, that the cache gets refreshed every time, which is of course, not the way it should work, especially when you need multiple users to interface with the website. I tried a check on the SessionID before clearing the cache (so check if that SessionId has already been added), but on the same computer this gives the same issue. And so, does not solve it. So the issue has not been resolved - yet... – DaGrooveNL Sep 10 '14 at 06:21
  • Actually, browsing to the site via a different browser does not create an issue if you use SessionID as the Identifier... Still testing... – DaGrooveNL Sep 10 '14 at 07:31