【问题标题】:How do I overcome MissingMethodException please. Am running out of ideas请问我该如何克服 MissingMethodException 。我已经没有想法了
【发布时间】:2021-11-10 06:06:51
【问题描述】:

使用 AlanJudenMvcReportViewer 在 .net core 2.1 中开发包含 2 个项目、报告和 Web 的解决方案,该解决方案在大约十几个 SSRS 服务器报告上运行良好。 决定使用 Microsoft.DotNet.UpgradeAssistant 迁移到 net 5.0。除了这个之外,我遇到了许多我已经克服的错误:

现在在 net 5.0 中运行任何报告都会显示“报告加载失败,请检查报告参数”,这实际上是 500 / 内部服务器错误: System.MissingMethodException:找不到方法:'Microsoft.AspNetCore.Mvc.JsonResult Microsoft.AspNetCore.Mvc.Controller.Json(System.Object, Newtonsoft.Json.JsonSerializerSettings)'。

ReportViewer.cshtml/viewReportPage 中出现错误:$.get("/Report/ViewReportPage/?reportPath=@Model.ReportPath.UrlEncode()&page=" + page + "&" + urlParams)

一些研究给了我:https://github.com/alanjuden/MvcReportViewer/issues/92(和其他人):

...有两种解决方案,一种涉及从 Alan 的代码修改 ReportController,另一种涉及包含包引用并修改您的启动以指示 MVC 使用 Newtonsoft JSON。

选项#1:在MvcReportViewer/ReportController/ViewReportPage方法中,完全替换以下代码

new Newtonsoft.Json.JsonSerializerSettings() { ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver() });

与...新的 System.Text.Json.JsonSerializerOptions());

选项 #2:首先在 ItemGroup 中为您的项目添加 .csproj 文件的包引用,其中包含您的其他包引用...

然后,在您的 Startup.cs/ConfigureServices 方法中,指示 MVC 使用 Newtonsoft JSON... services.AddMvc().AddNewtonsoftJson();....

已尝试选项 #2 - 没有变化,同样的错误。 不知道如何应用选项 #1,因为我没有看到要替换的代码(这可能是问题所在)。

已经看到使用早期版本包的问题的参考。据我所知,我已经更新了我的所有内容。

我使用的 ReportController.cs 是:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using SSFA_Web.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;

namespace SSFA_Web.Controllers
{
    [Authorize]
    public class ReportController : AlanJuden.MvcReportViewer.ReportController 
      {
        private readonly SSFA_SQLContext _context;

        public ReportController(SSFA_SQLContext context)
        {
            _context = context;
        }

        protected override ICredentials NetworkCredentials 
        { 
            get 
            {
                return new System.Net.NetworkCredential("Myusername", "Mypassword", "Mydomain"); 
            }
        }

        protected override System.ServiceModel.HttpClientCredentialType ClientCredentialType
        {
            get
            {
                return System.ServiceModel.HttpClientCredentialType.Ntlm;
            }
        }

        protected override string ReportServerUrl
        { 
            get 
            {
                return "http://MyReportServer directory"; 
            } 
        }

        protected override bool UseCustomReportImagePath { get { return true; } }

        protected override string ReportImagePath
        { 
            get 
            { 
                return "/Report/ReportImage/?originalPath={0}";
            } 
        }
                
        
        public ActionResult CalendarListing()
        {
            var model = this.GetReportViewerModel(Request);
            model.ReportPath = "/Reports/CalendarListing";
            
            return View("ReportViewer", model);
        }

    // etc
        
    }
}

ReportViewer.cshtml 是:

@model AlanJuden.MvcReportViewer.ReportViewerModel
@using AlanJuden.MvcReportViewer

@{
    ViewBag.Title = "ReportViewer";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>ReportViewer</h2>

@section AdditionalHeadContent {
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/select2.min.css" />
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/select2-bootstrap.min.css" />
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/mvcreportviewer-bootstrap.css" />
    <style>
        .row {
            margin-left: 0;
            margin-right: 0;
        }
    </style>
    <script src="~/lib/bootstrap/dist/js/select2.min.4.0.3.js"></script>
    <script src="~/lib/jquery/dist/jquery.highlight-5.js"></script>
    <script>
            $(document).ready(function () {
                _initializeReportViewerControls();

                $('.FirstPage, .ViewReport, .Refresh').click(function () {
                    if (!$(this).attr('disabled')) {
                        viewReportPage(1);
                    }
                });

                $('.PreviousPage').click(function () {
                    if (!$(this).attr('disabled')) {
                        var page = parseInt($('#ReportViewerCurrentPage').val()) - 1;

                        viewReportPage(page);
                    }
                });

                $('.NextPage').click(function () {
                    if (!$(this).attr('disabled')) {
                        var page = parseInt($('#ReportViewerCurrentPage').val()) + 1;

                        viewReportPage(page);
                    }
                });

                $('.LastPage').click(function () {
                    if (!$(this).attr('disabled')) {
                        var page = parseInt($('#ReportViewerTotalPages').text());

                        viewReportPage(page);
                    }
                });

                $('#ReportViewerCurrentPage').change(function () {
                    var page = $(this).val();

                    viewReportPage(page);
                });

                $('.ExportXml, .ExportCsv, .ExportPdf, .ExportMhtml, .ExportExcelOpenXml, .ExportTiff, .ExportWordOpenXml').click(function () {
                    exportReport($(this));
                });

                $('#ReportViewerSearchText').on("keypress", function (e) {
                    if (e.keyCode == 13) {
                        // Cancel the default action on keypress event
                        e.preventDefault();
                        findText();
                    }
                });

                $('.FindTextButton').click(function () {
                    findText();
                });

                $('.Print').click(function () {
                    printReport();
                });
            });

            function _initializeReportViewerControls() {
                $('select').select2();

                try {
                    ReportViewer_Register_OnChanges();
                } catch (e) { }
            }

            function reloadParameters() {
                var params = $('.ParametersContainer :input').serializeArray();
                var urlParams = $.param(params);

                showLoadingProgress("Updating Parameters...");

                $.get("/Report/ReloadParameters/?reportPath=@Model.ReportPath.UrlEncode()&" + urlParams).done(function (data) {
                    if (data != null) {
                        $('.Parameters').html(data);
                        _initializeReportViewerControls();

                        if ($('.ReportViewerContent').find('div').length != 1) {
                            $('.ReportViewerContent').html('<div class="ReportViewerInformation">Please fill parameters and run the report...</div>');
                        }
                    }
                    hideLoadingProgress();
                });
            }

            function showLoadingProgress(message) {
                hideLoadingProgress();

                $('.ReportViewerContent').hide();
                $('.ReportViewerContentContainer').append('<div class="loadingContainer"><div style="margin: 0 auto; width: 100%; text-align: center; vertical-align: middle;"><h2><i class="glyphicon glyphicon-refresh gly-spin"></i>' + message + '</h2></div></div>');
            }

            function hideLoadingProgress() {
                $('.loadingContainer').remove();
                $('.ReportViewerContent').show();
            }

            function printReport() {
                var params = $('.ParametersContainer :input').serializeArray();
                var urlParams = $.param(params);

                window.open("/Report/PrintReport/?reportPath=@Model.ReportPath.UrlEncode()&" + urlParams, "_blank");
            }

            function findText() {
                $('.ReportViewerContent').removeHighlight();
                var searchText = $("#ReportViewerSearchText").val();
                if (searchText != undefined && searchText != null && searchText != "") {
                    showLoadingProgress('Searching Report...');
                    var params = $('.ParametersContainer :input').serializeArray();
                    var urlParams = $.param(params);

                    var page = parseInt($('#ReportViewerCurrentPage').val());

                    $.get("/Report/FindStringInReport/?reportPath=@Model.ReportPath.UrlEncode()&page=" + page + "&searchText=" + searchText + "&" + urlParams).done(function (data) {
                        if (data > 0) {
                            viewReportPage(data, function () {
                                $('.ReportViewerContent').highlight(searchText);
                                hideLoadingProgress();
                            });
                        } else {
                            $('.ReportViewerContent').highlight(searchText, { wholeWord: false, ignoreCase: true, color: "#ffff00", bold: true });
                            hideLoadingProgress();
                        }
                    });
                }
            }

            function viewReportPage(page, afterReportLoadedCallback) {
                showLoadingProgress('Loading Report Page...');
                var params = $('.ParametersContainer :input').serializeArray();
                var urlParams = $.param(params);
                var totalPages = parseInt($('#ReportViewerTotalPages').text());

                if (page == undefined || page == null || page < 1) {
                    page = 1;
                } else if (page > totalPages) {
                    page = totalPages;
                }

                $.get("/Report/ViewReportPage/?reportPath=@Model.ReportPath.UrlEncode()&page=" + page + "&" + urlParams)
                    .done(function (data) {
                        updateReportContent(data);
                        hideLoadingProgress();

                        if (afterReportLoadedCallback && typeof (afterReportLoadedCallback) == "function") {
                            afterReportLoadedCallback();
                        }
                })
                    .fail(function (data) {
                        $('.ReportViewerContent').html("<div class='ReportViewerError'>Report failed to load, check report parameters...</div>");
                        hideLoadingProgress();
                });
            }

            function exportReport(element) {
                var params = $('.ParametersContainer :input').serializeArray();
                var urlParams = $.param(params);
                var format = $(element).attr('class').replace("Export", "");

                window.location.href = "/Report/ExportReport/?reportPath=@Model.ReportPath.UrlEncode()&format=" + format + "&" + urlParams;
            }

            function updateReportContent(data) {
                if (data != undefined && data != null) {
                    $('#ReportViewerCurrentPage').val(data.CurrentPage);
                    $('#ReportViewerTotalPages').text(data.TotalPages);
                    $('.ReportViewerContent').html($.parseHTML(data.Content));

                    if (data.TotalPages <= 1) {
                        $('.FirstPage').attr('disabled', true);
                        $('.PreviousPage').attr('disabled', true);
                        $('.NextPage').attr('disabled', true);
                        $('.LastPage').attr('disabled', true);
                    } else {
                        $('.FirstPage').attr('disabled', false);
                        $('.PreviousPage').attr('disabled', false);
                        $('.NextPage').attr('disabled', false);
                        $('.LastPage').attr('disabled', false);
                    }
                }
            }
    </script>
}

@section Content {
    @Html.RenderReportViewer(Model)
}

任何帮助将不胜感激。

【问题讨论】:

  • 为什么不将"/Report/ViewReportPage/?reportPath=@Model.ReportPath.UrlEncode()&amp;page=" + page + "&amp;" + urlParams 解析为实际值,看看它是什么样子的。我认为那里有一些它不喜欢的坏数据
  • 谢谢尼克,已经这样做了(大约有 30 个不同的值)。仍然得到完全相同的结果。
  • 所以当您将该 URL 直接插入浏览器时,您会收到 500 错误还是它有效?我已经完全将 SSRS 与 Web URL API 一起使用。如果您对 Web URL API 进行故障排除,它可能会帮助您隔离问题。听起来这是一个旧的不受支持的库。它只是使用 Web URL API 来呈现报告,然后对其进行一些诡计。
  • 登录后,如果我将 URL 直接插入我的 2.1 版本,它就可以工作。与转换后的 5.0 版本相同的 URL 会出现 500 错误。
  • 如果您将 URL 直接插入浏览器,它不知道您使用的是哪个 .net 版本。但无论如何,至少听起来它是一个有效的 URL。在不同版本之间解析 URL 时,它们看起来是否相同?

标签: c# asp.net json asp.net-mvc


【解决方案1】:

我不确定这是否有帮助,但签名显然已经从

Json(Object, JsonSerializerSettings)

Json(Object, Object)

documentation

data Object 

要序列化的对象。

serializerSettings  Object 

格式化程序要使用的序列化程序设置。

使用 System.Text.Json 时,这应该是 JsonSerializerOptions。

使用 Newtonsoft.Json 时,这应该是 JsonSerializerSettings.

因此,大概该方法仍应接受相同的对象。但是如果你有一些使用旧方法签名的东西,你要么需要更新引用,要么需要更新调用该方法的库。毕竟,方法解析发生在您编译源代码时。当达到抖动时,方法签名需要完全匹配。

不幸的是,我对 asp.net 以及 .net core 2 与 .net 5 的知识不够了解,无法提供更具体的建议。

【讨论】:

  • 感谢 JonasH,之前在我的研究中看到过该参考资料,并且您没有足够的知识来应用它。也许这意味着 AlanJuden 的包需要更新?
  • @Rod Foulcher,这似乎很有可能。
【解决方案2】:

答案:(我只是部分理解)

感谢@Nick.McDermaid 和@JonasH 的帮助。

回到 AlanJuden GitHub 并参考选项 #1 中提到的代码找到了他的另一个控制器,该控制器具有不同的 ViewReportPage 方法。

将此复制到我的控制器中(带有一些用于错误的修改和前面提到的 System.Text.Json 作为选项 #1 的更改)以尝试使 System.Text.Json.JsonSerializerOptions() 正常工作。

IE 在报告 ActionResults 之前在 ReportController.cs 中添加了以下内容。

public new JsonResult ViewReportPage(string reportPath, int? page = 0)
        {
            var model = this.GetReportViewerModel(Request);
            model.ViewMode = AlanJuden.MvcReportViewer.ReportViewModes.View;
            model.ReportPath = reportPath;

            var contentData = AlanJuden.MvcReportViewer.ReportServiceHelpers.ExportReportToFormat(model, AlanJuden.MvcReportViewer.ReportFormats.Html4_0, page, page);
            var content = model.Encoding.GetString(contentData.ReportData);
            if (model.UseCustomReportImagePath && model.ReportImagePath.HasValue())
            {
                content = AlanJuden.MvcReportViewer.ReportServiceHelpers.ReplaceImageUrls(model, content);
            }

            var jsonResult = Json(
                new
                {
                    contentData.CurrentPage,
                    Content = content,
                    contentData.TotalPages
                },
                
                new System.Text.Json.JsonSerializerOptions()); 

            return jsonResult;
        } 

当我运行此程序时,在 $get 代码(F12 开发人员工具/网络选项卡/正文)处我收到不同的 500 错误 - 请求匹配多个端点。火柴: SSFA_Web.Controllers.ReportController.ViewReportPage (SSFA_Web) SSFA_Web.Controllers.ReportController.ViewReportPage (SSFA_Web)

我假设 1 来自我的 Controller mods 和 1 来自 AlanJudens dll。

最终(几天后)发现这是可行的:

已更改 ReportController.cs/JsonResult:
来自 public new JsonResult ViewReportPage(string reportPath, int?page = 0)

To public JsonResult ViewReportPageX(string reportPath, int?page = 0)

已更改 ReportViewer.cshtml/viewReportPage
来自 $.get("/Report/viewReportPage/?reportPath=@Model.ReportPath.UrlEncode()&page=" + page + "&" + urlParams)

到 $.get("/Report/viewReportPageX/?reportPath=@Model.ReportPath.UrlEncode()&page=" + page + "&" + urlParams)

很可能不是应该怎么做,但它确实有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-05
    • 2015-01-17
    • 2018-02-24
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    相关资源
    最近更新 更多