diff --git a/Source/Podio .NET/Exceptions/PodioException.cs b/Source/Podio .NET/Exceptions/PodioException.cs
index d9a8c6d..9659d61 100644
--- a/Source/Podio .NET/Exceptions/PodioException.cs
+++ b/Source/Podio .NET/Exceptions/PodioException.cs
@@ -207,7 +207,18 @@ public PodioUnavailableException(SerializationInfo info, StreamingContext contex
}
#endif
}
-
+ public class PodioInvalidJsonException : PodioException
+ {
+ public PodioInvalidJsonException(int status, PodioError error)
+ : base(status, error)
+ {
+ }
+#if !NETSTANDARD1_3
+ public PodioInvalidJsonException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+#endif
+ }
///
/// Represent the error response from API
///
diff --git a/Source/Podio .NET/Models/Task.cs b/Source/Podio .NET/Models/Task.cs
index 2bb5cbe..f6bbffc 100644
--- a/Source/Podio .NET/Models/Task.cs
+++ b/Source/Podio .NET/Models/Task.cs
@@ -7,7 +7,7 @@ namespace PodioAPI.Models
public class Task
{
[JsonProperty("task_id")]
- public string TaskId { get; set; }
+ public int TaskId { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
diff --git a/Source/Podio .NET/Podio.cs b/Source/Podio .NET/Podio.cs
index 5ed8501..9864947 100644
--- a/Source/Podio .NET/Podio.cs
+++ b/Source/Podio .NET/Podio.cs
@@ -1,4 +1,5 @@
-using PodioAPI.Exceptions;
+using Newtonsoft.Json;
+using PodioAPI.Exceptions;
using PodioAPI.Models;
using PodioAPI.Services;
using PodioAPI.Utils;
@@ -75,8 +76,11 @@ internal async Task Get(string url, Dictionary requestData
}
else
{
- var jsonString = JSONSerializer.Serilaize(requestData);
- request.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
+ if (requestData != null)
+ {
+ var jsonString = JSONSerializer.Serilaize(requestData);
+ request.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
+ }
}
return await Request(request);
@@ -159,31 +163,44 @@ internal async Task Get(string url, Dictionary requestData
else
{
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
- var podioError = JSONSerializer.Deserialize(responseBody);
-
- if (response.StatusCode == HttpStatusCode.Unauthorized)
+ try
{
- // If RefreshToken exists, refresh the access token and try the request again
- if (OAuth is PodioOAuth podioOAuth && !string.IsNullOrEmpty(podioOAuth.RefreshToken) && podioError.ErrorDescription == "expired_token" || podioError.Error == "invalid_token")
+ var podioError = JSONSerializer.Deserialize(responseBody);
+
+ if (response.StatusCode == HttpStatusCode.Unauthorized)
{
- var authInfo = await RefreshAccessToken().ConfigureAwait(false);
- if (authInfo != null && !string.IsNullOrEmpty(authInfo.AccessToken))
+ // If RefreshToken exists, refresh the access token and try the request again
+ if (OAuth is PodioOAuth podioOAuth && !string.IsNullOrEmpty(podioOAuth.RefreshToken) && podioError.ErrorDescription == "expired_token" || podioError.Error == "invalid_token")
+ {
+ var authInfo = await RefreshAccessToken().ConfigureAwait(false);
+ if (authInfo != null && !string.IsNullOrEmpty(authInfo.AccessToken))
+ {
+ requestCopy.Headers.Authorization = new AuthenticationHeaderValue("OAuth2", authInfo.AccessToken);
+ return await Request(requestCopy, isFileDownload, returnAsString);
+ }
+ }
+ else
{
- requestCopy.Headers.Authorization = new AuthenticationHeaderValue("OAuth2", authInfo.AccessToken);
- return await Request(requestCopy, isFileDownload, returnAsString);
+ OAuth = null;
+ throw new PodioAuthorizationException((int)response.StatusCode, podioError);
}
}
else
{
- OAuth = null;
- throw new PodioAuthorizationException((int)response.StatusCode, podioError);
- }
+ ProcessErrorResponse(response.StatusCode, podioError);
+ }
+
}
- else
+ catch (JsonException ex)
{
- ProcessErrorResponse(response.StatusCode, podioError);
+ throw new PodioInvalidJsonException((int)response.StatusCode, new PodioError
+ {
+ Error = "Error response is not a valid Json string.",
+ ErrorDescription = ex.ToString(),
+ ErrorDetail = responseBody
+ });
}
-
+
return default(T);
}
}
@@ -215,6 +232,7 @@ private HttpRequestMessage CreateHttpRequest(string url, HttpMethod httpMethod,
private void ProcessErrorResponse(HttpStatusCode statusCode, PodioError podioError)
{
var status = (int)statusCode;
+
switch (status)
{
case 400:
diff --git a/Source/Podio .NET/Services/FileService.cs b/Source/Podio .NET/Services/FileService.cs
index a432b52..063cb75 100644
--- a/Source/Podio .NET/Services/FileService.cs
+++ b/Source/Podio .NET/Services/FileService.cs
@@ -318,5 +318,21 @@ public async Task DownloadFile(FileAttachment fileAttachment)
};
return await _podio.Get(fileLink, new Dictionary(), true);
}
+ ///
+ /// Add linked account file (like sharefile, google drive)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task UploadLinkedAccountFile(int linkedAccountId, string externalFileId, bool preservePermissions = true)
+ {
+ var url = $"/file/linked_account/{linkedAccountId}/";
+ var request = new
+ {
+ external_file_id = externalFileId
+ };
+ return await _podio.Post(url, request);
+ }
}
}
\ No newline at end of file
diff --git a/Source/Podio .NET/Utils/ItemFields/LocationItemField.cs b/Source/Podio .NET/Utils/ItemFields/LocationItemField.cs
index 37f697d..971cfaa 100644
--- a/Source/Podio .NET/Utils/ItemFields/LocationItemField.cs
+++ b/Source/Podio .NET/Utils/ItemFields/LocationItemField.cs
@@ -77,6 +77,44 @@ public double? Longitude
this.Values.First()["lng"] = value;
}
}
+ public string StreetAddress
+ {
+ get
+ {
+ if (this.Values.Any())
+ {
+ return (string)this.Values.First["street_address"];
+ }
+
+ return null;
+ }
+ }
+
+ public string City
+ {
+ get
+ {
+ if (this.Values.Any())
+ {
+ return (string)this.Values.First["city"];
+ }
+
+ return null;
+ }
+ }
+
+ public string PostalCode
+ {
+ get
+ {
+ if (this.Values.Any())
+ {
+ return (string)this.Values.First["postal_code"];
+ }
+
+ return null;
+ }
+ }
public string Country
{