运行 简单控制台应用程序作为 Azure webjob 时出错

Error While running Simple console application as Azure webjob

我创建了一个简单的控制台应用程序并将其作为 Azure webjob 运行,出现以下错误。相同的代码在本地运行良好。

[10/10/2016 18:15:48 > 494acb: SYS INFO] Status changed to Initializing [10/10/2016 18:15:48 > 494acb: SYS INFO] Run script 'ConsoleApplication1.exe' with script host - 'WindowsScriptHost' [10/10/2016 18:15:48 > 494acb: SYS INFO] Status changed to Running [10/10/2016 18:15:49 > 494acb: ERR ] [10/10/2016 18:15:49 > 494acb: ERR ] Unhandled Exception: Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request. [10/10/2016 18:15:49 > 494acb: ERR ] at System.Net.HttpWebRequest.GetResponse() [10/10/2016 18:15:49 > 494acb: ERR ] at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) [10/10/2016 18:15:49 > 494acb: ERR ] --- End of inner exception stack trace --- [10/10/2016 18:15:49 > 494acb: ERR ] at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) [10/10/2016 18:15:49 > 494acb: ERR ] at Microsoft.WindowsAzure.Storage.Table.TableOperation.Execute(CloudTableClient client, CloudTable table, TableRequestOptions requestOptions, OperationContext operationContext) [10/10/2016 18:15:49 > 494acb: ERR ] at Microsoft.WindowsAzure.Storage.Table.CloudTable.Execute(TableOperation operation, TableRequestOptions requestOptions, OperationContext operationContext) [10/10/2016 18:15:49 > 494acb: ERR ] at ConsoleApplication1.Program.getStockPriceFromGoogle() [10/10/2016 18:15:49 > 494acb: ERR ] at ConsoleApplication1.Program.Main(String[] args) [10/10/2016 18:15:49 > 494acb: SYS INFO] Status changed to Failed [10/10/2016 18:15:49 > 494acb: SYS ERR ] Job failed due to exit code -532462766

控制台应用程序代码:

class Program
{
    static void Main(string[] args)
    {
        getStockPriceFromGoogle();
    }

    public static void getStockPriceFromGoogle()
    {

        try
        {
            CloudStorageAccount storageAcount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
            CloudTableClient tableClient = storageAcount.CreateCloudTableClient();
            CloudTable googleStockTable = tableClient.GetTableReference("GoogleStock");
            googleStockTable.CreateIfNotExists();

            const string tickers = "RELIANCE,SBIN";
            string json = null;

            try
            {
                using (var web = new WebClient())
                {
                    var url = $"http://finance.google.com/finance/info?client=ig&q=NSE%3A{tickers}";
                    json = web.DownloadString(url);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Error calling Google service , error :" + ex.ToString());
            }

            //Google adds a comment before the json for some unknown reason, so we need to remove it
            json = json.Replace("//", "");

            var v = JArray.Parse(json);

            foreach (var i in v)
            {
                var ticker = i.SelectToken("t");
                var price = (decimal)i.SelectToken("l");

                GoogleStock googleStock = new GoogleStock(ticker.ToString(), DateTime.Now)
                {
                    Price = price,
                    PriceInLocalCurrency = i.SelectToken("l_cur").ToString(),

                    id = (int)i.SelectToken("id"),
                    Exchange = i.SelectToken("e").ToString(),
                    Chanage = (float)i.SelectToken("c"),
                    ChnagePersontage = (float)i.SelectToken("cp"),
                    LastTradeTime = (DateTime)i.SelectToken("lt_dts"),

                };

                try
                {
                    TableOperation insertOperation = TableOperation.Insert(googleStock);
                    googleStockTable.Execute(insertOperation);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Error When saving data , error :" + ex.ToString());
                    throw;
                }

                Console.WriteLine($"{ticker} : {price}");
            }
        }
        catch (Exception ex)
        {
            Trace.WriteLine("Error When saving data , error :" + ex.ToString());
            throw;
        }
    }
}

class GoogleStock : TableEntity
{
    public GoogleStock(string StockName, DateTime InsertionDate)
    {
        this.PartitionKey = StockName;
        this.RowKey = InsertionDate.ToUniversalTime().ToString();
    }

    public int id { get; set; }

    public string StockName { get; set; }

    public string Exchange { get; set; }

    public decimal Price { get; set; }

    public string PriceInLocalCurrency { get; set; }

    public DateTime LastTradeTime { get; set; }

    public float Chanage { get; set; }

    public float ChnagePersontage { get; set; }
}

我在 Azure 门户中添加了应用程序设置密钥,仍然没有帮助。

当我们对Table服务进行操作时,许多factors可能会导致400 bad request错误。例如,属性 名称无效,指定的值无效等。

Same code working fine in local.

我在我的本地测试你的代码,你的代码在我的本地不起作用(returns 400 错误请求错误)。我发现您使用了基于日期时间的行键 (this.RowKey = InsertionDate.ToUniversalTime().ToString();),这可能会导致此类问题。行键值在我的本地看起来像 10/11/2016 3:14:03 AM(具有正斜杠 (/) 字符)。但是,PartitionKey 和 RowKey 属性的值中不允许使用正斜杠 (/) 字符。请检查“Characters Disallowed in Key Fields”部分。

您可以尝试使用以下代码,将Ticks中的当前时间值作为Row Key值。

this.RowKey = InsertionDate.Ticks.ToString("d19");

此外,您可以查看 this article,其中解释了两种基于日期时间生成分区键的方法。