Попытка POST через .NET REST API

Итак, я пишу приложение C#.NET, которое должно иметь возможность считывать исторические данные из Rally. В частности, мне нужно получить общую оценку плана для данного выпуска для каждого из первых 7 дней выпуска.

Я читал, что есть два основных способа сделать это; через историю изменений или через Lookback API и с помощью POST. Я решил, что LBAPI будет чище и надежнее, поэтому я пошел по этому пути. К сожалению, я никогда раньше не работал с POST, поэтому не совсем уверен, что делаю.

Вот что я придумал до сих пор. Я чувствую, что либо близок и упускаю что-то ослепительно очевидное, либо я совершенно не в себе:

string uri = @"https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/14457696030/artifact/snapshot/query.js";

DynamicJsonObject data = new DynamicJsonObject();
data["find"] = new DynamicJsonObject();
data["find"]["_ProjectHierarchy"] = 14457702297;
data["find"]["_TypeHierarchy"] = "HierarchicalRequirement";
data["find"]["Children"] = null;
data["find"]["__At"] = "2014-02-02T00Z%22";
data["fields"] = new string[] { "PlanEstimate", "ObjectID", "Name" };

DynamicJsonObject results = API.post(uri, data);

Когда я использую скомпилированный URL-адрес в веб-браузере, я получаю правильные данные:

https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/14457696030/artifact/snapshot/query.js?find={%22_ProjectHierarchy%22:14457702297,%22_TypeHierarchy%22:%22HierarchicalRequirement%22,%22Children%22:null,%22__At%22:%222014-02-02T00Z%22}&fields=[%22ObjectID%22,%22Name%22,%22PlanEstimate%22]&start=0

Когда я использую приведенный выше код С# и вызываю:

DynamicJsonObject results = API.post(uri, data);

Я получаю сообщение WebException: "Удаленный сервер вернул ошибку: (405) Метод не разрешен." что звучит почти так, как будто я даже не могу использовать этот метод публикации с самого начала.

Мы будем очень признательны за любые рекомендации.


person Andrew McGrath    schedule 02.04.2014    source источник
comment
Как подключиться к ралли? У вас есть прокси-сервер? Возможно, ответ 405 исходит не от Rally, а от вышестоящего прокси-сервера. LBAPI поддерживает либо GET, либо POST.   -  person    schedule 02.04.2014
comment
Эй, Марк, это через мою корпоративную сеть, которая, я полагаю, использует какой-то прокси? Сейчас я смотрю, правильно ли настроены IIS и Visual Studio. Есть ли способ попробовать использовать GET в REST API? Я вижу только метод для POST. Спасибо.   -  person Andrew McGrath    schedule 02.04.2014
comment
Каков ваш объект API в этом случае? Я предполагал, что это .NET WebClient. Обратите внимание, что .NET REST DLL от Rally еще не поддерживает Lookback API.   -  person    schedule 02.04.2014
comment
Я пытался использовать .NET REST DLL. Я предположил, что это было по крайней мере возможно, поскольку метод post был доступен. Переключившись на использование System.Net.WebRequest и выяснив, как прикрепить учетные данные, я, наконец, смог заставить его работать. Спасибо за вашу помощь @MarkW   -  person Andrew McGrath    schedule 02.04.2014


Ответы (1)


На случай, если кто-то еще захочет сделать что-то подобное, это было мое решение, следуя указаниям Марка (возможно, можно сделать чище, но это работает для меня):

    private static DynamicJsonObject getBaseline(string day, long projectID, long ReleaseID)
    {
        int pageSize = 200;
        string uri = @"https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/14457696030/artifact/snapshot/query.js?find={%22_ProjectHierarchy%22:" + 
                     projectID + @",%22_TypeHierarchy%22:%22HierarchicalRequirement%22,%22Release%22:{$in:[" + ReleaseID + @"]},%22Children%22:null,%22__At%22:%22" + 
                     day + @"T00Z%22}&fields=[%22PlanEstimate%22,%22ScheduleState%22]&hydrate=[%22ScheduleState%22]&start=0&pagesize=" + pageSize;

        DynamicJsonObject response = HttpGet(uri);
        DynamicJsonObject points = new DynamicJsonObject();

        foreach (var story in response["Results"])
        {
            // Do whatever
        }
        return points;
    }

    public static DynamicJsonObject HttpGet(string URI)
    {
        System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
        req.Credentials = GetCredential();
        req.PreAuthenticate = true;
        req.ContentType = "application/json";
        System.Net.WebResponse resp = req.GetResponse();
        System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());

        DynamicJsonObject result = new DynamicJsonSerializer().Deserialize(sr.ReadToEnd());
        // Not sure if all of these are necessary
        sr.Close(); sr.Dispose();
        resp.Close();
        sr.Close(); sr.Dispose();
        return result;
    }

    private static CredentialCache GetCredential()
    {
        if (credentialCache == null)
        {
            string url = @"https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/14457696030/artifact/snapshot/query.js?";
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
            credentialCache = new CredentialCache();
            String user = ConfigurationManager.AppSettings["user"];
            String password = ConfigurationManager.AppSettings["password"];
            credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(user, password));
        }
        return credentialCache;
    }
person Andrew McGrath    schedule 16.04.2014