【问题标题】:The following works in development on a local host but in production does not以下在本地主机上的开发工作,但在生产中没有
【发布时间】:2019-11-21 11:30:58
【问题描述】:

我创建了一个类,它有一个计时器,该计时器调用在我的 Azure 帐户中创建的函数以返回 azure 的状态,返回值被缓存。在类中,我有一个返回缓存值的 WEB API。

我有 Windows 窗体软件,每分钟调用一次 WEB API 以获取状态。

这一切在本地主机上的开发中都可以正常工作,但在生产中却不行。

[EnableCorsAttribute("*", "*", "*")]
public class AzureStatusController : ApiController
{
    private readonly int statusTimerInterval = 60 * 1000; // every 60 seconds

    private static bool cloudStatus = false;

    static HttpClient client;
    private static string url = "";
    private static string code = "";

    private System.Threading.Timer cloudTimer;

    /// <summary>
    /// Classes Ctor
    /// </summary>
    public AzureStatusController()
    {
        cloudTimer = new System.Threading.Timer(OnAzureStatusCallback, null, 0, statusTimerInterval);

        url = ConfigurationManager.AppSettings["CloudFunctionsBaseUrl"].ToString();
        code = ConfigurationManager.AppSettings["CloudStatusCode"].ToString();
        client = new HttpClient();
        client.BaseAddress = new Uri(url);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    private void OnAzureStatusCallback(object state)
    {
        var status = false;
        if (client != null && client.BaseAddress.ToString().Length > 30 && code.Length > 70)
        {
            try
            {
                var response = client.GetAsync(code);
                if (response != null && !response.IsFaulted)
                {
                    var result = response.Result;
                    if (result != null && result.IsSuccessStatusCode && result.Content != null)
                    {
                        string responseString = result.Content.ReadAsStringAsync().Result.Trim().ToLower();
                        status = (responseString.Contains("ok"));
                    }
                }
            }
            catch
            {
                status = false;
            }
        }
        cloudStatus = status;
    }

    /// <summary>
    /// Returns the cached value of the Azure status
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet]
    [Route("api/AzureStatus")]
    public IHttpActionResult Get()
    {
        return Ok(cloudStatus);
    }
}

有人知道我可能缺少什么吗?

【问题讨论】:

  • 如果我理解正确,您有三个元素:1) 生成状态消息的 Azure 函数 2) 每分钟轮询函数并存储缓存值的 WebAPI 控制器,然后可用于 3) A Windows 窗体应用程序。我的问题是——这三件中的哪一件在生产中不起作用,具体是什么不起作用?例如消息丢失、抛出错误或计时器未触发。如果您遇到错误,请编辑以添加堆栈跟踪。发布表单和函数的相关代码也可能会有所帮助。
  • 我收到一则错误消息 {"Message":"An error has occurred."}。没有堆栈可追踪。我最终确实让我的系统管理员打开了服务器调试,并且我收到了更多信息(虽然不是真的有用)。经过更多测试后,我发现问题出在 ConfigurationManager.AppSettings 调用的 .ToString() 部分。尽管摆脱 .ToString() 确实解决了我的问题,但这也没有什么意义。
  • 现在可以用了吗?
  • 是的。很抱歉在我的回复中没有明确说明。
  • 太棒了!请考虑将此作为答案发布 - 这将使处于相同情况的其他人更容易找到解决方案。

标签: c# azure asp.net-web-api timer


【解决方案1】:

我最终发现将 .ToString() 添加到我的 ConfigurationManager.AppSettings 调用的末尾会导致生产问题,但不会导致开发问题。我没有花更多时间在这个问题上,而是使用了以下代码:

public class AzureStatusController : ApiController
{
    private static bool cloudStatus = false;
    private static DateTime expiration;

    /// <summary>
    /// Classes Ctor
    /// </summary>
    public AzureStatusController()
    {
        expiration = DateTime.Now.AddHours(-1);
    }

    private void CheckAzureStatus()
    {
        var status = false;
        using (var client = new HttpClient())
        {
            // the following 2 lines should be changed to retrieve the info from 
            var url = ConfigurationManager.AppSettings["CloudFunctionsBaseUrl"];
            var code = ConfigurationManager.AppSettings["CloudStatusCode"];
            client.BaseAddress = new Uri(url);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            try
            {
                var response = client.GetAsync(code);
                if (response != null && !response.IsFaulted)
                {
                    var result = response.Result;
                    if (result != null && result.IsSuccessStatusCode && result.Content != null)
                    {
                        string responseString = result.Content.ReadAsStringAsync().Result.Trim().ToLower();
                        status = (responseString.Contains("ok"));
                    }
                }
            }
            catch
            {
                status = false;
            }
        }
        cloudStatus = status;
        expiration = DateTime.Now.AddMinutes(1);
    }

    /// <summary>
    /// Returns the cached value of the Azure status
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet]
    [Route("api/AzureStatus")]
    public IHttpActionResult Get()
    {
        if (expiration < DateTime.Now)
        {
            CheckAzureStatus();
        }
        return Ok(cloudStatus);
    }
}

【讨论】:

    猜你喜欢
    • 2018-08-01
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2017-06-25
    相关资源
    最近更新 更多