c# - PostAsJsonAsync 不使用匿名类型从 Windows 服务调用 webapi 服务,有什么明显的错误吗?

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

我有一个具有以下代码的 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").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;
    }
}

以下是被调用的服务

        ////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <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 代码行,因此它应该执行该帖子。那我做错了什么?

最佳答案

问题出在您的网络 API 方法上。您的 post 方法接受两种“简单”类型。默认情况下,简单类型是从正文中的 URI NOT 中读取的。

读取复杂类型的正文。 所以你有两个选择:

  1. 使您的 web api 方法中的参数成为具有适当属性的复杂类型
  2. 将您的参数放在您的 URI 中以获取它们

您不能从正文中读取两种原始类型,您只能使用 [FromBody] 属性强制读取一种。

您可以在此处阅读参数绑定(bind)的更多详细信息:Parameter Binding in ASP.NET Web API

关于c# - PostAsJsonAsync 不使用匿名类型从 Windows 服务调用 webapi 服务,有什么明显的错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24212152/

相关文章:

c# - 在 ASP.NET WebAPI 中检索不记名 token

docker - 如何让docker包含wwwroot静态内容aspnet核心

Extjs批量加载多个店铺

c# - 在 C# 中按月对数据进行分组和计数

c# - Visual Studio 加载项 : How do I Add Item Specific Commands to the Solution Explorer Context Menu

c# - 如何在C#中标准化WAV文件量?

php - 循环遍历 Laravel 集合并使用 Redis 存储到 key

php - 如何访问数组中的json?

c# - Itextsharp : PDF size too large when including images

javascript - 循环遍历json数组列表