user547794
user547794

Reputation: 14511

Ajax.ActionLink post entire model from a view?

I have a view that is strongly typed to a ViewModel. Is it possible to pass all of the data from a model in the view, back to a controller action? Something like this?

@Ajax.ActionLink("(Export to Excel)", "ExportCsv", "SurveyResponse", new {  
ResultsViewModel = Model }, new AjaxOptions {HttpMethod = "POST"})

And then collect the data from ResultsViewModel as a parameter in another controller

public ActionResult ExportCsv(ResultsViewModel resultsviewmodel)
{

}

Upvotes: 7

Views: 18681

Answers (4)

Rm558
Rm558

Reputation: 4992

Managed to make below works,

@Ajax.ActionLink("(Export to Excel)", "ExportCsv", "SurveyResponse", 
new { Model.F1, Model.F2, Model.OtherFields }, new AjaxOptions {HttpMethod = "POST"})

Controller

[HttpPost]
public ActionResult ExportCsv(ResultsViewModel resultsviewmodel)
{

}

This is a http post, but the data in not in "form data", it's encoded in request's URL (but not a http get).

Looks like MVC automatically converts the individual fields into a single model.

URL has a length limits, large model may fail.

Upvotes: 2

Zapnologica
Zapnologica

Reputation: 22556

I did the following. It kind of defeats the point of HTTP POST in my oppionion. But hey it gets the job done.

My Ajax:

@Ajax.ActionLink("Delete", "RemoveSubjectFromCategory","Categories", new { SubjectId = item.Id, CategoryId = Model.Id }, new AjaxOptions {HttpMethod = "GET"})

My Controller:

[HttpGet]
public async Task<ActionResult> RemoveSubjectFromCategory(RemoveSubjectFromCategoryModel model)
{}

My Binding Model:

public class RemoveSubjectFromCategoryModel
{
    [Required]
    public int SubjectId { get; set; }

    [Required]
    public int CategoryId { get; set; }
}

Upvotes: 0

Hamid Reza
Hamid Reza

Reputation: 2973

Try to send your model's Id to the controller and get json result:

@Ajax.ActionLink("(Export to Excel)", "ExportCsv", "SurveyResponse", new {  
id = Model.Id }, new AjaxOptions {HttpMethod = "POST"})

And in controller you will have:

[HttpGet]
public ActionResult ExportCsv(int id)
{
//Here get the whole model from your repository for example:
var model=GetModelByModelId(id);
//And do everything you want with your model.
return Json(model,JsonRequestBehavior.AllowGet);
}

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038810

No, you cannot pass entire view model like this in an action link. You could pass only the id of this model and then retrieve the actual model using this id from wherever you retrieved it initially:

@Ajax.ActionLink(
    "(Export to Excel)", 
    "ExportCsv", 
    "SurveyResponse", 
    new { id = Model.Id }, 
    new AjaxOptions { HttpMethod = "POST" }
)

As an alternative you could serialize the model as a javascript literal and then send it as a JSON data with the AJAX request:

@Html.ActionLink(
    "(Export to Excel)", 
    "ExportCsv", 
    "SurveyResponse", 
    null, 
    new { @class = "exportCsv" }
)
<script type="text/javascript">
    $('.exportCsv').click(function() {
        var model = @Html.Raw(Json.Encode(Model));
        $.ajax({
            url: this.href,
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(model),
            success: function(result) {

            }
        });
        return false;
    });
</script>

Upvotes: 4

Related Questions