Net Core 3.1 Вернуть задание с результатом, содержащим сведения об исключении? - PullRequest
2 голосов
/ 04 февраля 2020

Я использую ADO. Net для заполнения таблицы данных, метод заполнения данных, который я поместил в отдельный репозиторий. Я внедряю репозиторий / интерфейс в модель тестовой страницы. Метод модели страницы "OnPostUpdateAlarmDataTableAsyn c" должен вызвать интерфейс и запросить заполнение таблицы данных. Я хочу вернуть результат задачи, которая заполняет эту таблицу, поэтому, если по какой-либо причине задача завершается неудачей, я могу сообщить пользователю об интерфейсе пользователя, я также хочу записать подробности ошибки из модели страницы, так как является вызывающим потоком.

Текущая ошибка компиляции говорит, что «не может присвоить void неявно типизированной переменной» Но какую бы комбинацию в коде я не изменял, я пытаюсь что-то никогда не скомпилировать должным образом. Я хочу достичь задачи из асинхронной операции c с соответствующей информацией, содержащей подробности об исключении.

Интерфейс:

public interface IAdoNetRepository
{
    Task FillAlarmsDataTable();
}

Репозиторий:

public class AdoNetRepository : IAdoNetRepository
{
    public readonly IConfiguration _config;

    public AdoNetRepository(IConfiguration config)
    {
        _config = config;
    }

    // Used for method below GetUserGroupsData()
    public static SqlDataAdapter dataAdapter = new SqlDataAdapter();
    public static DataTable alarmDataTable;


    public async Task FillAlarmsDataTable()
    {
        string connectionString = _config.GetConnectionString("Data:DefaultConnection:ConnectionString");

        try
        {
            SqlConnection connection = new SqlConnection(connectionString);
            string cmdText1 = "SELECT * FROM [dbo].[Alarms] ORDER BY Name";

            // Create a new data adapter based on the specified query.
            dataAdapter = new SqlDataAdapter(cmdText1, connection);

            // Populate a new data table and bind it to the BindingSource.
            alarmDataTable = new DataTable
            {
                Locale = CultureInfo.InvariantCulture
            };
            await Task.Run(() => dataAdapter.Fill(alarmDataTable));
            //dataAdapter.Fill(alarmDataTable);

            return; // Return what ?
        }
        catch (Exception ex)
        {
            // Return the task with details of the exception
            return; // Return what?
        }
    }
}

PageModel:

public class TestModel : PageModel
{

    private readonly IAdoNetRepository _adoNetRepository;

    public TestModel(IAdoNetRepository adoNetRepository)
    {
        _adoNetRepository = adoNetRepository;
    }

    public async Task<IActionResult> OnPostUpdateAlarmDataTableAsync()
    {
        // This gets squiggly line compile error            
        var result = await _adoNetRepository.FillAlarmsDataTable();

        if (!result.Succeeded)
        {
            // log the exception returned from the task that failed!
        }

        return new JsonResult(result);
    }
}

1 Ответ

2 голосов
/ 04 февраля 2020

Комментарии в исходном примере показывают, что вы на самом деле должны делать.

вам нужно создать модель для хранения необходимой информации.

Что-то вроде

/// <summary>
/// Represents the result of an ADO.Net operation.
/// </summary>
public class AdoNetResult {
    private List<Exception> _errors = new List<Exception>();

    public bool Succeeded { get; protected set; }
    public IEnumerable<Exception> Errors => _errors;

    public static AdoNetResult Success { get; } = new AdoNetResult { Succeeded = true };
    public static AdoNetResult Failed(params Exception[] errors) {
        var result = new AdoNetResult { Succeeded = false };
        if (errors != null) {
            result._errors.AddRange(errors);
        }
        return result;
    }
}

Интерфейс, однако, должен быть реорганизован

public interface IAdoNetRepository {
    Task<AdoNetResult> FillAlarmsDataTable();
}

и реализация

public async Task<AdoNetResult> FillAlarmsDataTable() {
    string connectionString = _config.GetConnectionString("Data:DefaultConnection:ConnectionString");

    try {
        SqlConnection connection = new SqlConnection(connectionString);
        string cmdText1 = "SELECT * FROM [dbo].[Alarms] ORDER BY Name";

        // Create a new data adapter based on the specified query.
        dataAdapter = new SqlDataAdapter(cmdText1, connection);

        // Populate a new data table and bind it to the BindingSource.
        alarmDataTable = new DataTable {
            Locale = CultureInfo.InvariantCulture
        };
        await Task.Run(() => dataAdapter.Fill(alarmDataTable));

        // Return what ?
        return AdoNetResult.Success; 
    } catch (Exception ex) {
        // Return the task with details of the exception
        return AdoNetResult.Failed(ex);
    }
}

После этого исходный код должен работать как задумано

public async Task<IActionResult> OnPostUpdateAlarmDataTableAsync() {

    var result = await _adoNetRepository.FillAlarmsDataTable();

    if (!result.Succeeded) {
        // log the exception returned from the task that failed!
        //result.Errors
    }

    return new JsonResult(result);
}

В качестве альтернативы можно было бы разрешить FillAlarmsDataTable генерировать любые исключения, с которыми он может столкнуться

public Task FillAlarmsDataTable() {
    string connectionString = _config.GetConnectionString("Data:DefaultConnection:ConnectionString");

    SqlConnection connection = new SqlConnection(connectionString);
    string cmdText1 = "SELECT * FROM [dbo].[Alarms] ORDER BY Name";

    // Create a new data adapter based on the specified query.
    dataAdapter = new SqlDataAdapter(cmdText1, connection);

    // Populate a new data table and bind it to the BindingSource.
    alarmDataTable = new DataTable {
        Locale = CultureInfo.InvariantCulture
    };
    return Task.Run(() => dataAdapter.Fill(alarmDataTable));
}

перехватывать ( catch ) исключение, где оно используется, и отвечать соответствующим образом

public async Task<IActionResult> OnPostUpdateAlarmDataTableAsync() {
    try {
        await _adoNetRepository.FillAlarmsDataTable();
        return Ok(); //200 OK
    catch(Exception ex) {
        //...log the exception returned from the task that failed!

        return new ExceptionResult(ex, includeErrorDetail:true);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...