PostAsJsonAsync not calling webapi service from wi

2019-07-14 22:07发布

I have a windows service which has the following code

    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").Result;
        // loop through all applications and compare to rules
        if (certificationsResponse.IsSuccessStatusCode)
        {

            content = certificationsResponse.Content.ReadAsStringAsync().Result;
            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;
    }
}

The Following are the services that are getting called

        ////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <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;
        }
    }

}

I've verified the GetAsync GetAllCertifications() call works as I can debug into that code block. However when I do the PostAsJsonAsync using the anonymous type it won't work. I know json only cares about the properties. I've also verified that it DOES hit the PostAsJsonAsync line of code, so it should be performing the post. So what am I doing wrong?

1条回答
趁早两清
2楼-- · 2019-07-14 22:34

the problem is your web api method. Your post method accepts two "simple" types. And per default simple types are read from the URI NOT from the body.

The body is read for a complex type. So you have two options:

  1. Make the parameter in your web api method a complex type with appropriate properties
  2. Put your parameters in your URI to get them

You can't read two primitive types from the body, you can only force one to be read with [FromBody] Attribute.

In more detail you can read the parameter binding here: Parameter Binding in ASP.NET Web API

查看更多
登录 后发表回答