PostAsJsonAsync не вызывает службу webapi из службы Windows, используя анонимный тип, что-то явно не так?

#c# #json #asp.net-web-api #anonymous-types

#c# #json #asp.net-web-api #анонимные типы

Вопрос:

У меня есть служба Windows, которая имеет следующий код

     public class CertificationStatusCheckJob : IJob
{
    public readonly ILog _logger = LogManager.GetCurrentClassLogger();
    readonly HttpClient client = new HttpClient { BaseAddress = new Uri(ConfigurationManager.AppSettings["MercuryServicesWebApiUrl"]) };
    // Temporary local versoin of statuses
    private enum CertificationStatus
    {
        Active = 1,
        Pending,
        PendingRenewal,
        RenewalPastDue,
        ReinstatementOnCurrentCycle,
        ClosedInactive,
        ClosedRenewed
    };

    public async void Execute(IJobExecutionContext context)
    {

        Dictionary<string, int> designationWindows = new Dictionary<string, int>
        {
            {"RenewalWindow", 10},
            {"CertificationLength", 12},
            {"FreeGrace", 1},
            {"InactiveAccessLength",1},
            {"InactivityLength", 36}
        };


        Console.WriteLine("CertificationApplicationStatusCheckJob: Creating Cert application status job");
        string content = null;
        List<Certification> retrievedCerts = null;

        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        // Call webapi to retrieve all applications
        var certificationsResponse = client.GetAsync("certifications/getAllCertifications").Resu<
        // loop through all applications and compare to rules
        if (certificationsResponse.IsSuccessStatusCode)
        {

            content = certificationsResponse.Content.ReadAsStringAsync().Resu<
            Console.WriteLine(content);
        }

        if (content != null)
        {
            retrievedCerts = JsonConvert.DeserializeObject<List<Certification>>(content);
            _logger.Debug("Got Certifications OK");
        }

        //  Allows for all task calls to service api to be performed in parallel in async
        if (retrievedCerts != null)
            await Task.WhenAll(retrievedCerts.Select(i => CheckCert(i)) as IEnumerable<Task>);
    }

    private async Task<object> CheckCert(Certification cert)
    {
        // current date time to compare the range for each state below to.
        // if this date falls in the range for the state, do not change the state,
        // otherwise kick them into the next state.
        DateTime currentDateTime = DateTime.UtcNow;

        var newCertStatus = new { certUniqueId = Guid.NewGuid(), statusId=6 };

        switch ((CertificationStatus)cert.CertificationStatusId)
        {

            case CertificationStatus.Active:
                //Condition to test for when the cert is in the active state
                await client.PostAsJsonAsync("certifications/updateStateForCertification", newCertStatus);
                break;
            case CertificationStatus.Pending:
                break;
            case CertificationStatus.PendingRenewal:
                break;
            case CertificationStatus.RenewalPastDue:
                break;
            case CertificationStatus.ReinstatementOnCurrentCycle:
                break;
            case CertificationStatus.ClosedInactive:
                break;
            case CertificationStatus.ClosedRenewed:
                break;
        }
        return null;
    }
}
  

Ниже приведены службы, которые вызываются

         ////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>   Gets all certifications. </summary>
    /// <returns>   all certifications. </returns>
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    [Route("getAllCertifications")]
    [AllowAnonymous]
    public async Task<List<Certification>> GetAllCertifications()
    {

        List<Certification> certList = null;
        try
        {
            certList = await _certificationService.GetAllCertifications();
        }
        catch (Exception e)
        {
            _logger.Error("exception GetAllCertifications", e);
            throw;
        }

        return certList;
    }


    //TODO WRITE SERVICE ENTRY POINT FOR SAVE ROUTINE
    [Route("updateStateForCertification")]
    [AcceptVerbs("POST")]
    [AllowAnonymous]
    public void UpdateStateForCertification(Guid certUniqueId, int statusId)
    {

        List<Certification> certList = null;
        try
        {
           _certificationService.UpdateStateForCertification(certUniqueId, statusId);
        }
        catch (Exception e)
        {
            _logger.Error("exception UpdateStateForCertification", e);
            throw;
        }
    }

}
  

Я проверил, что вызов GetAsync GetAllCertifications() работает, поскольку я могу выполнять отладку в этом блоке кода. Однако, когда я выполняю PostAsJsonAsync с использованием анонимного типа, это не сработает. Я знаю, что json заботится только о свойствах. Я также проверил, что он попадает в строку кода PostAsJsonAsync, поэтому он должен выполнять post. Итак, что я делаю не так?

Комментарии:

1. Можете ли вы попробовать перейти content = certificationsResponse.Content.ReadAsStringAsync().Result на content = await certificationsResponse.Content.ReadAsStringAsync() ? Это что-нибудь меняет?

2. @avo — GetAllCertifications работает нормально… это сообщение, которое не

Ответ №1:

проблема в вашем методе веб-api. Ваш метод post принимает два «простых» типа. И по умолчанию простые типы считываются из URI, А НЕ из тела.

Тело считывается для сложного типа. Итак, у вас есть два варианта:

  1. Сделайте параметр в вашем методе web api сложным типом с соответствующими свойствами
  2. Поместите свои параметры в свой URI, чтобы получить их

Вы не можете прочитать два примитивных типа из тела, вы можете только принудительно прочитать один из них с [FromBody] помощью атрибута.

Более подробно вы можете ознакомиться с привязкой параметров здесь: Привязка параметров в ASP.NET Веб — API