0
votes

I created a simple console application and runing it as Azure webjob, getting below error. Same code working fine in local.

[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

Console App code :

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

I added app setting key in azure portal , still no help.

1
Looks like you're getting a storage exception. First step is isolate to a simpler scenario that doesn't involve WebJobs, per this page.David Ebbo

1 Answers

2
votes

Many factors could cause 400 bad request error when we do an operation on the Table service. For example, the property name is invalid, the value specified is invalid etc.

Same code working fine in local.

I test your code on my local, your code do not work (it returns 400 bad request error) on my local. I find that you use a datetime-based row key(this.RowKey = InsertionDate.ToUniversalTime().ToString();), which may cause this type issue. The row key value looks like 10/11/2016 3:14:03 AM (having the forward slash (/) character) on my local. However the forward slash (/) character is not allowed in values for the PartitionKey and RowKey properties. Please check “Characters Disallowed in Key Fields” section.

You could try to use the following code taking the current time value in Ticks as the Row Key value.

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

Besides, you could check this article which explained two approaches to generate a Partition Keys based on datetime.