public async Task <HttpResponseMessage> Post(
            [Metadata("API POST URL", "Web Service Request URI")] string _API_URL,
            [Metadata("API Key", "Web Service API Key")] string _API_Key,
            [Metadata("Storage Account Name (Input)", "Azure Storage Account Name")] string _Input_AccountName,
            [Metadata("Storage Account Key (Input)", "Azure Storage Account Key")] string _Input_AccountKey,
            [Metadata("Storage Container Name (Input)", "Azure Storage Container Name")] string _Input_Container,
            [Metadata("Blob Name (Input)", "Azure Storage Blob Name")] string _Input_Blob,

            [Metadata(FriendlyName = "Global Parameters Keys", Description = "Comma separated list of parameters", Visibility = VisibilityType.Advanced)] string _GlobalKeys = "",
            [Metadata(FriendlyName = "Global Parameters Values", Description = "Comma separated list of values", Visibility = VisibilityType.Advanced)] string _GlobalValues = ""

            )
        {
            BES_Input Obj = new BES_Input
            {
                API_URL           = _API_URL,
                API_Key           = _API_Key,
                Input_AccountName = _Input_AccountName,
                Input_AccountKey  = _Input_AccountKey,
                Input_Container   = _Input_Container,
                Input_Blob        = _Input_Blob,

                GlobalKeys   = _GlobalKeys,
                GlobalValues = _GlobalValues
            };

            BatchScoreStatus result = await BatchExecutionService.InvokeBatchExecutionService(Obj);

            HttpResponseMessage response = Request.CreateResponse <BatchScoreStatus>(HttpStatusCode.Accepted, result);

            response.Headers.Location = new Uri(string.Format("https://" + Request.RequestUri.Authority + "/api/CheckStatus?url={0}&api={1}", WebUtility.UrlEncode(result.JobLocation), WebUtility.UrlEncode(_API_Key)));
            response.Headers.Add("Retry-after", "30");
            return(response);
        }
        public async Task <HttpResponseMessage> Post(
            [Metadata("API POST URL", "Web Service Request URI")] string API_URL,
            [Metadata("API Key", "Web Service API Key")] string API_KEY,
            [Metadata("Storage Account Name (Input)", "Azure Storage Account Name")] string Input_AccountName,
            [Metadata("Storage Account Key (Input)", "Azure Storage Account Key")] string Input_AccountKey,
            [Metadata("Storage Container Name (Input)", "Azure Storage Container Name")] string Input_Container,
            [Metadata("Blob Name (Input)", "Azure Storage Blob Name")] string Input_Blob,
            [Metadata("Storage Account Name (Output)", "Azure Storage Account Name. Leave blank if same with Input")] string Output_AccountName            = "",
            [Metadata("Storage Account Key (Output)", "Azure Storage Account Key. Leave blank if same with Input")] string Output_AccountKey               = "",
            [Metadata("Storage Container Name (Output)", "Azure Storage Container Name. Leave blank if same with Input")] string Output_Container          = "",
            [Metadata("Blob Name (Output)", "Azure Storage Blob Name. Include file extention. Leaving blank will set it default name")] string Output_Blob = "",
            [Metadata(FriendlyName = "Global Parameters Keys", Description = "Comma separated list of parameters", Visibility = VisibilityType.Advanced)] string GlobalKeys = "",
            [Metadata(FriendlyName = "Global Parameters Values", Description = "Comma separated list of values", Visibility = VisibilityType.Advanced)] string GlobalValues = ""

            )
        {
            BES_Full Obj = new BES_Full
            {
                API_URL            = API_URL,
                API_Key            = API_KEY,
                Input_AccountName  = Input_AccountName,
                Input_AccountKey   = Input_AccountKey,
                Input_Container    = Input_Container,
                Input_Blob         = Input_Blob,
                Output_AccountName = Output_AccountName,
                Output_AccountKey  = Output_AccountKey,
                Output_Container   = Output_Container,
                Output_Blob        = Output_Blob,
                GlobalKeys         = GlobalKeys,
                GlobalValues       = GlobalValues
            };

            if (string.IsNullOrEmpty(Obj.Output_AccountName))
            {
                Obj.Output_AccountName = Obj.Input_AccountName;
            }
            if (string.IsNullOrEmpty(Obj.Output_AccountKey))
            {
                Obj.Output_AccountKey = Obj.Input_AccountKey;
            }
            if (string.IsNullOrEmpty(Obj.Output_Container))
            {
                Obj.Output_Container = Obj.Input_Container;
            }
            if (string.IsNullOrEmpty(Obj.Output_Blob))
            {
                Obj.Output_Blob = "output_" + Obj.Input_Blob;
            }

            BatchScoreStatus result = await BatchExecutionService.InvokeBatchExecutionService(Obj);

            HttpResponseMessage response = Request.CreateResponse <BatchScoreStatus>(HttpStatusCode.Accepted, result);

            response.Headers.Location = new Uri(string.Format("https://" + Request.RequestUri.Authority + "/api/CheckStatus?url={0}&api={1}", WebUtility.UrlEncode(result.JobLocation), WebUtility.UrlEncode(API_KEY)));
            response.Headers.Add("Retry-after", "30");

            return(response);
        }
        private async Task <HttpResponseMessage> InvokeBatchExecutionService(string url, string api)
        {
            var response = new HttpResponseMessage();

            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", api);
                    //Task<string> response = null;
                    //response = client.GetStringAsync(url);

                    BatchScoreStatus status = new BatchScoreStatus();
                    response = await client.GetAsync(url);

                    if (!response.IsSuccessStatusCode)
                    {
                        response.StatusCode = HttpStatusCode.NotFound;
                        return(response);
                    }

                    status = await response.Content.ReadAsAsync <BatchScoreStatus>();


                    if (status.StatusCode == BatchScoreStatusCode.NotStarted || status.StatusCode == BatchScoreStatusCode.Running)
                    {
                        response.StatusCode       = HttpStatusCode.Accepted;
                        response.Headers.Location = new Uri(Request.RequestUri.AbsoluteUri);    // Set location same with last time.
                        response.Headers.Add("Retry-after", "30");
                    }

                    else if (status.StatusCode == BatchScoreStatusCode.Failed || status.StatusCode == BatchScoreStatusCode.Cancelled)
                    {
                        response.StatusCode = HttpStatusCode.InternalServerError;
                    }


                    else if (status.StatusCode == BatchScoreStatusCode.Finished)
                    {
                        status.SetAdditionInformation();
                        response = Request.CreateResponse <BatchScoreStatus>(HttpStatusCode.OK, status);
                    }

                    return(response);
                }
            }
            catch (Exception ex)
            {
                response.StatusCode   = HttpStatusCode.InternalServerError;
                response.ReasonPhrase = ex.Message;
                return(response);
            }
        }
        private async Task<HttpResponseMessage> InvokeBatchExecutionService(string url, string api)
        {
            var response = new HttpResponseMessage();
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", api);
                    //Task<string> response = null;
                    //response = client.GetStringAsync(url);

                    BatchScoreStatus status = new BatchScoreStatus();
                    response = await client.GetAsync(url);

                    if (!response.IsSuccessStatusCode)
                    {
                        response.StatusCode = HttpStatusCode.NotFound;
                        return response;
                    }

                    status = await response.Content.ReadAsAsync<BatchScoreStatus>();


                    if (status.StatusCode == BatchScoreStatusCode.NotStarted || status.StatusCode == BatchScoreStatusCode.Running)
                    {
                        response.StatusCode = HttpStatusCode.Accepted;
                        response.Headers.Location = new Uri(Request.RequestUri.AbsoluteUri);    // Set location same with last time.
                        response.Headers.Add("Retry-after", "30");
                    }

                    else if (status.StatusCode == BatchScoreStatusCode.Failed || status.StatusCode == BatchScoreStatusCode.Cancelled)
                    {
                        response.StatusCode = HttpStatusCode.InternalServerError;
                    }

                    
                    else if (status.StatusCode == BatchScoreStatusCode.Finished)
                    {
                        status.SetAdditionInformation();
                        response = Request.CreateResponse<BatchScoreStatus>(HttpStatusCode.OK, status);
                    }                    

                    return response;
                }
            }
            catch (Exception ex)
            {
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.ReasonPhrase = ex.Message;
                return response;
            }
        }
        public static async Task <BatchScoreStatus> InvokeBatchExecutionService(BES_Obj besobj)
        {
            // set a time out for polling status
            //const int TimeOutInMilliseconds = 120 * 10000; // Set a timeout of 20 minutes
            BatchScoreStatus status  = new BatchScoreStatus();
            string           BaseUrl = besobj.GetAPIURL();

            string strApiVersion = besobj.GetApiVersion();

            if (!strApiVersion.Contains("api-version=2.0"))
            {
                status.StatusCode = 0;
                status.Details    = "Invalid API version. Please check your Post URL is from version 2.0 of the API help page.";
                status.SetAdditionInformation();
                return(status);
            }

            BaseUrl = BaseUrl.Substring(0, BaseUrl.LastIndexOf("/jobs") + 5);   // Correct BaseUrl don't have api-version
            string apiKey = besobj.GetAPIKey();


            using (HttpClient client = new HttpClient())
            {
                var request = new BatchExecutionRequest()
                {
                    Input            = besobj.GenerateInput(),
                    Outputs          = besobj.GenerateOutputs(),
                    GlobalParameters = besobj.GenerateGlobalParameters()
                };

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);


                //Submitting the job...
                // submit the job
                var response = await client.PostAsJsonAsync(BaseUrl + "?" + strApiVersion, request);

                if (!response.IsSuccessStatusCode)
                {
                    status.StatusCode = 0;
                    status.Details    = response.ReasonPhrase + ". Job submission encountered error. Please check input.";
                    status.SetAdditionInformation();
                    return(status);
                }

                string jobId = await response.Content.ReadAsAsync <string>();

                Console.WriteLine(string.Format("Job ID: {0}", jobId));

                response = await client.PostAsync(BaseUrl + "/" + jobId + "/start?" + strApiVersion, null);

                string jobLocation = BaseUrl + "/" + jobId + "?" + strApiVersion;
                status.JobLocation = jobLocation;
                return(status);


                // start the job
                //Starting the job...
                //response = await client.PostAsync(BaseUrl + "/" + jobId + "/start?" + strApiVersion, null);
                //if (!response.IsSuccessStatusCode)
                //{
                //    status.StatusCode = 0;
                //    status.Details = response.ReasonPhrase + ". Cannot get status of Job Id " + jobId;
                //    status.SetAdditionInformation();
                //    return null;
                //}

                //string jobLocation = BaseUrl + "/" + jobId + "?" + strApiVersion;
                //Stopwatch watch = Stopwatch.StartNew();
                //bool done = false;
                //while (!done)

                //{
                //    //Checking the job status...
                //    response = await client.GetAsync(jobLocation);
                //    if (!response.IsSuccessStatusCode)
                //    {

                //        return null;
                //    }

                //    status = await response.Content.ReadAsAsync<BatchScoreStatus>();
                //    if (watch.ElapsedMilliseconds > TimeOutInMilliseconds)
                //    {
                //        done = true;
                //        await client.DeleteAsync(jobLocation);
                //    }
                //    switch (status.StatusCode)
                //    {
                //        case BatchScoreStatusCode.NotStarted:
                //            break;
                //        case BatchScoreStatusCode.Running:
                //            break;
                //        case BatchScoreStatusCode.Failed:
                //            done = true;
                //            break;
                //        case BatchScoreStatusCode.Cancelled:
                //            done = true;
                //            break;
                //        case BatchScoreStatusCode.Finished:
                //            done = true;
                //            break;
                //    }

                //    if (!done)
                //    {
                //        Thread.Sleep(1000); // Wait one second
                //    }
                //}

                //status.SetAdditionInformation();
                //return status;
            }
        }
        public static async Task<BatchScoreStatus> InvokeBatchExecutionService(BES_Obj besobj)
        {
            

            // set a time out for polling status
            //const int TimeOutInMilliseconds = 120 * 10000; // Set a timeout of 20 minutes
            BatchScoreStatus status = new BatchScoreStatus();
            string BaseUrl = besobj.GetAPIURL();

            string strApiVersion = besobj.GetApiVersion();
            if(!strApiVersion.Contains("api-version=2.0"))
            {
                status.StatusCode = 0;
                status.Details = "Invalid API version. Please check your Post URL is from version 2.0 of the API help page.";
                status.SetAdditionInformation();
                return status;
            }

            BaseUrl = BaseUrl.Substring(0, BaseUrl.LastIndexOf("/jobs") + 5);   // Correct BaseUrl don't have api-version
            string apiKey = besobj.GetAPIKey();

            
            using (HttpClient client = new HttpClient())
            {
                var request = new BatchExecutionRequest()
                {
                    Input = besobj.GenerateInput(),
                    Outputs = besobj.GenerateOutputs(),
                    GlobalParameters = besobj.GenerateGlobalParameters()                    
                };

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);


                //Submitting the job...
                // submit the job
                var response = await client.PostAsJsonAsync(BaseUrl + "?" + strApiVersion, request);
                if (!response.IsSuccessStatusCode)
                {
                    status.StatusCode = 0;
                    status.Details = response.ReasonPhrase + ". Job submission encountered error. Please check input.";
                    status.SetAdditionInformation();
                    return status;
                }

                string jobId = await response.Content.ReadAsAsync<string>();
                Console.WriteLine(string.Format("Job ID: {0}", jobId));

                response = await client.PostAsync(BaseUrl + "/" + jobId + "/start?" + strApiVersion, null);

                string jobLocation = BaseUrl + "/" + jobId + "?" + strApiVersion;
                status.JobLocation = jobLocation;
                return status;


                // start the job
                //Starting the job...
                //response = await client.PostAsync(BaseUrl + "/" + jobId + "/start?" + strApiVersion, null);
                //if (!response.IsSuccessStatusCode)
                //{
                //    status.StatusCode = 0;
                //    status.Details = response.ReasonPhrase + ". Cannot get status of Job Id " + jobId;
                //    status.SetAdditionInformation();
                //    return null;
                //}

                //string jobLocation = BaseUrl + "/" + jobId + "?" + strApiVersion;
                //Stopwatch watch = Stopwatch.StartNew();
                //bool done = false;                
                //while (!done)

                //{
                //    //Checking the job status...
                //    response = await client.GetAsync(jobLocation);
                //    if (!response.IsSuccessStatusCode)
                //    {   
                        
                //        return null;
                //    }

                //    status = await response.Content.ReadAsAsync<BatchScoreStatus>();
                //    if (watch.ElapsedMilliseconds > TimeOutInMilliseconds)
                //    {
                //        done = true;
                //        await client.DeleteAsync(jobLocation);
                //    }
                //    switch (status.StatusCode)
                //    {
                //        case BatchScoreStatusCode.NotStarted:
                //            break;
                //        case BatchScoreStatusCode.Running:
                //            break;
                //        case BatchScoreStatusCode.Failed:
                //            done = true;
                //            break;
                //        case BatchScoreStatusCode.Cancelled:
                //            done = true;
                //            break;
                //        case BatchScoreStatusCode.Finished:
                //            done = true;
                //            break;
                //    }

                //    if (!done)
                //    {
                //        Thread.Sleep(1000); // Wait one second
                //    }
                //}

                //status.SetAdditionInformation();
                //return status;
            }

        }