Как отправить предварительный запрос перед каждым запросом в Windows Phone 7

Я хочу отправить один предварительный запрос на мой сервер перед отправкой каждого запроса. Из этого предварительного запроса я получу токен с моего сервера, а затем мне нужно будет добавить этот токен во все запросы. Это процесс.

Я попробовал некоторые методы для достижения этого. Но я сталкиваюсь с одной проблемой. То есть, когда я пытаюсь отправить предварительный запрос, он обрабатывается с текущим запросом. Это означает, что оба запроса идут параллельно.

Я хочу сначала отправить предварительный запрос и проанализировать ответ. Только после анализа ответа на предварительный запрос я хочу отправить этот другой запрос. Но первый запрос не ожидает ответа на предварительный запрос. Пожалуйста, позвольте мне отправить предварительный запрос перед всеми запросами.

Это мой код:

Модель представления:

`public class ListExampleViewModel
    {
        SecurityToken sToken = null;
        public ListExampleViewModel()
        {
            GlobalConstants.isGetToken = true;
            var listResults = REQ_RESP.postAndGetResponse((new ListService().GetList("xx","xxx")));

            listResults.Subscribe(x =>
            {
                Console.WriteLine("\n\n..................................2");
                Console.WriteLine("Received Response==>" + x);
            });
        }
    }`

Константный класс для запроса и ответа:

`public class REQ_RESP
    {
        private static string receivedAction = "";
        private static string receivedPostDate = "";


        public static IObservable<string> postAndGetResponse(String postData)
        {
            if (GlobalConstants.isGetToken)
            {
    //Pre Request for every reusest               
                receivedPostDate = postData;
                GlobalConstants.isGetToken = false;
                getServerTokenMethod();
                postData = receivedPostDate;
            }

            HttpWebRequest serviceRequest =
            (HttpWebRequest)WebRequest.Create(new Uri(Constants.SERVICE_URI));


            var fetchRequestStream =
                 Observable.FromAsyncPattern<Stream>(serviceRequest.BeginGetRequestStream,
                                                                 serviceRequest.EndGetRequestStream);
            var fetchResponse =
                Observable.FromAsyncPattern<WebResponse>(serviceRequest.BeginGetResponse,
                                                            serviceRequest.EndGetResponse);

            Func<Stream, IObservable<HttpWebResponse>> postDataAndFetchResponse = st =>
            {
                using (var writer = new StreamWriter(st) as StreamWriter)
                {
                    writer.Write(postData);
                    writer.Close();
                }
                return fetchResponse().Select(rp => (HttpWebResponse)rp);
            };

            Func<HttpWebResponse, IObservable<string>> fetchResult = rp =>
            {
                if (rp.StatusCode == HttpStatusCode.OK)
                {

                    using (var reader = new StreamReader(rp.GetResponseStream()))
                    {
                        string result = reader.ReadToEnd();
                        reader.Close();
                        rp.GetResponseStream().Close();
                        XDocument xdoc = XDocument.Parse(result);
                        Console.WriteLine(xdoc);
                        return Observable.Return<string>(result);
                    }
                }
                else
                {
                    var msg = "HttpStatusCode == " + rp.StatusCode.ToString();
                    var ex = new System.Net.WebException(msg,
                        WebExceptionStatus.ReceiveFailure);
                    return Observable.Throw<string>(ex);
                }

            };

            return
                from st in fetchRequestStream()
                from rp in postDataAndFetchResponse(st)
                from str in fetchResult(rp)
                select str;
        }

        public static void getServerTokenMethod()
        {
            SecurityToken token = new SecurityToken();

            var getTokenResults = REQ_RESP.postAndGetResponse((new ServerToken().GetServerToken()));

            getTokenResults.Subscribe(x =>
            {
                ServerToken serverToken = new ServerToken();
                ServiceModel sm = new ServiceModel();
    //Parsing Response
                serverToken = extract(x, sm);
                if (!(string.IsNullOrEmpty(sm.NetErrorCode)))
                {
        MessageBox.Show("Show Error Message");
                }
                else
                {
                    Console.WriteLine("\n\n..................................1");
                    Console.WriteLine("\n\nserverToken.token==>" + serverToken.token);
                    Console.WriteLine("\n\nserverToken.pk==>" + serverToken.pk);                   
                }
            },
            ex =>
            {
                MessageBox.Show("Exception = " + ex.Message);
            },
            () =>
            {
                Console.WriteLine("End of Process.. Releaseing all Resources used.");
            });
        }
    }`

person Vijay    schedule 28.02.2015    source источник


Ответы (1)


Вот пара вариантов:

Вы можете заменить модель Reactive Extensions более простой моделью async/await для веб-запросов, используя HttpClient (вам также потребуется Microsoft.Bcl.Async в РП7). С HttpClient ваш код будет выглядеть так:

Запрос и ответ:

        public static async Task<string> postAndGetResponse(String postData)
    {
        if (GlobalConstants.isGetToken)
        {
            //Pre Request for every reusest               
            await getServerTokenMethod();
        }

        var client = new HttpClient();
        var postMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(Constants.SERVICE_URI));
        var postResult = await client.SendAsync(postMessage);

        var stringResult = await postResult.Content.ReadAsStringAsync();

        return stringResult;
    }

Модель представления:

    public class ListExampleViewModel
{
    SecurityToken sToken = null;
    public ListExampleViewModel()
    {
        GetData();
    }

    public async void GetData()
    {
        GlobalConstants.isGetToken = true;
        var listResults = await REQ_RESP.postAndGetResponse("postData");
    }
}

Другой вариант, если вы хотите продолжать использовать Reactive Extensions, посмотреть на метод RX Concat. С его помощью вы можете связать запрос токена и фактический веб-запрос: https://stackoverflow.com/a/6754558/66988

person Mikael Koskinen    schedule 28.02.2015
comment
Привет, я пытаюсь следовать вашему первому варианту. Но я не могу этого сделать. Я столкнулся с некоторой ошибкой. The type or namespace name 'async' could not be found (are you missing a using directive or an assembly reference?). Я ищу решение для этой ошибки. И я нашел один ответ [Из этой ссылки].(stackoverflow.com/questions/16557032/). Я делаю вывод, что это невозможно. Сейчас пробую ваш второй вариант. Но я не знаю, где я должен добавить эти методы. Если возможно, пожалуйста, дайте мне любой способ решить мою проблему. - person Vijay; 28.02.2015
comment
Привет @ Микаэль Коскинен .. Наконец-то я нашел решение. Я использовал o1().SelectMany(_ =› o2()).Subscribe(); для своего решения и внес некоторые изменения в свой код. Теперь я могу отправить предварительный запрос..!! Большое вам спасибо.. - person Vijay; 02.03.2015