Jaco Ferreira Ответов: 1

Как войти в базу данных SQL для подключения к отчету crystal с помощью ASP.NET контроллер MVC 5 (C#)


Привет,

У меня есть решение Visual Studio 2017 с несколькими проектами. Один из проектов содержит все мои отчеты. Веб-приложение было создано с использованием языка C#, ASP.NET MVC 5, MS SQL 2014, и я использую Entity Framework Code-first для своих моделей данных.

Конкретный отчет, который я создал, довольно сложен. Таким образом, он собирает финансовые данные из нескольких таблиц данных, а затем отображает "отчет-подобный" отчет для конкретного клиента. Чтобы позволить пользователю сохранять отчеты, я создал следующие модели данных отчетов для хранения полученных данных из остальной части приложения:

Я использую надстройку Crystal Reports для Visual Studio.

1) ежемесячные платежи клиентов - соединяет отчет "MonthlyCustomerPayments.rpt" с моделью данных "CustomerMonthlyPaymentsReport". Это "основной" или "основной" отчет.


Следующие подотчеты/модели связаны через первичный ключ "ReportId" с основным отчетом/моделью.

2) резюме клиента - "CustomerSummary.rpt" - модель данных "CustomerSummary".

3) сводка платы за обслуживание клиентов - "CustomerServiceFeeSummary.rpt" модель данных "CustomerServiceFeeSummary".

4) сводка профиля учетной записи клиента - "CustomerAccountProfileSummary.rpt" - модель данных "CustomerAccountProfileSummary".

5) сводка по счету клиента - "CustomerAccountSummary.rpt" - модель данных "CustomerAccountSummary".

6) сводка обслуживания клиентов - "CustomerServiceSummary.rpt" - модель данных "CustomerServiceSummary".

7) Сведения о Службе поддержки транзакций - "обслуживание клиентов подробности операции" - "CustomerServiceTransactionDetails" модели данных.


Я надеюсь, что все вышесказанное имеет смысл с точки зрения настройки моделей данных и соответствующих им отчетов.

У меня есть контроллер, который собирает данные для каждой таблицы данных, сохраняет их, а затем отображает таблицы отчетов в виде Razor. На этом представлении у меня есть две кнопки: одна для "экспорта в PDF", а другая для "экспорта в Excel".

Таким образом, идея заключается в том, что клиент генерирует отчет для указанного диапазона дат, сохраняет его, а затем имеет возможность экспортировать отчет в PDF или Excel foemat.

Я буду использовать экспорт PDF в качестве примера. У меня есть следующий код для кнопки экспорта PDF в CustomerMonthlyPaymentReportsController:

public ActionResult ExportReportPDF(int id)
{
	string ServerName = System.Configuration.ConfigurationManager.AppSettings["DbServer"].ToString();       //Database server name to which report connected
        string DataBaseName = System.Configuration.ConfigurationManager.AppSettings["DbName"].ToString();       //Database name to which report connected
        string UserID = System.Configuration.ConfigurationManager.AppSettings["DbUser"].ToString();             //Database user name to which report connected
        string Password = System.Configuration.ConfigurationManager.AppSettings["DbPwd"].ToString();            //Database user password to which report connected

        ReportDocument crReportDocument = new ReportDocument();

        crReportDocument.Load(Path.Combine(Server.MapPath("~/Reports/Admin"), "MonthlyCustomerPayments.rpt"));
        crReportDocument.SetDataSource(db.CustomerMonthlyPaymentsReport.Where(x => x.ReportId == id).ToList());

        //crReportDocument.SetDatabaseLogon(UserID, Password);
        Logon(crReportDocument, ServerName, DataBaseName, UserID, Password);

        //crReportDocument = prepareReport(crReportDocument);

        Response.Buffer = false;
        Response.ClearContent();
        Response.ClearHeaders();

        string reportDescription = db.CustomerMonthlyPaymentsReport.Where(x => x.ReportId == id).Select(x => x.ReportDescription).First();

        try
        {
            Stream stream = crReportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
            stream.Seek(0, SeekOrigin.Begin);
            string savedFileName = string.Format(reportDescription + ".pdf");
            return File(stream, "application/pdf", savedFileName);
        }
        catch
        {
            throw;
        }
}



Следующий код используется для входа в каждый отчет с использованием учетных данных SQL server, хранящихся в файле Web.Config:

//Check whether crytal report can login to the server
private bool Logon(ReportDocument cr, string server, string database, string user_id, string password)
{
    // Declare and instantiate a new connection info object.
    ConnectionInfo ci;
    ci = new ConnectionInfo();

    ci.ServerName = server;
    ci.DatabaseName = database;
    ci.UserID = user_id;
    ci.Password = password;             //password;
    // ci.IntegratedSecurity = false;

    // If the ApplyLogon function fails then return a false for this function.
    // We are applying logon information to the main report at this stage.
    if (!ApplyLogon(cr, ci))
    {
        return false;
    }

    // Declare a subreport object.
    SubreportObject subobj;

    // Loop through all the report objects and locate subreports.
    // If a subreport is found then apply logon information to
    // the subreport.
    foreach (ReportObject obj in cr.ReportDefinition.ReportObjects)
    {
        if (obj.Kind == ReportObjectKind.SubreportObject)
        {
            subobj = (SubreportObject)obj;
            if (!ApplyLogon(cr.OpenSubreport(subobj.SubreportName), ci))
            {
                return false;
            }
        }
    }

    // Return True if the code runs to this stage.
    return true;

}



Следующий код вызывается методом входа в систему:

private bool ApplyLogon(ReportDocument cr, ConnectionInfo ci)
{
    // This function is called by the "Logon" function
    // It loops through the report tables and applies
    // the connection information to each table.

    // Declare the TableLogOnInfo object and a table object for use later.
    TableLogOnInfo li;
    // For each table apply connection info.

    foreach (CrystalDecisions.CrystalReports.Engine.Table tbl in cr.Database.Tables)
    {

        li = tbl.LogOnInfo;
        li.ConnectionInfo.ServerName = ci.ServerName;
        li.ConnectionInfo.DatabaseName = ci.DatabaseName;
        li.ConnectionInfo.UserID = ci.UserID;
        li.ConnectionInfo.Password = ci.Password;
        tbl.ApplyLogOnInfo(li);
        tbl.Location = ci.DatabaseName + ".dbo." + tbl.Name;

        // Verify that the logon was successful.
        // If TestConnectivity returns false, correct table locations.
        if (!tbl.TestConnectivity())
        {
            return false;

        }
    }
    return true;
}



Я надеюсь, что приведенный выше код имеет смысл. То, что я пытаюсь сделать, - это заставить приложение войти в базу данных, используя конкретные учетные данные, которые я указываю в конфигурации.Веб-файл. Это делается для того, чтобы я мог тестировать отчеты на своем компьютере разработчика и указывать учетные данные для входа на рабочий (живой) сервер.

Проблема, с которой я сталкиваюсь, заключается в том, что все это прекрасно работает на моем компьютере Dev, но дает мне следующую ошибку на производственном сервере:

"Ошибка в файле MonthlyCustomerPayments 5412_8572_{99689A9A-3AB1-47CF-B744-2DA06097BBDD}.rpt:
Не удается подключиться: неверные параметры входа в систему."

Из того, что я смог выяснить, кажется, что он берет имя SQL server моего Dev PC, встроенное в отчет, и мой код выше для входа в экземпляр SQL server производственного сервера игнорируется.

Я знаю, что это логическое объяснение моей конкретной проблемы, но я опубликовал на многих форумах об этом, и люди, похоже, неправильно понимают детали и сложность настройки моего отчета.

Я надеюсь, что кто-то, кто использовал Entity Framework и Crystal Reports в приложении MVC с отчетом и несколькими вложенными отчетами, может дать мне совет по этому вопросу.

Спасибо, что прочитали это, и я с нетерпением жду любых предложений/советов.

Что я уже пробовал:

Я пробовал бесчисленные предложения по использованию ASPX и CrstalReport Viewer, но боюсь, что они не очень хорошо работают с этим сложным отчетом, который имеет несколько вложенных отчетов.

Приведенный выше код я реализовал по предложению человека на другом форуме, чтобы регистрировать каждый отчет/подотчет в базе данных.

1 Ответов

Рейтинг:
0

Maciej Los

Проверить это:

Цитата:


Для тех, у кого есть такая же проблема, также проверьте, является ли поставщик источников данных вашего отчета "собственным клиентом SQL". Если да, то это не будет работать на вашем производственном сервере, на котором не установлен SQL-клиент. Это должен быть "SQLOLEDB", чтобы он работал на машинах, где не установлен SQL-клиент.

Именно по этой причине мой отчет работал на моем тестовом сервере(который имел клиент SQL server) и не работал на моем рабочем сервере


Источник: c# - Crystal Report: невозможно подключить неверные параметры входа в систему - переполнение стека[^]

Возможно, Вам тоже будет интересно прочитать этот документ: Руководство по устранению неполадок с подключением баз данных к Crystal Reports в Visual Studio .Сетевые приложения[^]