Asp.net-mvc – pass model from view to controller with html.actionlink

asp.net-mvcasp.net-mvc-3asp.net-mvc-4razor

I am trying to get the model data from a strongly typed view to a controller.
Using the submit button is ok, I can get the data. Now I want to achieve the same with html.actionlink.
This is what I have:
View:

@model WordAutomation.Models.Document    
    @{
        ViewBag.Title = "Document";
    }
      <script type="text/javascript">
          $(function () {
              $("#dialog").dialog();
          });
        </script>

    <h2>Document</h2>

    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)

        <fieldset>
            <legend>Document</legend>

            <div class="editor-label">
                @Html.LabelFor(model => model.ClientTitle)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ClientTitle)
                @Html.ValidationMessageFor(model => model.ClientTitle)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.ClientFullName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ClientFullName)
                @Html.ValidationMessageFor(model => model.ClientFullName)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.ClientCustomSSN)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ClientCustomSSN)
                @Html.ValidationMessageFor(model => model.ClientCustomSSN)
            </div>

            <p>
                <input type="submit" value="Create" />            
            </p>
        </fieldset>
    }

    <div>
        @Html.ActionLink("Preview", "PreviewWordDocument", "Home", null, new { id = "previewLink" })    

    </div>

    <div id="dialogcontainer">
        <div id="dialogcontent"><input type="submit" value="Create" />        </div>
    </div>

    @section Scripts {

        <script type="text/javascript">

                $(document).ready(function() {

                    $("#dialogcontainer").dialog({
                        width: 400,
                        autoOpen:false,
                        resizable: false,
                        title: 'Test dialog',
                        open: function (event, ui) {
                            $("#dialogcontent").load("@Url.Action("PreviewWordDocument", "Home")");
                        },
                        buttons: {
                            "Close": function () {
                                $(this).dialog("close");
                            }
                        }
                    });

                    $("#previewLink").click(function(e) {
                        e.preventDefault();
                        $("#dialogcontainer").dialog('open');
                    });

                });

            </script>
    }

Controller:

public ActionResult Document()
        {      
            return View();
        }

        [HttpPost]
        public ActionResult Document(WordAutomation.Models.Document model)
        {
            Models.Utility.EditWord word = new Models.Utility.EditWord();
            word.EditWordDoc(model);
            return View("Display", model);
        }

        public ActionResult PreviewWordDocument()
        {           
            var image = Url.Content("~/Content/preview.jpeg");

            return PartialView((object)image);
        } 

The document actionresult can get the model, but I want to know how can I get the values from the actionlink which will trigger the PreviewWordDocument action.

Thanks in advance, Laziale

Best Answer

The form can only be posted using the submit button to the URL given by its action attribute.

You can however send the form data to a different URL using the jQuery post method, manually validating the form before it is sent. That way you can send the form data to the PreviewWordDocument controller method and handle the response in order to show the preview in the desired div. (It will be helpful if you give an id to the form, so you can easily find it using jQuery)

So your click event handler for the preview link will look like this:

$("#previewLink").click(function(e) {
    e.preventDefault();
    if($("#YourFormId").valid()){
        $("#dialogcontainer").dialog('open');
    }
});

In the open function of the dialog you will post the form (which was already validated) to the preview controller method, using the jQuery ajax function. The response will be loaded into the dialogContent div:

    $.ajax({
        type: "POST",
        url: $("#previewLink").attr("href"), //the preview controller method
        data: $("#YourFormId").serialize(), 
        success: function (data) {
            //load ajax response into the dialogContent div
            $("#dialogcontent").html(data);
        },
        error: function(xhr, error) {
            $("#YourFormId").prepend('<div id="ajaxErrors"></div>')
                            .html(xhr.responseText);
        }
    });

Now you will now be able to receive the whole document in the PreviewWordDocument action:

public ActionResult PreviewWordDocument(WordAutomation.Models.Document model)
{           
    var image = Url.Content("~/Content/preview.jpeg");

    return PartialView((object)image);
}