FlyFish
FlyFish

Reputation: 547

TempData Dropping Data

I'm trying to persist a TempData value on a return PartialView(). It works correctly in one Post but not another and I'm stymied.

In the following action it works correctly and the value gets passed, via javascript redirect to the action that is using the value:

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult DeletetheFile(int attachmentid, string issueId)
{          

    string response = _adoSqlService.DeleteAttachment(attachmentid);
    TempData["ID"]= issueId;
    TempData.Keep();
     return PartialView("_DeleteFile");

}

In the following action it is getting set properly (see the first image), but by the time it gets to the same action as the first one I showed it has changed (see second image).

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult EditFile(IFormCollection collection)
{
    AttachmentModel model = new AttachmentModel();

    model.attachmentId = Convert.ToInt32(collection["attachmentId"]);
    model.aIssueAttachmentDescription = collection["aIssueAttachmentDescription"];
    string response = _adoSqlService.EditFileDescription(model);
    TempData.Remove("ID");
    TempData["ID"] = collection["issueId"];
    TempData.Keep();
    return PartialView("_EditFile");
 }

Setting TempData Reading TempData

When it gets to the where I need it is now returning [string1] instead of the 20-003.

Both of the above actions run against a partial view in a modal pop-up. The following javascript captures the modal action and redirects the results to the Issue/Edit controller/action.

$('body').on('click', '.relative', function (e) {
        e.preventDefault();
        var form = $(this).parents('.modal').find('form');
        var actionUrl = form.attr('action');
        var dataToSend = form.serialize();
        $.post(actionUrl, dataToSend).done(function (data) {
            $('body').find('.modal-content').html(data);
            var isValid = $('body').find('[name="IsValid"]').val() == 'True';
            if (isValid) {
                $('body').find('#modal-container').modal('hide');
                window.location.href = "/Issue/Edit";
            }

        });
    })

The redirection seems to happen since the edit action is being called in both cases. It's just that in the second case it is not getting the correct value of the TempData value. Here is the start of the Edit action which resides in a different controller than the 2 actions above:

public ActionResult Edit(string id)
{
    if (id == null)
    {
        id = TempData["ID"].ToString();                
    }

----------More Comments So after working on this for the past 4 hrs I've come up with a work-around. I'm not sure this is the correct technique or not. What I ended up doing was adding a hidden input field on the partial views and then parsing the ajax response for that value.

var issueid = $(response).find('[name="issueidSaved"]').val();
window.location.href = "/Issue/Edit/?id=" + issueid

My concern now is that the issueid is now included in the query string and is visible in the URL.

Is this the correct method or should I go back to using TempData and trying to get that to work?

UPDATE Hopefully I can explain this better. The goal is to get a TempData value into the following action in my Issues Controller which is tied to my Edit Page (Issues/Edit):

public ActionResult Edit(string id)
{
    if (id == null)
    {
        id = TempData["ID"].ToString();                
    }

I have a modal on my Edit page that is populated with different partial views depending upon what is populating it. The partial views use the Attachment controller, while the Edit view uses the Issues Controller. I use Javascript/ajax to capture the submit from the partial views to close the modal and redirect to the Edit view so a refresh of the data affected by the partial views is reflected on the Edit view. The TempData value is working correctly when I submit the _DeleteFile, but not when I submit the _EditFile partial views in the modal.

Here is the common Javascript/ajax on the Edit view:

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script>
        //Using this to scroll the page on the close of the modal/page refresh
         $(document).ready(function () {
            var JumpTo = '@ViewBag.JumpToDivId';
            if (JumpTo != "") {
                $(this).scrollTop($('#' + JumpTo).position().top);
            }
        });
        //Using this to Capture the click that opens the modals
        $('body').on('click', '.modal-link', function () {
            var actionUrl = $(this).attr('href');
            $.get(actionUrl).done(function (data) {
                $('body').find('.modal-content').html(data);
            });
            $(this).attr('data-target', '#modal-container');
            $(this).attr('data-toggle', 'modal');
        });
        //Using this to Capture the click that Submits the _EditFile,_DeleteFile,_CreateEdit forms on the modal
        $('body').on('click', '.relative', function (e) {
            e.preventDefault();
            var form = $(this).parents('.modal').find('form');
            var actionUrl = form.attr('action');
            var dataToSend = form.serialize();
            $.post(actionUrl, dataToSend).done(function (data) {
                $('body').find('.modal-content').html(data);
                var isValid = $('body').find('[name="IsValid"]').val() == 'True';
                var issueid = "";
                issueid = $('body').find('[name="issueidSaved"]').val();
                var jumpto = $('body').find('[name="jumpto"]').val();
                if (isValid) {
                    $('body').find('#modal-container').modal('hide');
                    if (issueid == "")
                    {
                        window.location.href = "/Issue/Edit/?id=" + issueid + "&jumpto=" + jumpto;
                    }
                }
            });
        })
        //Using this to Capture the click that Submits the _UploadFile form on the modal
        $(function () {
            $('body').on('click', '.fileupload', function (e) {
                e.preventDefault();
                var form = $(this).parents('.modal').find('form');
                var actionUrl = form.attr('action');

                var fdata = new FormData();
                $('input[name="file"]').each(function (a, b) {
                    var fileInput = $('input[name="file"]')[a];
                    if (fileInput.files.length > 0) {
                        var file = fileInput.files[0];
                        fdata.append("file", file);
                    }
                });
                $("form input[type='text']").each(function (x, y) {
                    fdata.append($(y).attr("name"), $(y).val());
                });
                $("form input[type='hidden']").each(function (x, y) {
                    fdata.append($(y).attr("name"), $(y).val());
                });
                $.ajax({
                    url: actionUrl,
                    method: "POST",
                    contentType: false,
                    processData: false,
                    data: fdata
                }).done((response, textStatus, xhr) => {
                    var isValid = $(response).find('[name="IsValid"]').val() == 'True';
                    var issueid = $(response).find('[name="issueidSaved"]').val();
                    var jumpto = $(response).find('[name="jumpto"]').val();
                    if (isValid) {
                        $('body').find('#modal-container').modal('hide');
                        window.location.href = "/Issue/Edit/?id=" + issueid + "&jumpto="+jumpto;
                    }
                   });
            })
        });

        $('body').on('click', '.close', function () {
            $('body').find('#modal-container').modal('hide');
        });

        $('#CancelModal').on('click', function () {
            return false;
        });

        $("form").submit(function () {
            if ($('form').valid()) {
                $("input").removeAttr("disabled");
            }
        });
    </script>

Here is the _DeleteFile Partial view and the AttachmentController code that handles the submit:

<!--Modal Body Start-->

<div class="modal-content">
    <input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />
    <input name="issueidSaved" type="hidden" value="@ViewBag.ID" />
    <input name="jumpto" type="hidden" value="@ViewBag.JumpToDivId" />
    <!--Modal Header Start-->
    <div class="modal-header">
        <h4 class="modal-title">Delete File</h4>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <!--Modal Header End-->

    <form asp-action="DeletetheFile" asp-route-attachmentid="@ViewBag.id" asp-route-issueId="@ViewBag.issueId" asp-controller="Attachment" method="post" enctype="multipart/form-data">

        @Html.AntiForgeryToken()

        <div class="modal-body form-horizontal">
            Are you sure you want to delete the @ViewBag.title File?

            <!--Modal Footer Start-->
            <div class="modal-footer">
                <button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">No</button>
                <input type="submit" class="btn btn-success relative" id="btnSubmit" data-save="modal" value="Yes">
            </div>
            <div class="row">
                &nbsp;
            </div>

        </div> <!--Modal Footer End-->
    </form>

</div>
<script type="text/javascript">
    $(function () {

    });
</script>

<!--Modal Body End--> 

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult DeletetheFile(int attachmentid, string issueId)
{
    string response = _adoSqlService.DeleteAttachment(attachmentid);
    ViewBag.ID = issueId;
    ViewBag.JumpToDivId = "upload";
    TempData["ID"]= issueId;
    TempData.Keep();
    return PartialView("_DeleteFile");
}

Here is the _EditFile partial view and the AttachmentController code: Edit File ×

    <form asp-action="EditFile" asp-controller="Attachment" method="post" enctype="multipart/form-data">

        @Html.AntiForgeryToken()

        <div class="modal-body form-horizontal">
            <input name="issueId" type="hidden" value="@ViewBag.issueId" />
            <input name="attachmentId" type="hidden" value="@ViewBag.attachmentId" />
            <label class="control-label">@ViewBag.aFileName</label><br />
            Make changes to description then select "Save Changes".<br />
            <input name="aIssueAttachmentDescription" class="form-control formtableborders" id="titletext" value="@ViewBag.aIssueAttachmentDescription" />

            <!--Modal Footer Start-->
            <div class="modal-footer">
                <button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">No</button>
                <input type="submit" class="btn btn-success relative" id="btnSubmit" data-save="modal" value="Save Changes">
            </div>
            <div class="row">
                &nbsp;
            </div>

        </div> <!--Modal Footer End-->
    </form>

</div>
<script type="text/javascript">
    $(function () {

    });
</script>

<!--Modal Body End-->  

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult EditFile(IFormCollection collection)
{
    AttachmentModel model = new AttachmentModel();

    model.attachmentId = Convert.ToInt32(collection["attachmentId"]);
    model.aIssueAttachmentDescription = collection["aIssueAttachmentDescription"];
    string response = _adoSqlService.EditFileDescription(model);
    ViewBag.ID = collection["issueId"];
    ViewBag.JumpToDivId = "upload";
    TempData.Remove("ID");
    TempData["ID"] = collection["issueId"];
    TempData.Keep();
    return PartialView("_EditFile");
}

When I inspect the TempData at the Issue/Edit action after the _DeleteFile submit it displays the following (which is correct):

Setting TempData

When I inspect the TempData at the Issue/Edit action after the _EditFile submit it displays the following (which is incorrect):

Reading TempData

Upvotes: 0

Views: 285

Answers (1)

Yiyi You
Yiyi You

Reputation: 18159

You need to change

TempData["ID"] = collection["issueId"];

to

TempData["ID"] = collection["issueId"].ToString();

Because collection["issueId"] is Type Microsoft.Extensions.Primitives.StringValues rathar than Type String.

Here is a picture to show the Type: enter image description here

Upvotes: 2

Related Questions