简体   繁体   中英

C# Make HttpWebResponse wait until response has been received instead of receiving HTTP 400 Error

I am trying to access Adobe's Datawarehouse reporting using their API. The way it works is by first forming the JSON using the metrics available and the dimensions you want it to be brojen down by. That all works fine. However where I do have the issue comes down to this. Whenever I request more than 3 to 4 dimensions, the report takes longer to generate. I would need the HttpWebResponse to wait until it has been completed before moving to the next line. Below is my sample code that I have built based on an example from github.

class Program 
{

    protected static string JSONFolder = System.Configuration.ConfigurationManager.AppSettings["JSONFolder"];
    protected static string USERNAME = System.Configuration.ConfigurationManager.AppSettings["Username"];
    protected static string SECRET = System.Configuration.ConfigurationManager.AppSettings["Secret"];
    protected static string ReportSuiteID = System.Configuration.ConfigurationManager.AppSettings["ReportSuiteID"];
    private static string ENDPOINT = "https://api5.omniture.com/admin/1.4/rest/";
    protected static string environment = "dev"; 

    static void Main(string[] args)
    {
        DateTime previousDay = DateTime.Today.AddDays(-1);
        string json = RequestJsonBuilder(previousDay, previousDay, ReportSuiteID);
        string response = callMethod("Report.Queue", json, 15);

        var jss = new JavaScriptSerializer();
        var requestDetails = jss.Deserialize<Dictionary<string, string>>(response);
    }

    /*Build the json for the methods Report.GetStatus and Report.Get*/
    public static string RequestJsonBuilderStatus(string id)
    {
        ReportID json = new ReportID() { reportID = id };

        var serializer = new JavaScriptSerializer();
        var serializedResult = serializer.Serialize(json);
        return serializedResult;
    }

    /*Build the json for the method Report.Queue*/
    static string RequestJsonBuilder(DateTime StartDate, DateTime EndDate, string ReportSuiteID)
    {
        //Build the list of metrics to send with the request
        var listMetrics = new List<Metrics>();
        listMetrics.Add(new Metrics() { id = "visits" });


        //Build the list of elements to send with the request
        var listElements = new List<Elements>();
        listElements.Add(new Elements() { id = "page" , top = "25"});

        var serializer2 = new JavaScriptSerializer();
        Dictionary<string, RankedRequest> dic = new Dictionary<string, RankedRequest>();
        dic.Add("reportDescription", new RankedRequest()
        {
            reportSuiteID = ReportSuiteID,
            dateFrom = StartDate.ToString("yyyy-MM-dd"),
            dateTo = EndDate.ToString("yyyy-MM-dd"),
            metrics = listMetrics,
            elements = listElements,
            source = "warehouse"

        });
        var serializedResult2 = serializer2.Serialize(dic);
        return serializedResult2;
    }

    /*Build the rest call to the Adobe Analytics REST APII 1.4*/
    public static String callMethod(String method, String data, int secs)
    {
        Program prog = new Program();
        HttpWebResponse statusResponse = null;
        string responseXml = "";
        StringBuilder sbUrl = new StringBuilder(ENDPOINT + "?method=" + method);
        HttpWebRequest omniRequest = (HttpWebRequest)WebRequest.Create(sbUrl.ToString());
        string timecreated = generateTimestamp();
        string nonce = generateNonce();
        string digest = getBase64Digest(nonce + timecreated + SECRET);
        nonce = base64Encode(nonce);
        omniRequest.Headers.Add("X-WSSE: UsernameToken Username=\"" + USERNAME + "\", PasswordDigest=\"" + digest + "\", Nonce=\"" + nonce + "\", Created=\"" + timecreated + "\"");
        omniRequest.Method = "POST";
        omniRequest.ContentType = "text/json";

        //Write the json details to the request
        using (var streamWriter = new StreamWriter(omniRequest.GetRequestStream()))
        {
            string json = data;
            Console.WriteLine("\n 2.0 ############## Json request : \n\n " + json + "\n\n");
            streamWriter.Write(json);
        }

        //Get the response of the request
        try
        {
            Console.WriteLine("\n 2.0 ############## Sleeping thread for " + secs + "\n");

            using (HttpWebResponse statusResponse = (HttpWebResponse) omniRequest.GetResponse())
            {
                using (Stream receiveStream = statusResponse.GetResponseStream())
                {
                    using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
                    {
                        responseXml = readStream.ReadToEnd();
                        return responseXml;
                    }
                }
            }
        }
        catch (Exception ex) { throw ex; }
    }

    // other methods defined below
    // private static string getBase64Digest(string input)
    // private static string generateNonce()
    // public static string base64Encode(string data)
    // etc.
}

How do I make HttpWebResponse wait until a HTTP 200 response is actually received. This might take minutes to sometimes an hour depending on the number of metrics and dimensions I add.

Things I have tried also include changing line 88 to something like this:

How to process WebResponse when .NET throws WebException ((400) Bad Request)?

how to wait until a web request with HttpWebRequest is finished?

Sincerely appreciate all help here.

Thanks

Did you try setting the timeout? I was looking recently for the similar question and found that one:

HttpWebRequest.GetResponse() keeps getting timed out

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM