IE 中的 JSON 安全警告,尝试在 MVC3 应用程序中下载



在我研究同一问题的过程中,我在SO上看到了很多问题,但其中任何一个的答案都没有帮助我。

我已经尝试了每个答案解决方案,但没有一个奏效。

因此,我将逐段列出代码,以及我尝试过的内容和位置。

首先,我的观点..由2个形式和一个部分视图组成,这里的主要观点是:

@using MyApplication.Select.Web.Helpers; 
@model SearchUsersViewModel
@*Scripts*@
<script src="@Url.Content("~/Scripts/SearchEntity.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ManageUsers.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/FormValidation.js")" type="text/javascript"></script>
<script type="text/javascript">
    var theme = "admin"; //(lender, school, admin, or public)
    var cssArray = ["ManageUsers.css", "ActionIcons.css"];
    //Invoke loadCSS Method from CSSLoader.js
    loadCSS(theme, cssArray);
    //Set active tab from NavigationAdmin.js
    setActiveNavTab("tab01"); //(tab01, tab02, tab03, tab04, tab05, tab06)
    document.getElementById("AdminPageHeaderIMG").className = "HeaderImageManageUsers";
</script>
<div>
    <table id="" cellpadding="0" cellspacing="0" border="0">
        <tr style="height: 60px;">
            <td>
                <div class="PageHeaderDescriptionDiv">
                    Welcome to My Application
                </div>
            </td>
        </tr>
        <tr style="height: 1px;">
            <td class="ContentDividerHoriz"></td>
        </tr>
    </table>
    <table class="SearchUsersMainTable" cellpadding="0" cellspacing="0" border="0">
        <tr>
            <td>
                <table cellpadding="0" cellspacing="0" border="0">
                    <tbody>
                        <tr>
                            <td>
                                <div class="SearchByUserDataTable">
                                    @using (Html.BeginForm()) {
                                        @Html.HiddenFor(model => model.SearchFilterType)
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 30px;">
                                                <td class="Header01">
                                                    User Search
                                                </td>
                                            </tr>
                                        </table>
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 20px;">
                                                <td class="Header02">
                                                    Search By User Information
                                                </td>
                                            </tr>
                                        </table>
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 1px;">
                                                <td class="ContentDividerHoriz_425"></td>
                                            </tr>
                                        </table>
                                        <table id="searchByUserDataTable" cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 26px;">
                                                <td class="leftColumn">
                                                    @Html.LabelFor(model => model.LastName)
                                                </td>
                                                <td class="rightColumn">
                                                    @Html.TextBoxFor(model => model.LastName, new { @class = "TextField_220" })
                                                </td>
                                            </tr>
                                            <tr style="height: 26px;">
                                                <td class="leftColumn">
                                                    @Html.LabelFor(model => model.Username)
                                                </td>
                                                <td class="rightColumn">
                                                    @Html.TextBoxFor(model => model.Username, new { @class = "TextField_220" })
                                                </td>
                                            </tr>
                                            <tr style="height: 26px;">
                                                <td class="leftColumn">
                                                    @Html.LabelFor(model => model.EmailAddress)
                                                </td>
                                                <td class="rightColumn">
                                                    @Html.TextBoxFor(model => model.EmailAddress, new { @class = "TextField_220" })
                                                </td>
                                            </tr>
                                        </table>
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr>
                                                <td id="filterByUserError" style="width: 300px; color: #ff0000;"></td>
                                                <td align="right" style="width: 50px;">
                                                    <div>
                                                        <input id="filterByUserButton" type="submit" value="Search" />
                                                    </div>
                                                </td>
                                                <td style="width: 75px;"></td>
                                            </tr>
                                        </table>
                                    }
                                </div>
                            </td>
                            <td style="width: 20px;"></td>
                            <td>   
                                <div class="SearchByEntityDataTable">
                                    @using (Html.BeginForm()) { 
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 28px;">
                                                <td style="width: 425px;"></td>
                                            </tr>
                                        </table>
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 20px;">
                                                <td class="Header02">
                                                    Search By Entity Information
                                                </td>
                                            </tr>
                                        </table>
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 1px;">
                                                <td class="ContentDividerHoriz_425"></td>
                                            </tr>
                                        </table>
                                        <table id="searchByEntityDataTable" cellpadding="0" cellspacing="0" border="0">
                                            <tr style="height: 26px;">
                                                <td class="leftColumn">
                                                    @Html.LabelFor(model => model.EntityTypeID)
                                                </td>
                                                <td class="rightColumn">
                                                    @Html.DropDownListFor(model => model.EntityTypeID, new SelectList(Model.EntityTypes, "ID", "Name"), new { id = "entityTypeDropDown", @class = "DropDown_220" })
                                                </td>
                                            </tr>
                                            <tr style="height: 26px;">
                                                <td class="leftColumn">
                                                    @Html.LabelFor(model => model.SearchField, new { id = "entityTypeSearchLabel"})
                                                </td>
                                                <td class="rightColumn">
                                                    @Html.TextBoxFor(model => model.SearchField, new { id = "entityTypeSearchField", @class = "ui-widget TextField_220" })
                                                </td>
                                            </tr>
                                            <tr style="height: 26px;">
                                                <td class="leftColumn"></td>
                                                <td class="rightColumn"></td>
                                            </tr>
                                        </table>
                                        <table cellpadding="0" cellspacing="0" border="0">
                                            <tr>
                                                <td id="filterByEntityError" style="width: 300px; color: #ff0000;"></td>
                                                <td align="right" style="width: 50px;">
                                                    <div>
                                                        <input id="filterByEntityButton" type="submit" value="Search" />
                                                    </div>
                                                </td>
                                                <td style="width: 75px;"></td>
                                            </tr>
                                        </table>
                                    }
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <table cellpadding="0" cellspacing="0" border="0">
                    <tr style="height: 1px;">
                        <td class="ContentDividerHoriz"></td>
                    </tr>
                </table>
                <table cellpadding="0" cellspacing="0" border="0">
                    <tr style="height: 33px;">
                        <td style="width: 870px;">
                            <div class="TelerikGridHeaderBkgd">
                                <table cellpadding="0" cellspacing="0" border="0">
                                    <tr>
                                        <td class="Header01" style="width: 150px; padding: 0px 0px 4px 5px;">
                                            User Search Results
                                        </td>
                                        <td style="width: 10px;"></td>
                                        <td style="width: 710px;">
                                            <table cellpadding="0" cellspacing="0" border="0">
                                                <tr style="height: 4px;">
                                                    <td style="width: 710px;"></td>
                                                </tr>
                                            </table>
                                            <table>
                                                <tr style="height: 20px;">
                                                    <td style="width: 188px;">
                                                        @*Resend Invitation*@
                                                        <table cellpadding="0" cellspacing="0" border="0">
                                                            <tr>
                                                                <td class="ActionIcon_ResendInvitationOn"></td>
                                                                <td style="padding-left: 5px; padding-right: 10px;">
                                                                    <span class="SearchUsersLegendText">= Resend Invitation</span> 
                                                                </td>
                                                            </tr>
                                                        </table>
                                                    </td>
                                                    <td style="width: 140px;">
                                                        @*Account Approved Status*@
                                                        <table width="140" cellpadding="0" cellspacing="0" border="0">
                                                            <tr>
                                                                <td class="ActionIcon_AccountStatusLegend"></td>
                                                                <td style="padding-left: 5px; padding-right: 10px;">
                                                                    <div class="SearchUsersLegendText">
                                                                        <span>= </span> 
                                                                        <span style="color: #839f1b;">Active</span>
                                                                        <span> / </span>
                                                                        <span style="color: #d6161f;">Inactive</span>
                                                                    </div>
                                                                </td>
                                                            </tr>
                                                        </table>
                                                    </td>
                                                    <td style="width: 162px;">
                                                        @*Account Lock Status*@
                                                        <table cellpadding="0" cellspacing="0" border="0">
                                                            <tr>
                                                                <td class="ActionIcon_UnlockAccountOn"></td>
                                                                <td style="padding-left: 5px; padding-right: 10px;">
                                                                    <span class="SearchUsersLegendText">= Unlock Account</span> 
                                                                </td>
                                                            </tr>
                                                        </table>
                                                    </td>
                                                    <td style="width: 170px;">
                                                        @*Reset Password*@
                                                        <table cellpadding="0" cellspacing="0" border="0">
                                                            <tr>
                                                                <td class="ActionIcon_ResetPasswordOn"></td>
                                                                <td style="padding-left: 5px; padding-right: 10px;">
                                                                    <span class="SearchUsersLegendText">= Reset Password</span> 
                                                                </td>
                                                            </tr>
                                                        </table>
                                                    </td>
                                                    <td style="width: 145px;">
                                                        @*Edit Account*@
                                                        <table cellpadding="0" cellspacing="0" border="0">
                                                            <tr>
                                                                <td class="ActionIcon_EditOn"></td>
                                                                <td style="padding-left: 5px; padding-right: 10px;">
                                                                    <span class="SearchUsersLegendText">= Edit Account</span> 
                                                                </td>
                                                            </tr>
                                                        </table>
                                                    </td>
                                                </tr>
                                            </table>
                                            <table>
                                                <tr style="height: 6px;">
                                                    <td style="width: 710px;"></td>
                                                </tr>
                                            </table>
                                        </td>
                                    </tr>
                                </table>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td style="width: 870px;">
                            <div id="searchResults">
                                @Html.Partial("SearchResultsPartial", Model)
                            </div>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</div>

SearchResultsPartial 在这里:

@model SearchUsersViewModel
@*Scripts*@
<link href="@Url.Content("~/Content/styles/TelerikCustom.css")" rel="stylesheet" type="text/css" />
@(Html.Telerik().Grid(Model.Users)
    .Name("Users").TableHtmlAttributes(new { style = "width: 870px;"})
    .Columns(columns => {
        columns.Bound(o => o.EntityTypeName).Title("Entity Type");
        columns.Bound(o => o.FirstName).Title("First Name");
        columns.Bound(o => o.LastName).Title("Last Name");
        columns.Bound(o => o.Username).Title("Username");
        columns.Template(
            @<text>
                <a href="mailto:@item.EmailAddress" target="blank">@item.EmailAddress</a>
            </text>).Title("Email").HtmlAttributes(new { style = "text-align: center" }).HeaderHtmlAttributes(new { style = "text-align: center" });
        columns.Template(
            @<text>
                 @{ if (@item.MembershipID == 0) {
                        <div class="ActionIcon_ResendInvitationOn" title="Resend Invitation" onclick="resendInvitation(@item.EntityID, @item.EntityTypeID, '@item.EmailAddress')"></div>
                    }
                    else {
                        if ((bool) item.IsApproved) {
                            <div class="ActionIcon_AccountStatusOn" title="Disable Account" onclick="setApprovalStatus('@item.Username', false)"></div>
                        }
                        else {
                            <div class="ActionIcon_AccountStatusOff" title="Enable Account" onclick="setApprovalStatus('@item.Username', true)"></div>
                        }
                        if ((bool) item.IsLockedOut) {
                            <div class="ActionIcon_UnlockAccountOn" title="Unlock Account" onclick="unlockAccount('@item.Username')"></div>
                        }
                        else {
                            <div class="ActionIcon_ResetPasswordOn" title="Reset Password" onclick="resetPassword('@item.Username')"></div>
                        }
                        <div class="ActionIcon_EditOn" title="Edit User" onclick="location.href='@Url.Action("Edit", "Admin", new { id = item.MembershipID, username = item.Username })'"></div>
                    }
                 }
            </text>).Title("Actions");
        columns.Bound(o => o.RowNumber).Hidden(true);
        columns.Bound(o => o.MembershipID).Hidden(true);
        columns.Bound(o => o.EntityID).Hidden(true);
        columns.Bound(o => o.EntityTypeID).Hidden(true);
    })
)
<div>
     Total Rows:
    @{
        if (!@Model.Users.Any()) {
            @Html.Label("0")
        }
        else {
            @Model.Users.First().TotalRows
        } 
    }
</div>

任何一种形式都可以进行搜索,这是相互排斥的搜索。按用户数据搜索或按实体数据搜索,但不能同时搜索两者。每个表单上的提交按钮都会触发自己的 javascript,该脚本运行 ajax 调用:

function filterByUserSearch() {
    var lastName = document.getElementById("LastName");
    var username = document.getElementById("Username");
    var emailAddress = document.getElementById("EmailAddress");
    var entityTypeID = document.getElementById("entityTypeDropDown");
    var entityName = document.getElementById("entityTypeSearchField");
    var searchFilterType = document.getElementById("SearchFilterType");
    //alert("User Search");
    entityTypeID.value = 0;
    entityName.value = "";
    searchFilterType.value = 0;
    $.ajax({
        url: "/Admin/Search/",
        dataType: "json",
        cache: false,
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: { LastName: lastName.value, Username: username.value, EmailAddress: emailAddress.value, SearchFilterType: searchFilterType.value },
        success: function (result) {
            $('#resultSpan').html('');
            if(result.Success) {
                $('#searchResults').html(result.Data);
                if (result.ResultMessage != '<li></li>') {
                    $('#resultSpan').append($("<ul id='successMsg' style='list-style: none;' />").append(result.ResultMessage)).addClass("AjaxSuccessText");
                    $('#successMsg').css("padding-left", "0");
                    showResultPopUpDiv("ajaxResultWrapperDiv", "Action was Successful!");
                }
            }
            else {
                $('#resultSpan').append($("<ul id='errorMsg' style='list-style: none;' />").append(result.ResultMessage)).addClass("AjaxErrorText");
                $('#errorMsg').css("padding-left", "0");
                showResultPopUpDiv("ajaxResultWrapperDiv", "Ooops! There was an Error");
            }
        }
    });
    return false;
}

调用的控制器操作如下所示:

[HttpPost]
public JsonResult Search(SearchUsersViewModel model) {
    try {
        if (model.SearchFilterType == SearchFilterType.ByUserData)
            return SearchForUsersByUserData(model, string.Empty);
        if (model.SearchFilterType == SearchFilterType.ByEntityData)
            return SearchForUsersByEntityData(model, string.Empty);
    }
    catch (Exception ex) {
        ModelState.AddModelError("", ModelStateErrorUtility.WrapResultMessageForList(ex.Message));   
    }
    return Json(new { Success = false, ResultMessage = ModelStateErrorUtility.GetModelStateErrors(ModelState) }, "application/json", JsonRequestBehavior.AllowGet);
}
private JsonResult SearchForUsersByUserData(SearchUsersViewModel model, string resultMessage) {
    if (model.LastName != null || model.Username != null || model.EmailAddress != null) {
        var listOfMatchingUsers = SearchUserService.SearchByUserData(model.LastName, model.Username, model.EmailAddress);
        return PrepareSearchResultsForPartialView(model, listOfMatchingUsers, resultMessage);
    }
    throw new ArgumentNullException("Last Name, Username or Email Address must be entered for search");
}
private JsonResult SearchForUsersByEntityData(SearchUsersViewModel model, string resultMessage) {
    if ((model.EntityTypeID == 1) || (model.EntityTypeID > 0 && model.SearchField != null)) {
        var listOfMatchingUsers = SearchUserService.SearchByEntityData(model.EntityTypeID, model.SearchField);
        return PrepareSearchResultsForPartialView(model, listOfMatchingUsers, resultMessage);
    }
    throw new ArgumentNullException("Entity Type must be entered for search");
}
private JsonResult PrepareSearchResultsForPartialView(SearchUsersViewModel model, ICollection<SearchUserResultsDTO> list, string resultMessage) {
    return Json(new { Success = true, ResultMessage = ModelStateErrorUtility.WrapResultMessageForList(resultMessage), Data = RenderRazorViewToString("SearchResultsPartial", PrepareSearchResultsForModel(list, model)) }, "application/json", JsonRequestBehavior.AllowGet);
}
private static SearchUsersViewModel PrepareSearchResultsForModel(ICollection<SearchUserResultsDTO> listOfMatchingUsers, SearchUsersViewModel model) {
    if (listOfMatchingUsers.Count != 0) {
        model.Users = listOfMatchingUsers.Select(item => new UserEditViewModel(item)).ToList();
    }
    return model;
}
private string RenderRazorViewToString(string viewName, object model) {
    ViewData.Model = model;
    using (var sw = new StringWriter()) {
        var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);
        viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
        return sw.GetStringBuilder().ToString();
    }
}

我尝试过:

操作

方法返回设置为 JsonResult

响应中未指定内容类型,ajax 调用内容类型:application/json;charset=utf-8

  1. IE 8 指向暂存服务器 IIS 提示下载文件
  2. 指向暂存服务器 IIS 的 IE 9 什么都不做
  3. 指向暂存服务器 IIS 的 Chrome 什么都不做
  4. 指向本地网络服务器的Chrome根本不做
  5. 任何事情

application/json;charset=utf-8 在响应中指定,ajax 调用时没有内容类型

  1. IE 8 指向暂存服务器 IIS 提示下载文件
  2. IE 9指向暂存服务器IIS工作完美
  3. Chrome指向暂存服务器IIS工作完美
  4. 指向本地网络服务器的Chrome完美运行

在这一点上,我有 3 种方式中的 4 种工作得很好,IE 8 很糟糕。所以现在我更改操作方法结果。

操作

方法返回时设置为操作结果

响应中未指定内容类型,ajax 调用内容类型:application/json;charset=utf-8

  1. IE 8 指向暂存服务器 IIS 提示下载文件
  2. 指向暂存服务器 IIS 的 IE 9 什么都不做
  3. 指向暂存服务器 IIS 的 Chrome 什么都不做
  4. 指向本地网络服务器的Chrome根本不做
  5. 任何事情

此时,我认为在 ajax 调用本身中指定 contentType 是不好的。

application/json;charset=utf-8 在响应中指定,ajax 调用时没有内容类型

  1. IE 8 指向暂存服务器 IIS 提示下载文件
  2. IE 9指向暂存服务器IIS工作完美
  3. Chrome指向暂存服务器IIS工作完美
  4. 指向本地网络服务器的Chrome完美运行

我什至将脚本文件 JSON2.js 添加到项目中并在视图中引用了该脚本,这根本没有做任何事情。

这是疯狂的部分,我以相同的方式设置了另一个控制器,它构建的 json 完全相同,唯一的区别是调用 ajax 的视图略有不同。这是 Ajax 方法:

function setApprovalStatus(username, isApproved) {
    $.ajax({
        url: "/ELMAdmin/SetApprovalStatus/",
        dataType: "json",
        cache: false,
        type: 'POST',
        data: { username: username, isApproved: isApproved },
        success: function (result) {
            showManageUsersSuccessError(result);
        }
    });
}

它调用相同的子例程来呈现网格,唯一的区别是返回的数据。 所以我从部分视图中剥离了所有文本,IE 仍然尝试下载该文件。我觉得我已经尝试了我所知道的一切,现在需要一些额外的眼睛来帮助指出我希望是显而易见的东西。

好的,在查看示例并对其进行测试后,您需要将此内容类型添加到 ajax 调用中。

$.ajax({
    url: "/ELMAdmin/Search",
    cache: false,
    type: 'POST',
    contentType: "application/x-www-form-urlencoded;charset=utf-8",
    data: { LastName: lastName.value, Username: username.value, EmailAddress: emailAddress.value, SearchFilterType: searchFilterType.value },
    success: function (result) {
        showManageUsersSuccessError(result);
    }
});

请注意,contentType application/x-www-form-urlencoded;charset=utf-8。这应该可以解决 IE8 的任何问题。

此外,虽然它可能只是示例,但您需要在搜索按钮上的 onclick 方法中return false,否则它将返回 true,然后执行第二篇文章。

//Search By User Info
searchByUserBtn.onclick = function (event) {
    entityName.className = "FieldOk";
    entityName.value = "";
    entityName.setAttribute("disabled", "disabled");
    entityTypeID.value = 0;
    entityTypeID.className = "FieldOk";
    entityErrorMsgField.innerHTML = "";
    filterByUserValidation();
    return false;
}

尽管这个问题很旧,但我想我会再添加一个建议,以防万一其他人正在使用ASP.NET MVC 3 or 4并遇到这个问题。

根据我的经验,当IE尝试将Json响应下载为文件时,要纠正问题所要做的就是在视图中添加对jquery.unobtrusive的引用。

例如:

@Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")

一旦完成此操作,IE 将不再尝试从 JsonResult 控制器操作下载 json 响应。 无需更改响应类型等。

最新更新