зеркало из https://github.com/microsoft/winsdkfb.git
Коммит
cfa49c33a7
|
@ -210,14 +210,14 @@
|
|||
<ItemGroup>
|
||||
<PRIResource Include="Resources.resw" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\winsdkfb\winsdkfb_testing_key.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\winsdkfb\winsdkfb_uwp\winsdkfb_uwp\winsdkfb_uwp.vcxproj">
|
||||
<Project>{973a943b-ff77-4267-8f30-f5fe2b7f5583}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\winsdkfb\winsdkfb_testing_key.pfx" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
|
@ -34,7 +34,6 @@
|
|||
<ClCompile Include="FBPageBindable.cpp" />
|
||||
<ClCompile Include="UserInfo.xaml.cpp" />
|
||||
<ClCompile Include="UserLikes.xaml.cpp" />
|
||||
<ClCompile Include="OptionsPage.xaml.cpp" />
|
||||
<ClCompile Include="Dialogs.xaml.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -47,7 +46,6 @@
|
|||
<ClInclude Include="FBPageBindable.h" />
|
||||
<ClInclude Include="UserInfo.xaml.h" />
|
||||
<ClInclude Include="UserLikes.xaml.h" />
|
||||
<ClInclude Include="OptionsPage.xaml.h" />
|
||||
<ClInclude Include="Dialogs.xaml.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -114,13 +114,18 @@
|
|||
<None Include="..\winsdkfb_testing_key.pfx">
|
||||
<Link>winsdkfb_testing_key.pfx</Link>
|
||||
</None>
|
||||
<None Include="data.json" />
|
||||
<None Include="FBCSObjectImplementation.ttinclude" />
|
||||
<None Include="FBPhoto.tt" />
|
||||
<None Include="FBObject.tt" />
|
||||
<None Include="FBSuccess.tt" />
|
||||
<None Include="FBTestUser.tt" />
|
||||
<None Include="packages.config" />
|
||||
<Content Include="TestData\testJsonPropertySet.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\testJsonPropertySetNoBuiltInFields.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Utility.ttinclude" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace FBWinStoreCsTests
|
|||
{
|
||||
public String ResponseData;
|
||||
|
||||
public IAsyncOperation<string> DeleteTaskAsync(string path, PropertySet parameters)
|
||||
public IAsyncOperation<string> DeleteTaskAsync(string path, IReadOnlyDictionary<String, Object> parameters)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace FBWinStoreCsTests
|
|||
}).AsAsyncOperation<string>();
|
||||
}
|
||||
|
||||
public IAsyncOperation<string> GetTaskAsync(string path, PropertySet parameters)
|
||||
public IAsyncOperation<string> GetTaskAsync(string path, IReadOnlyDictionary<String, Object> parameters)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
|
@ -45,12 +45,12 @@ namespace FBWinStoreCsTests
|
|||
}).AsAsyncOperation<string>();
|
||||
}
|
||||
|
||||
public string ParametersToQueryString(PropertySet Parameters)
|
||||
public string ParametersToQueryString(IReadOnlyDictionary<String, Object> Parameters)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IAsyncOperation<string> PostTaskAsync(string path, PropertySet parameters)
|
||||
public IAsyncOperation<string> PostTaskAsync(string path, IReadOnlyDictionary<String, Object> parameters)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "test_user",
|
||||
"test_boolean": false,
|
||||
"test_num": 4,
|
||||
"test_string": "hello_world",
|
||||
"test_array": [ 2, 3, 5, 7, 11 ],
|
||||
"test_object": {
|
||||
"a": "b",
|
||||
"c": "d"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"test_boolean": false,
|
||||
"test_num": 4,
|
||||
"test_string": "hello_world",
|
||||
"test_array": [ 2, 3, 5, 7, 11 ],
|
||||
"test_object": {
|
||||
"a": "b",
|
||||
"c": "d"
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
//******************************************************************************
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -700,5 +701,49 @@ namespace FBWinStoreCsTests
|
|||
Assert.IsFalse(likes.HasPrevious);
|
||||
// test with next but no previous
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task testJsonPropertySet()
|
||||
{
|
||||
|
||||
StorageFolder installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
StorageFolder jsonFolder = await installedLocation.GetFolderAsync("TestData");
|
||||
StorageFile jsonTestFile = await jsonFolder.GetFileAsync("testJsonPropertySet.json");
|
||||
string text = await FileIO.ReadTextAsync(jsonTestFile);
|
||||
|
||||
FBUser testUser = (FBUser)FBUser.FromJson(text);
|
||||
// member variable
|
||||
Assert.AreEqual(testUser.Name, "test_user");
|
||||
Assert.IsFalse(testUser.Fields.ContainsKey("name"));
|
||||
// boolean field
|
||||
Assert.IsTrue(testUser.Fields.ContainsKey("test_boolean"));
|
||||
Assert.AreEqual(testUser.Fields["test_boolean"], "false");
|
||||
// num field
|
||||
Assert.IsTrue(testUser.Fields.ContainsKey("test_num"));
|
||||
Assert.AreEqual(testUser.Fields["test_num"], "4");
|
||||
// string field
|
||||
Assert.IsTrue(testUser.Fields.ContainsKey("test_string"));
|
||||
Assert.AreEqual(testUser.Fields["test_string"], "hello_world");
|
||||
// array field
|
||||
Assert.IsTrue(testUser.Fields.ContainsKey("test_array"));
|
||||
Assert.AreEqual(testUser.Fields["test_array"], "[2,3,5,7,11]");
|
||||
// object field
|
||||
Assert.IsTrue(testUser.Fields.ContainsKey("test_object"));
|
||||
Assert.AreEqual(testUser.Fields["test_object"], @"{""a"":""b"",""c"":""d""}");
|
||||
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task testJsonPropertySetNoBuiltInFields()
|
||||
{
|
||||
StorageFolder installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
StorageFolder jsonFolder = await installedLocation.GetFolderAsync("TestData");
|
||||
StorageFile jsonTestFile = await jsonFolder.GetFileAsync("testJsonPropertySetNoBuiltInFields.json");
|
||||
string text = await FileIO.ReadTextAsync(jsonTestFile);
|
||||
|
||||
FBUser testUser = (FBUser)FBUser.FromJson(text);
|
||||
Assert.AreNotEqual(testUser, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,10 @@ namespace winsdkfb
|
|||
Platform::String^ JsonText
|
||||
);
|
||||
|
||||
property Windows::Foundation::Collections::PropertySet^ Fields
|
||||
{
|
||||
Windows::Foundation::Collections::PropertySet^ get();
|
||||
}
|
||||
<#
|
||||
|
||||
foreach (XmlNode child in rootNode.SelectNodes("property"))
|
||||
|
@ -129,6 +133,7 @@ namespace winsdkfb
|
|||
<#
|
||||
}
|
||||
#>
|
||||
Windows::Foundation::Collections::PropertySet^ _fields;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ using namespace winsdkfb::Graph;
|
|||
using namespace Platform;
|
||||
using namespace Windows::Data::Json;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
<#
|
||||
<#
|
||||
if (bindable)
|
||||
{
|
||||
#>
|
||||
|
@ -86,9 +86,13 @@ using namespace Windows::UI::Xaml::Data;
|
|||
}
|
||||
#>
|
||||
{
|
||||
;
|
||||
_fields = ref new PropertySet();
|
||||
}
|
||||
|
||||
PropertySet^ <#= className #>::Fields::get()
|
||||
{
|
||||
return _fields;
|
||||
}
|
||||
<#
|
||||
for (int i = 0; i < props.Count; i++)
|
||||
{
|
||||
|
@ -118,7 +122,7 @@ void <#= className #>::<#= propName #>::set(<#= rtType #> value)
|
|||
}
|
||||
#>
|
||||
Object^ <#= className #>::FromJson(
|
||||
String^ JsonText
|
||||
String^ JsonText
|
||||
)
|
||||
{
|
||||
<#= className #>^ result = ref new <#= className #>;
|
||||
|
@ -178,11 +182,38 @@ Object^ <#= className #>::FromJson(
|
|||
<#
|
||||
}
|
||||
#>
|
||||
else
|
||||
{
|
||||
String^ value = nullptr;
|
||||
|
||||
switch (it->Current->Value->ValueType)
|
||||
{
|
||||
case JsonValueType::Boolean:
|
||||
value = it->Current->Value->GetBoolean().ToString();
|
||||
break;
|
||||
case JsonValueType::Number:
|
||||
value = it->Current->Value->GetNumber().ToString();
|
||||
break;
|
||||
case JsonValueType::String:
|
||||
value = it->Current->Value->GetString();
|
||||
break;
|
||||
case JsonValueType::Array:
|
||||
case JsonValueType::Object:
|
||||
value = it->Current->Value->Stringify();
|
||||
break;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
result->_fields->Insert(key, value);
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// No field names matched any known properties for this class.
|
||||
// No field names matched any known properties for this class.
|
||||
// Even if it *is* an object of our type, it's not useful.
|
||||
result = nullptr;
|
||||
}
|
||||
|
@ -190,7 +221,7 @@ Object^ <#= className #>::FromJson(
|
|||
}
|
||||
return result;
|
||||
}
|
||||
<#
|
||||
<#
|
||||
if (bindable)
|
||||
{
|
||||
#>
|
||||
|
@ -200,7 +231,7 @@ void <#= className #>::NotifyPropertyChanged(
|
|||
)
|
||||
{
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this, prop]()
|
||||
{
|
||||
PropertyChangedEventArgs^ args = ref new PropertyChangedEventArgs(prop);
|
||||
|
|
|
@ -146,13 +146,13 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBSingleValue::MakeHttpRequest(
|
|||
switch (httpMethod)
|
||||
{
|
||||
case HttpMethod::Get:
|
||||
innerTask = create_task(HttpManager::Instance->GetTaskAsync(_request, _parameters));
|
||||
innerTask = create_task(HttpManager::Instance->GetTaskAsync(_request, _parameters->GetView()));
|
||||
break;
|
||||
case HttpMethod::Post:
|
||||
innerTask = create_task(HttpManager::Instance->PostTaskAsync(_request, _parameters));
|
||||
innerTask = create_task(HttpManager::Instance->PostTaskAsync(_request, _parameters->GetView()));
|
||||
break;
|
||||
case HttpMethod::Delete:
|
||||
innerTask = create_task(HttpManager::Instance->DeleteTaskAsync(_request, _parameters));
|
||||
innerTask = create_task(HttpManager::Instance->DeleteTaskAsync(_request, _parameters->GetView()));
|
||||
break;
|
||||
default:
|
||||
OutputDebugString(L"FBSingleValue::MakeHttpRequest recieved unknown HttpMethod value\n");
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "HttpMethod.h"
|
||||
#include "JsonClassFactory.h"
|
||||
#include "SDKMessage.h"
|
||||
#include "GraphUriBuilder.h"
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Platform;
|
||||
|
@ -96,25 +97,26 @@ PropertySet^ FBClient::ToDictionary(PropertySet^ parameters, PropertySet^ mediaO
|
|||
|
||||
IAsyncOperation<String^>^ FBClient::GetTaskAsync(
|
||||
String^ path,
|
||||
PropertySet^ parameters
|
||||
IMapView<String^, Object^>^ parameters
|
||||
)
|
||||
{
|
||||
PropertySet^ modifiableParams = MapViewToPropertySet(parameters);
|
||||
IAsyncOperation<String^>^ myTask = create_async([=]()
|
||||
{
|
||||
Uri^ uri = FBClient::PrepareRequestUri(HttpMethod::Get, path,
|
||||
parameters, nullptr);
|
||||
modifiableParams);
|
||||
|
||||
return FBClient::GetTaskInternalAsync(uri)
|
||||
.then([=](String^ Response)
|
||||
{
|
||||
task<String^> result;
|
||||
|
||||
if (FBClient::IsOAuthErrorResponse(Response))
|
||||
if (FBClient::IsOAuthErrorResponse(Response))
|
||||
{
|
||||
result = create_task([=]()
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
})
|
||||
.then([=](FBResult^ Result)
|
||||
{
|
||||
|
@ -186,7 +188,7 @@ IAsyncOperation<String^>^ FBClient::SimplePostAsync(
|
|||
return create_async([=]()
|
||||
{
|
||||
Uri^ uri = FBClient::PrepareRequestUri(HttpMethod::Post, path,
|
||||
parameters, nullptr);
|
||||
parameters);
|
||||
|
||||
return FBClient::SimplePostInternalAsync(uri)
|
||||
.then([=](String^ Response)
|
||||
|
@ -198,7 +200,7 @@ IAsyncOperation<String^>^ FBClient::SimplePostAsync(
|
|||
result = create_task([=]()
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
})
|
||||
.then([=](FBResult^ Result)
|
||||
{
|
||||
|
@ -266,7 +268,7 @@ IAsyncOperation<String^>^ FBClient::MultipartPostAsync(
|
|||
return create_async([=]()
|
||||
{
|
||||
Uri^ uri = FBClient::PrepareRequestUri(HttpMethod::Post, path,
|
||||
parameters, nullptr);
|
||||
parameters);
|
||||
|
||||
return FBClient::MultipartPostInternalAsync(uri, streams)
|
||||
.then([=](String^ Response)
|
||||
|
@ -278,7 +280,7 @@ IAsyncOperation<String^>^ FBClient::MultipartPostAsync(
|
|||
result = create_task([=]()
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
})
|
||||
.then([=](FBResult^ Result)
|
||||
{
|
||||
|
@ -318,32 +320,33 @@ task<String^> FBClient::MultipartPostInternalAsync(
|
|||
|
||||
IAsyncOperation<String^>^ FBClient::PostTaskAsync(
|
||||
String^ path,
|
||||
PropertySet^ parameters
|
||||
IMapView<String^, Object^>^ parameters
|
||||
)
|
||||
{
|
||||
PropertySet^ modifiableParams = MapViewToPropertySet(parameters);
|
||||
IAsyncOperation<String^>^ result = nullptr;
|
||||
PropertySet^ streams = GetStreamsToUpload(parameters);
|
||||
PropertySet^ streams = GetStreamsToUpload(modifiableParams);
|
||||
if (streams)
|
||||
{
|
||||
result = FBClient::MultipartPostAsync(path, parameters, streams);
|
||||
result = FBClient::MultipartPostAsync(path, modifiableParams, streams);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FBClient::SimplePostAsync(path, parameters);
|
||||
result = FBClient::SimplePostAsync(path, modifiableParams);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Windows::Foundation::IAsyncOperation<String^>^ FBClient::DeleteTaskAsync(
|
||||
String^ path,
|
||||
PropertySet^ parameters
|
||||
String^ path,
|
||||
IMapView<String^, Object^>^ parameters
|
||||
)
|
||||
{
|
||||
PropertySet^ modifiableParams = MapViewToPropertySet(parameters);
|
||||
return create_async([=]()
|
||||
{
|
||||
Uri^ uri = FBClient::PrepareRequestUri(HttpMethod::Delete, path,
|
||||
parameters, nullptr);
|
||||
modifiableParams);
|
||||
|
||||
return FBClient::DeleteTaskInternalAsync(uri)
|
||||
.then([=](String^ Response)
|
||||
|
@ -355,7 +358,7 @@ Windows::Foundation::IAsyncOperation<String^>^ FBClient::DeleteTaskAsync(
|
|||
result = create_task([=]()
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
return FBSession::ActiveSession->TryRefreshAccessToken();
|
||||
})
|
||||
.then([=](FBResult^ Result)
|
||||
{
|
||||
|
@ -390,34 +393,37 @@ task<String^> FBClient::DeleteTaskInternalAsync(
|
|||
}
|
||||
|
||||
Uri^ FBClient::PrepareRequestUri(
|
||||
winsdkfb::HttpMethod httpMethod,
|
||||
String^ path,
|
||||
PropertySet^ parameters,
|
||||
Windows::Storage::Streams::IRandomAccessStream^ input
|
||||
winsdkfb::HttpMethod httpMethod,
|
||||
String^ path,
|
||||
PropertySet^ parameters
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
GraphUriBuilder^ uriBuilder = ref new GraphUriBuilder(path);
|
||||
|
||||
// Setup datawriter for the InMemoryRandomAccessStream
|
||||
DataWriter^ dataWriter = ref new DataWriter(input);
|
||||
dataWriter->UnicodeEncoding = UnicodeEncoding::Utf8;
|
||||
dataWriter->ByteOrder = ByteOrder::LittleEndian;
|
||||
if (parameters == nullptr)
|
||||
{
|
||||
parameters = ref new PropertySet();
|
||||
}
|
||||
|
||||
PropertySet^ mediaObjects = ref new PropertySet();
|
||||
PropertySet^ mediaStreams = ref new PropertySet();
|
||||
PropertySet^ parametersWithoutMediaObjects = ToDictionary(parameters, mediaObjects, mediaStreams);
|
||||
// ensure that media items are in valid states
|
||||
ValidateMediaStreams(mediaStreams);
|
||||
ValidateMediaObjects(mediaObjects);
|
||||
|
||||
if (parametersWithoutMediaObjects == nullptr)
|
||||
{
|
||||
parametersWithoutMediaObjects = ref new PropertySet();
|
||||
}
|
||||
|
||||
if (!parametersWithoutMediaObjects->HasKey("access_token") &&
|
||||
if (!parametersWithoutMediaObjects->HasKey("access_token") &&
|
||||
(sess->AccessTokenData != nullptr) &&
|
||||
(sess->AccessTokenData->AccessToken->Data() != nullptr) &&
|
||||
(sess->AccessTokenData->AccessToken->Length() > 0))
|
||||
{
|
||||
parametersWithoutMediaObjects->Insert("access_token",
|
||||
parametersWithoutMediaObjects->Insert("access_token",
|
||||
sess->AccessTokenData->AccessToken);
|
||||
}
|
||||
|
||||
|
@ -426,211 +432,71 @@ Uri^ FBClient::PrepareRequestUri(
|
|||
parametersWithoutMediaObjects->Insert("format", "json-strings");
|
||||
}
|
||||
|
||||
String^ contentTypeHeader = MultiPartContentType;
|
||||
String^ boundary = ref new String(MultiPartBoundary);
|
||||
contentTypeHeader += "boundary=" + boundary + MultiPartNewLine;
|
||||
long contentLength = -1;
|
||||
String^ queryString = ref new String();
|
||||
|
||||
OutputDebugString(contentTypeHeader->Data());
|
||||
|
||||
SerializeParameters(parametersWithoutMediaObjects);
|
||||
|
||||
if (parametersWithoutMediaObjects->HasKey("access_token"))
|
||||
// Add remaining parameters to query string. Note that parameters that
|
||||
// do not need to be uploaded as multipart, i.e. any which is are not
|
||||
// binary data, are required to be in the query string, even for POST
|
||||
// requests!
|
||||
auto kvp = parametersWithoutMediaObjects->First();
|
||||
while (kvp->HasCurrent)
|
||||
{
|
||||
// Add access_token to query string as the first parameter, for our own
|
||||
// convenience. We could as easily add it in the while loop below, but
|
||||
// putting at the beginning of the query string is helpful for
|
||||
// debugging, etc.
|
||||
auto accessToken = dynamic_cast<String^>(
|
||||
parametersWithoutMediaObjects->Lookup("access_token"));
|
||||
if ((accessToken != nullptr) && (accessToken->Length() > 0) &&
|
||||
(accessToken != "null"))
|
||||
{
|
||||
queryString += "access_token=" + Uri::EscapeComponent(accessToken);
|
||||
}
|
||||
uriBuilder->AddQueryParam(kvp->Current->Key, static_cast<String^>(kvp->Current->Value));
|
||||
kvp->MoveNext();
|
||||
}
|
||||
|
||||
// Remove the token before we loop through and add general parameters
|
||||
parametersWithoutMediaObjects->Remove("access_token");
|
||||
|
||||
// Add remaining parameters to query string. Note that parameters that
|
||||
// do not need to be uploaded as multipart, i.e. any which is are not
|
||||
// binary data, are required to be in the query string, even for POST
|
||||
// requests!
|
||||
auto kvp = parametersWithoutMediaObjects->First();
|
||||
while (kvp->HasCurrent)
|
||||
{
|
||||
String^ key = Uri::EscapeComponent(kvp->Current->Key);
|
||||
String^ value = Uri::EscapeComponent(
|
||||
dynamic_cast<String^>(kvp->Current->Value));
|
||||
return uriBuilder->MakeUri();
|
||||
}
|
||||
|
||||
if (queryString->Length() > 0)
|
||||
void FBClient::ValidateMediaStreams(PropertySet^ mediaStreams)
|
||||
{
|
||||
if (mediaStreams->Size > 0)
|
||||
{
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ facebookMediaStream = mediaStreams->First();
|
||||
while(facebookMediaStream->HasCurrent)
|
||||
{
|
||||
FBMediaStream^ mediaStream = dynamic_cast<FBMediaStream^>(facebookMediaStream->Current->Value);
|
||||
if ((mediaStream->Stream == nullptr) ||
|
||||
(mediaStream->Stream->ContentType == nullptr) ||
|
||||
(mediaStream->FileName == nullptr) ||
|
||||
(mediaStream->FileName->Length() == 0))
|
||||
{
|
||||
queryString += "&";
|
||||
throw ref new InvalidArgumentException(AttachmentMustHavePropertiesSetError);
|
||||
}
|
||||
|
||||
queryString += key + L"=" + value;
|
||||
|
||||
kvp->MoveNext();
|
||||
}
|
||||
|
||||
if (mediaStreams->Size > 0)
|
||||
{
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ facebookMediaStream =
|
||||
mediaStreams->First();
|
||||
while(facebookMediaStream->HasCurrent)
|
||||
IRandomAccessStream^ stream = mediaStream->Stream;
|
||||
if (stream == nullptr)
|
||||
{
|
||||
String^ sbMediaStream = ref new String();
|
||||
FBMediaStream^ mediaStream =
|
||||
dynamic_cast<FBMediaStream^>(
|
||||
facebookMediaStream->Current->Value);
|
||||
throw ref new InvalidArgumentException(AttachmentValueIsNull);
|
||||
}
|
||||
facebookMediaStream->MoveNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((mediaStream->Stream == nullptr) ||
|
||||
(mediaStream->Stream->ContentType == nullptr) ||
|
||||
(mediaStream->FileName == nullptr) ||
|
||||
(mediaStream->FileName->Length() == 0))
|
||||
{
|
||||
throw ref new InvalidArgumentException(AttachmentMustHavePropertiesSetError);
|
||||
}
|
||||
|
||||
sbMediaStream = MultiPartFormPrefix + boundary +
|
||||
MultiPartNewLine +
|
||||
"Content-Disposition: form-data; name=\"" +
|
||||
facebookMediaStream->Current->Key + "\"; filename=\"" +
|
||||
mediaStream->FileName + "\"" + MultiPartNewLine +
|
||||
"Content-Type: " + mediaStream->Stream->ContentType +
|
||||
MultiPartNewLine + MultiPartNewLine;
|
||||
OutputDebugString(sbMediaStream->Data());
|
||||
OutputDebugString(L"\n");
|
||||
|
||||
dataWriter->WriteString(sbMediaStream);
|
||||
|
||||
IRandomAccessStream^ stream = mediaStream->Stream;
|
||||
if (stream == nullptr)
|
||||
{
|
||||
throw ref new InvalidArgumentException(AttachmentValueIsNull);
|
||||
}
|
||||
|
||||
IInputStream^ inputStream = stream->GetInputStreamAt(0);
|
||||
DataReader^ dataReader = ref new DataReader(inputStream);
|
||||
dataReader->UnicodeEncoding = UnicodeEncoding::Utf8;
|
||||
dataReader->ByteOrder = ByteOrder::LittleEndian;
|
||||
|
||||
dataWriter->WriteBuffer(dataReader->ReadBuffer(dataReader->UnconsumedBufferLength));
|
||||
|
||||
dataWriter->WriteString(MultiPartNewLine);
|
||||
facebookMediaStream->MoveNext();
|
||||
void FBClient::ValidateMediaObjects(PropertySet^ mediaObjects)
|
||||
{
|
||||
if (mediaObjects->Size > 0)
|
||||
{
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ facebookMediaObject = mediaObjects->First();
|
||||
while (facebookMediaObject->HasCurrent)
|
||||
{
|
||||
FBMediaObject^ mediaObject = dynamic_cast<FBMediaObject^>(facebookMediaObject->Current->Value);
|
||||
if ((mediaObject->GetValue()== nullptr) ||
|
||||
(mediaObject->ContentType == nullptr) ||
|
||||
(mediaObject->FileName == nullptr) ||
|
||||
(mediaObject->FileName->Length() == 0))
|
||||
{
|
||||
throw ref new InvalidArgumentException(AttachmentMustHavePropertiesSetError);
|
||||
}
|
||||
|
||||
String^ str = ref new String();
|
||||
str = MultiPartNewLine + MultiPartFormPrefix + boundary +
|
||||
MultiPartFormPrefix + MultiPartNewLine;
|
||||
|
||||
dataWriter->WriteString(str);
|
||||
}
|
||||
|
||||
if (mediaObjects->Size > 0)
|
||||
{
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ facebookMediaObject =
|
||||
mediaObjects->First();
|
||||
while (facebookMediaObject->HasCurrent)
|
||||
if (mediaObject->GetValue() == nullptr)
|
||||
{
|
||||
String^ sbMediaObject = ref new String();
|
||||
FBMediaObject^ mediaObject =
|
||||
dynamic_cast<FBMediaObject^>(
|
||||
facebookMediaObject->Current->Value);
|
||||
|
||||
if ((mediaObject->GetValue()== nullptr) ||
|
||||
(mediaObject->ContentType == nullptr) ||
|
||||
(mediaObject->FileName == nullptr) ||
|
||||
(mediaObject->FileName->Length() == 0))
|
||||
{
|
||||
throw ref new InvalidArgumentException(AttachmentMustHavePropertiesSetError);
|
||||
}
|
||||
|
||||
sbMediaObject = MultiPartFormPrefix + boundary +
|
||||
MultiPartNewLine +
|
||||
"Content-Disposition: form-data; name=\"" +
|
||||
facebookMediaObject->Current->Key + "\"; filename=\"" +
|
||||
mediaObject->FileName + "\"" + MultiPartNewLine +
|
||||
"Content-Type: " + mediaObject->ContentType +
|
||||
MultiPartNewLine + MultiPartNewLine;
|
||||
OutputDebugString(sbMediaObject->Data());
|
||||
OutputDebugString(L"\n");
|
||||
|
||||
dataWriter->WriteString(sbMediaObject);
|
||||
|
||||
if (mediaObject->GetValue() == nullptr)
|
||||
{
|
||||
throw ref new InvalidArgumentException(AttachmentValueIsNull);
|
||||
}
|
||||
|
||||
dataWriter->WriteBytes(mediaObject->GetValue());
|
||||
|
||||
dataWriter->WriteString(MultiPartNewLine);
|
||||
facebookMediaObject->MoveNext();
|
||||
throw ref new InvalidArgumentException(AttachmentValueIsNull);
|
||||
}
|
||||
|
||||
String^ str = ref new String();
|
||||
str = MultiPartNewLine + MultiPartFormPrefix + boundary +
|
||||
MultiPartFormPrefix + MultiPartNewLine;
|
||||
|
||||
dataWriter->WriteString(str);
|
||||
}
|
||||
|
||||
// TODO: Figure out where to get the right value for this. input
|
||||
//doesn't appear to have a length at this point in the code when debugging,
|
||||
contentLength = input == nullptr ? 0 : (long)input->Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for GET,DELETE
|
||||
if (mediaObjects->Size > 0 && mediaStreams->Size > 0)
|
||||
{
|
||||
throw ref new FailureException("Attachments (FBMediaObject/FBMediaStream) are valid only in POST requests.");
|
||||
}
|
||||
#if !WP8
|
||||
if (httpMethod == HttpMethod::Delete)
|
||||
{
|
||||
queryString += L"method=delete&";
|
||||
}
|
||||
#endif
|
||||
queryString += ParametersToQueryString(parametersWithoutMediaObjects);
|
||||
}
|
||||
|
||||
String^ host;
|
||||
String^ apiVersion = L"";
|
||||
|
||||
if (parametersWithoutMediaObjects->HasKey("request_host"))
|
||||
{
|
||||
host = static_cast<String^>(
|
||||
parametersWithoutMediaObjects->Lookup("request_host"));
|
||||
}
|
||||
else
|
||||
{
|
||||
host = L"graph.facebook.com";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
facebookMediaObject->MoveNext();
|
||||
}
|
||||
}
|
||||
|
||||
// Check the path for multiple id read requests and
|
||||
// modify it accordingly
|
||||
const std::wstring wStringPath(path->Data());
|
||||
std::size_t found = wStringPath.find(L"?ids=");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
path += L"&";
|
||||
}
|
||||
else
|
||||
{
|
||||
path += L"?";
|
||||
}
|
||||
|
||||
String^ uriString = L"https://" + host + L"/" + apiVersion + path + queryString;
|
||||
|
||||
return ref new Uri(uriString);
|
||||
}
|
||||
|
||||
void FBClient::SerializeParameters(
|
||||
|
@ -654,8 +520,12 @@ void FBClient::SerializeParameters(
|
|||
auto item = keysThatAreNotString->First();
|
||||
while (item->HasCurrent)
|
||||
{
|
||||
// TODO: Jsonize the object value
|
||||
String^ newValue = dynamic_cast<String^>(parameters->Lookup(item->Current));
|
||||
Object^ val = parameters->Lookup(item->Current);
|
||||
String^ newValue = dynamic_cast<String^>(val);
|
||||
if (!newValue)
|
||||
{
|
||||
newValue = val->ToString();
|
||||
}
|
||||
|
||||
// Replace the existing object with the new Jsonized value
|
||||
parameters->Remove(item->Current);
|
||||
|
@ -667,16 +537,16 @@ void FBClient::SerializeParameters(
|
|||
}
|
||||
|
||||
String^ FBClient::ParametersToQueryString(
|
||||
PropertySet^ Parameters
|
||||
IMapView<String^, Object^>^ parameters
|
||||
)
|
||||
{
|
||||
String^ queryString = L"";
|
||||
|
||||
// Add remaining parameters to query string. Note that parameters that
|
||||
// do not need to be uploaded as multipart, i.e. any which is are not
|
||||
// binary data, are required to be in the query string, even for POST
|
||||
// Add remaining parameters to query string. Note that parameters that
|
||||
// do not need to be uploaded as multipart, i.e. any which is are not
|
||||
// binary data, are required to be in the query string, even for POST
|
||||
// requests!
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ kvp = Parameters->First();
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ kvp = parameters->First();
|
||||
while (kvp->HasCurrent)
|
||||
{
|
||||
String^ key = Uri::EscapeComponent(kvp->Current->Key);
|
||||
|
@ -749,3 +619,16 @@ task<String^> FBClient::TryReceiveHttpResponse(
|
|||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
PropertySet^ FBClient::MapViewToPropertySet(IMapView<String^, Object^>^ mapView)
|
||||
{
|
||||
PropertySet^ propertySet = ref new PropertySet();
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ it = mapView->First();
|
||||
while (it->HasCurrent)
|
||||
{
|
||||
IKeyValuePair<String^, Object^>^ current = it->Current;
|
||||
propertySet->Insert(current->Key, current->Value);
|
||||
it->MoveNext();
|
||||
}
|
||||
return propertySet;
|
||||
}
|
|
@ -42,7 +42,7 @@ namespace winsdkfb
|
|||
*/
|
||||
GetTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ namespace winsdkfb
|
|||
virtual Windows::Foundation::IAsyncOperation<Platform::String^>^
|
||||
PostTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -70,7 +70,7 @@ namespace winsdkfb
|
|||
virtual Windows::Foundation::IAsyncOperation<Platform::String^>^
|
||||
DeleteTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -80,7 +80,7 @@ namespace winsdkfb
|
|||
* "key1=value1&key2=value2&..." etc.
|
||||
*/
|
||||
virtual Platform::String^ ParametersToQueryString(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
private:
|
||||
|
@ -156,7 +156,6 @@ namespace winsdkfb
|
|||
* @param httpMethod Type of HTTP request to build URI for
|
||||
* @param path Request path
|
||||
* @param parameters Query parameters for the request
|
||||
* @param input TODO
|
||||
* @return Request URI
|
||||
* @exception FailureExecption if FBMediaObject or FBMediaStream are
|
||||
* attempting to be attached on non-POST requests.
|
||||
|
@ -165,8 +164,7 @@ namespace winsdkfb
|
|||
Windows::Foundation::Uri^ PrepareRequestUri(
|
||||
winsdkfb::HttpMethod httpMethod,
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters,
|
||||
Windows::Storage::Streams::IRandomAccessStream^ input
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -232,5 +230,17 @@ namespace winsdkfb
|
|||
concurrency::task<Windows::Web::Http::HttpResponseMessage^> httpRequestTask,
|
||||
concurrency::cancellation_token_source cancellationTokenSource
|
||||
);
|
||||
|
||||
Windows::Foundation::Collections::PropertySet^ MapViewToPropertySet(
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ mapView
|
||||
);
|
||||
|
||||
void ValidateMediaStreams(
|
||||
Windows::Foundation::Collections::PropertySet^ mediaStreams
|
||||
);
|
||||
|
||||
void ValidateMediaObjects(
|
||||
Windows::Foundation::Collections::PropertySet^ mediaObjects
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -347,7 +347,7 @@ Uri^ FacebookDialog::BuildFeedDialogUrl(
|
|||
L"&redirect_uri=" + GetRedirectUriString(L"feed") +
|
||||
L"&display=popup" +
|
||||
L"&app_id=" + sess->FBAppId;
|
||||
String^ queryString = HttpManager::Instance->ParametersToQueryString(Parameters);
|
||||
String^ queryString = HttpManager::Instance->ParametersToQueryString(Parameters->GetView());
|
||||
if (queryString->Length() > 0)
|
||||
{
|
||||
dialogUriString += "&" + queryString;
|
||||
|
@ -372,7 +372,7 @@ Uri^ FacebookDialog::BuildRequestsDialogUrl(
|
|||
L"&redirect_uri=" + GetRedirectUriString(L"requests") +
|
||||
L"&display=popup" +
|
||||
L"&app_id=" + sess->FBAppId;
|
||||
String^ queryString = HttpManager::Instance->ParametersToQueryString(Parameters);
|
||||
String^ queryString = HttpManager::Instance->ParametersToQueryString(Parameters->GetView());
|
||||
if (queryString->Length() > 0)
|
||||
{
|
||||
dialogUriString += "&" + queryString;
|
||||
|
@ -397,7 +397,7 @@ Uri^ FacebookDialog::BuildSendDialogUrl(
|
|||
L"&redirect_uri=" + GetRedirectUriString(L"send") +
|
||||
L"&display=popup" +
|
||||
L"&app_id=" + sess->FBAppId;
|
||||
String^ queryString = HttpManager::Instance->ParametersToQueryString(Parameters);
|
||||
String^ queryString = HttpManager::Instance->ParametersToQueryString(Parameters->GetView());
|
||||
if (queryString->Length() > 0)
|
||||
{
|
||||
dialogUriString += "&" + queryString;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "FacebookSession.h"
|
||||
#include "HttpManager.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace winsdkfb;
|
||||
using namespace winsdkfb::Graph;
|
||||
|
@ -42,6 +44,10 @@ FBPaginatedArray::FBPaginatedArray(
|
|||
_parameters(Parameters),
|
||||
_objectFactory(ObjectFactory)
|
||||
{
|
||||
if (_parameters == nullptr)
|
||||
{
|
||||
_parameters = ref new PropertySet();
|
||||
}
|
||||
}
|
||||
|
||||
Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::FirstAsync(
|
||||
|
@ -228,9 +234,9 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::GetPage(
|
|||
String^ path
|
||||
)
|
||||
{
|
||||
return create_async([this, path]() -> task<FBResult^>
|
||||
return create_async([=]() -> task<FBResult^>
|
||||
{
|
||||
return create_task(HttpManager::Instance->GetTaskAsync(path, _parameters))
|
||||
return create_task(HttpManager::Instance->GetTaskAsync(path, _parameters->GetView()))
|
||||
.then([this](String^ responseString)
|
||||
{
|
||||
if (responseString == nullptr)
|
||||
|
@ -243,4 +249,4 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::GetPage(
|
|||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -99,7 +99,7 @@ FBSession::FBSession() :
|
|||
login_evt = CreateEventEx(NULL, NULL, 0, DELETE | SYNCHRONIZE);
|
||||
}
|
||||
_APIMajorVersion = 2;
|
||||
_APIMinorVersion = 1;
|
||||
_APIMinorVersion = 6;
|
||||
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
_webViewRedirectDomain = FACEBOOK_MOBILE_SERVER_NAME;
|
||||
#else
|
||||
|
@ -160,6 +160,9 @@ FBAccessTokenData^ FBSession::AccessTokenData::get()
|
|||
void FBSession::AccessTokenData::set(FBAccessTokenData^ value)
|
||||
{
|
||||
_AccessTokenData = value;
|
||||
|
||||
// If token have been updated, make sure to save updated token
|
||||
TrySaveTokenData();
|
||||
}
|
||||
|
||||
FBUser^ FBSession::User::get()
|
||||
|
@ -205,9 +208,12 @@ task<FBResult^> FBSession::GetUserInfo(
|
|||
winsdkfb::FBAccessTokenData^ TokenData
|
||||
)
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
parameters->Insert(L"fields",
|
||||
L"gender,link,first_name,last_name,locale,timezone,email,updated_time,verified,name,id");
|
||||
FBSingleValue^ value = ref new FBSingleValue(
|
||||
"/me",
|
||||
nullptr,
|
||||
parameters,
|
||||
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
|
||||
{
|
||||
return FBUser::FromJson(JsonText);
|
||||
|
@ -961,7 +967,6 @@ IAsyncOperation<FBResult^>^ FBSession::LoginAsync(
|
|||
{
|
||||
Permissions = ref new FBPermissions((ref new Vector<String^>())->GetView());
|
||||
}
|
||||
_dialog = ref new FacebookDialog();
|
||||
|
||||
return create_async([=]()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
//******************************************************************************
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
//******************************************************************************
|
||||
|
||||
#include "pch.h"
|
||||
#include "GraphUriBuilder.h"
|
||||
#include "FacebookSession.h"
|
||||
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace winsdkfb;
|
||||
|
||||
|
||||
GraphUriBuilder::GraphUriBuilder(String^ path)
|
||||
:
|
||||
_queryParams { ref new PropertySet() }
|
||||
{
|
||||
Uri^ testUri;
|
||||
bool buildDomain = false;
|
||||
try
|
||||
{
|
||||
testUri = ref new Uri(path);
|
||||
}
|
||||
catch (Platform::InvalidArgumentException^ e)
|
||||
{
|
||||
buildDomain = true;
|
||||
}
|
||||
|
||||
if (buildDomain)
|
||||
{
|
||||
String^ domain = L"https://graph.facebook.com/";
|
||||
testUri = ref new Uri(domain + path);
|
||||
}
|
||||
_host = testUri->Host;
|
||||
_path = testUri->Path;
|
||||
_scheme = testUri->SchemeName;
|
||||
|
||||
// remove any extra '/'s from path
|
||||
FixPathDelimiters();
|
||||
// capture api version from path or build it
|
||||
BuildApiVersionString();
|
||||
// save query params in map for later use
|
||||
DecodeQueryParams(testUri);
|
||||
}
|
||||
|
||||
void GraphUriBuilder::AddQueryParam(Platform::String^ query, Platform::String^ param)
|
||||
{
|
||||
_queryParams->Insert(query, param);
|
||||
}
|
||||
|
||||
Windows::Foundation::Uri^ GraphUriBuilder::MakeUri()
|
||||
{
|
||||
// this request_host stuff is a bit of a hack to send graph calls in
|
||||
// the unit tests to our own web service.
|
||||
if (_queryParams->HasKey(L"request_host"))
|
||||
{
|
||||
_host = static_cast<String^>(_queryParams->Lookup(L"request_host"));
|
||||
}
|
||||
String^ fullPath = _scheme + L"://" + _host + L"/" + _apiVersion + _path;
|
||||
|
||||
if (_queryParams->Size > 0)
|
||||
{
|
||||
String^ separator = L"?";
|
||||
auto it = _queryParams->First();
|
||||
while (it->HasCurrent)
|
||||
{
|
||||
fullPath += separator + Uri::EscapeComponent(it->Current->Key) + L"=" + Uri::EscapeComponent(static_cast<String^>(it->Current->Value));
|
||||
separator = L"&";
|
||||
it->MoveNext();
|
||||
}
|
||||
}
|
||||
return ref new Uri(fullPath);
|
||||
}
|
||||
|
||||
void GraphUriBuilder::BuildApiVersionString()
|
||||
{
|
||||
std::wstring regexString = LR"__(^.?(v\d\.\d)(.*))__";
|
||||
std::wregex apiRegex{ regexString };
|
||||
std::wsmatch match;
|
||||
std::wstring searchString{ _path->Data() };
|
||||
std::regex_match(searchString, match, apiRegex);
|
||||
if (match.size() >= 3) // 1 for matched string + 2 for each capture group
|
||||
{
|
||||
std::wstring apiString = match[1].str();
|
||||
_apiVersion = ref new String(apiString.c_str());
|
||||
// need to adjust _path so that the api version doesn't get added twice
|
||||
std::wstring newPath = match[2].str();
|
||||
_path = ref new String(newPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
_apiVersion = "v" + sess->APIMajorVersion.ToString() + "." + sess->APIMinorVersion.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphUriBuilder::FixPathDelimiters()
|
||||
{
|
||||
String^ fixedPath = L"";
|
||||
std::wstring originalPath{ _path->Data() };
|
||||
std::wistringstream iss{ originalPath };
|
||||
std::wstring token;
|
||||
while (std::getline(iss, token, L'/'))
|
||||
{
|
||||
if (token.size() > 0)
|
||||
{
|
||||
fixedPath += L"/" + ref new String(token.c_str());
|
||||
}
|
||||
}
|
||||
_path = fixedPath;
|
||||
}
|
||||
|
||||
void GraphUriBuilder::DecodeQueryParams(Uri^ uri)
|
||||
{
|
||||
WwwFormUrlDecoder^ decoder = uri->QueryParsed;
|
||||
if (decoder->Size > 0)
|
||||
{
|
||||
IIterator<IWwwFormUrlDecoderEntry^>^ it = decoder->First();
|
||||
while (it->HasCurrent)
|
||||
{
|
||||
IWwwFormUrlDecoderEntry^ current = it->Current;
|
||||
_queryParams->Insert(current->Name, current->Value);
|
||||
it->MoveNext();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
//******************************************************************************
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
//******************************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ppltasks.h>
|
||||
|
||||
namespace winsdkfb
|
||||
{
|
||||
public ref class GraphUriBuilder sealed
|
||||
{
|
||||
public:
|
||||
GraphUriBuilder(Platform::String^ path);
|
||||
|
||||
Windows::Foundation::Uri^ MakeUri();
|
||||
void AddQueryParam(Platform::String^ query, Platform::String^ param);
|
||||
|
||||
private:
|
||||
void BuildApiVersionString();
|
||||
void FixPathDelimiters();
|
||||
void DecodeQueryParams(Windows::Foundation::Uri^ uri);
|
||||
|
||||
Platform::String^ _host;
|
||||
Platform::String^ _path;
|
||||
Platform::String^ _scheme;
|
||||
Platform::String^ _apiVersion;
|
||||
Windows::Foundation::Collections::PropertySet^ _queryParams;
|
||||
};
|
||||
}
|
|
@ -34,23 +34,23 @@ void HttpManager::SetHttpClient(IHttpClient^ httpClient)
|
|||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
IAsyncOperation<String^>^ HttpManager::GetTaskAsync(String^ path, PropertySet^ parameters)
|
||||
IAsyncOperation<String^>^ HttpManager::GetTaskAsync(String^ path, IMapView<String^, Object^>^ parameters)
|
||||
{
|
||||
return _httpClient->GetTaskAsync(path, parameters);
|
||||
}
|
||||
|
||||
IAsyncOperation<String^>^ HttpManager::PostTaskAsync(String^ path, PropertySet^ parameters)
|
||||
IAsyncOperation<String^>^ HttpManager::PostTaskAsync(String^ path, IMapView<String^, Object^>^ parameters)
|
||||
{
|
||||
return _httpClient->PostTaskAsync(path, parameters);
|
||||
}
|
||||
|
||||
IAsyncOperation<String^>^ HttpManager::DeleteTaskAsync(String^ path, PropertySet^ parameters)
|
||||
IAsyncOperation<String^>^ HttpManager::DeleteTaskAsync(String^ path, IMapView<String^, Object^>^ parameters)
|
||||
{
|
||||
return _httpClient->DeleteTaskAsync(path, parameters);
|
||||
}
|
||||
|
||||
String^ HttpManager::ParametersToQueryString(
|
||||
PropertySet^ Parameters
|
||||
IMapView<String^, Object^>^ Parameters
|
||||
)
|
||||
{
|
||||
return _httpClient->ParametersToQueryString(Parameters);
|
||||
|
|
|
@ -34,21 +34,21 @@ namespace winsdkfb
|
|||
|
||||
virtual Windows::Foundation::IAsyncOperation<Platform::String^>^ GetTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
virtual Windows::Foundation::IAsyncOperation<Platform::String^>^ PostTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
virtual Windows::Foundation::IAsyncOperation<Platform::String^>^ DeleteTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
virtual Platform::String^ ParametersToQueryString(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
private:
|
||||
|
|
|
@ -23,21 +23,21 @@ namespace winsdkfb
|
|||
public:
|
||||
Windows::Foundation::IAsyncOperation<Platform::String^>^ GetTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
Windows::Foundation::IAsyncOperation<Platform::String^>^ PostTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
Windows::Foundation::IAsyncOperation<Platform::String^>^ DeleteTaskAsync(
|
||||
Platform::String^ path,
|
||||
Windows::Foundation::Collections::PropertySet^ parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
|
||||
Platform::String^ ParametersToQueryString(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^, Platform::Object^>^ parameters
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)pch.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ScaleConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)SDKMessage.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)GraphUriBuilder.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ColorLuminosityConverter.cpp" />
|
||||
|
@ -96,6 +97,7 @@
|
|||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ScaleConverter.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)GraphUriBuilder.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectCapability Include="SourceItemsFromImports" />
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)HttpManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)GraphUriBuilder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookDialog.xaml.h" />
|
||||
|
@ -189,6 +192,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)FBConstants.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)GraphUriBuilder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="$(MSBuildThisFileDirectory)Images\fb_blank_profile_portrait.png" />
|
||||
|
|
|
@ -98,6 +98,10 @@
|
|||
<None Include="..\..\FBWinStoreCsTests\FBCSObjectImplementation.ttinclude">
|
||||
<Link>FBCSObjectImplementation.ttinclude</Link>
|
||||
</None>
|
||||
<Content Include="..\..\FBWinStoreCsTests\TestData\testJsonPropertySet.json">
|
||||
<Link>TestData\testJsonPropertySet.json</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="..\..\FBWinStoreCsTests\Utility.ttinclude">
|
||||
<Link>Utility.ttinclude</Link>
|
||||
</None>
|
||||
|
|
|
@ -170,7 +170,7 @@ IAsyncOperation<String^>^ FBSDKAppEvents::LogInstallEvent(
|
|||
parameters->Insert(L"windows_attribution_id", campaignID);
|
||||
return create_task([=]() -> IAsyncOperation<String^>^
|
||||
{
|
||||
return HttpManager::Instance->PostTaskAsync(path, parameters);
|
||||
return HttpManager::Instance->PostTaskAsync(path, parameters->GetView());
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception^ ex)
|
||||
|
@ -206,7 +206,7 @@ IAsyncAction^ FBSDKAppEvents::LogActivateEvent(
|
|||
|
||||
return create_async([=]()
|
||||
{
|
||||
return create_task(HttpManager::Instance->PostTaskAsync(path, parameters))
|
||||
return create_task(HttpManager::Instance->PostTaskAsync(path, parameters->GetView()))
|
||||
.then([=](String^ response) -> void
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
|
|
Загрузка…
Ссылка в новой задаче