运行 简单控制台应用程序作为 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](RESTCommand
1 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,其中解释了两种基于日期时间生成分区键的方法。
我创建了一个简单的控制台应用程序并将其作为 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](RESTCommand
1 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](RESTCommand
1 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,其中解释了两种基于日期时间生成分区键的方法。