Merge pull request #72 from onerain88/chore
Chore
commit
29392036e6
|
@ -30,6 +30,9 @@
|
||||||
<Compile Include="..\Common\Json\LCJsonConverter.cs">
|
<Compile Include="..\Common\Json\LCJsonConverter.cs">
|
||||||
<Link>Json\LCJsonConverter.cs</Link>
|
<Link>Json\LCJsonConverter.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Common\Exception\LCException.cs">
|
||||||
|
<Link>Exception\LCException.cs</Link>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Newtonsoft.Json">
|
<Reference Include="Newtonsoft.Json">
|
||||||
|
|
|
@ -13,5 +13,6 @@
|
||||||
<Folder Include="Log\" />
|
<Folder Include="Log\" />
|
||||||
<Folder Include="Http\" />
|
<Folder Include="Http\" />
|
||||||
<Folder Include="Task\" />
|
<Folder Include="Task\" />
|
||||||
|
<Folder Include="Exception\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace LeanCloud.Storage {
|
namespace LeanCloud {
|
||||||
|
/// <summary>
|
||||||
|
/// LeanCloud 异常
|
||||||
|
/// </summary>
|
||||||
public class LCException : Exception {
|
public class LCException : Exception {
|
||||||
|
/// <summary>
|
||||||
|
/// 错误码
|
||||||
|
/// </summary>
|
||||||
public int Code {
|
public int Code {
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误信息
|
||||||
|
/// </summary>
|
||||||
public new string Message {
|
public new string Message {
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
@ -14,5 +23,9 @@ namespace LeanCloud.Storage {
|
||||||
Code = code;
|
Code = code;
|
||||||
Message = message;
|
Message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"{Code} - {Message}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,7 +52,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
||||||
attrs["name"] = name;
|
attrs["name"] = name;
|
||||||
}
|
}
|
||||||
if (properties != null) {
|
if (properties != null) {
|
||||||
attrs = properties.Union(attrs)
|
attrs = properties.Union(attrs.Where(kv => !properties.ContainsKey(kv.Key)))
|
||||||
.ToDictionary(k => k.Key, v => v.Value);
|
.ToDictionary(k => k.Key, v => v.Value);
|
||||||
}
|
}
|
||||||
conv.Attr = new JsonObjectMessage {
|
conv.Attr = new JsonObjectMessage {
|
||||||
|
|
|
@ -15,9 +15,6 @@
|
||||||
<Compile Include="..\Storage\LCCloud.cs">
|
<Compile Include="..\Storage\LCCloud.cs">
|
||||||
<Link>LCCloud.cs</Link>
|
<Link>LCCloud.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Storage\LCException.cs">
|
|
||||||
<Link>LCException.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\Storage\LCFile.cs">
|
<Compile Include="..\Storage\LCFile.cs">
|
||||||
<Link>LCFile.cs</Link>
|
<Link>LCFile.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using LeanCloud;
|
using LeanCloud;
|
||||||
using LeanCloud.Storage;
|
using LeanCloud.Storage;
|
||||||
|
|
||||||
|
@ -74,5 +75,19 @@ namespace Storage.Test {
|
||||||
TestContext.WriteLine(account.ObjectId);
|
TestContext.WriteLine(account.ObjectId);
|
||||||
Assert.NotNull(account.ObjectId);
|
Assert.NotNull(account.ObjectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Serialization() {
|
||||||
|
await LCUser.Login("hello", "world");
|
||||||
|
LCQuery<LCObject> query = new LCQuery<LCObject>("Account") {
|
||||||
|
IncludeACL = true
|
||||||
|
};
|
||||||
|
query.OrderByDescending("createdAt");
|
||||||
|
ReadOnlyCollection<LCObject> accounts = await query.Find();
|
||||||
|
foreach (LCObject account in accounts) {
|
||||||
|
TestContext.WriteLine($"public read access: {account.ACL.PublicReadAccess}");
|
||||||
|
TestContext.WriteLine($"public write access: {account.ACL.PublicWriteAccess}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using LeanCloud.Storage;
|
using LeanCloud;
|
||||||
|
|
||||||
namespace Storage.Test {
|
namespace Storage.Test {
|
||||||
public class ExceptionTest {
|
public class ExceptionTest {
|
||||||
|
|
|
@ -68,10 +68,25 @@ namespace LeanCloud.Storage.Internal.Codec {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LCGeoPoint DecodeGeoPoint(IDictionary data) {
|
public static LCGeoPoint DecodeGeoPoint(IDictionary data) {
|
||||||
double latitude = double.Parse(data["latitude"].ToString());
|
double latitude = Convert.ToDouble(data["latitude"]);
|
||||||
double longitude = double.Parse(data["longitude"].ToString());
|
double longitude = Convert.ToDouble(data["longitude"]);
|
||||||
LCGeoPoint geoPoint = new LCGeoPoint(latitude, longitude);
|
LCGeoPoint geoPoint = new LCGeoPoint(latitude, longitude);
|
||||||
return geoPoint;
|
return geoPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LCACL DecodeACL(Dictionary<string, object> dict) {
|
||||||
|
LCACL acl = new LCACL();
|
||||||
|
foreach (KeyValuePair<string, object> kv in dict) {
|
||||||
|
string key = kv.Key;
|
||||||
|
Dictionary<string, object> access = kv.Value as Dictionary<string, object>;
|
||||||
|
if (access.TryGetValue("read", out object ra)) {
|
||||||
|
acl.readAccess[key] = Convert.ToBoolean(ra);
|
||||||
|
}
|
||||||
|
if (access.TryGetValue("write", out object wa)) {
|
||||||
|
acl.writeAccess[key] = Convert.ToBoolean(wa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,18 +83,25 @@ namespace LeanCloud.Storage.Internal.Codec {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object EncodeACL(LCACL acl) {
|
public static object EncodeACL(LCACL acl) {
|
||||||
HashSet<string> readers = acl.readers;
|
HashSet<string> keys = new HashSet<string>();
|
||||||
HashSet<string> writers = acl.writers;
|
if (acl.readAccess.Count > 0) {
|
||||||
HashSet<string> union = new HashSet<string>(readers);
|
keys.UnionWith(acl.readAccess.Keys);
|
||||||
union.UnionWith(writers);
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
foreach (string k in union) {
|
|
||||||
dict[k] = new Dictionary<string, object> {
|
|
||||||
{ "read", readers.Contains(k) },
|
|
||||||
{ "write", writers.Contains(k) }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return dict;
|
if (acl.writeAccess.Count > 0) {
|
||||||
|
keys.UnionWith(acl.writeAccess.Keys);
|
||||||
|
}
|
||||||
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||||
|
foreach (string key in keys) {
|
||||||
|
Dictionary<string, bool> access = new Dictionary<string, bool>();
|
||||||
|
if (acl.readAccess.TryGetValue(key, out bool ra)) {
|
||||||
|
access["read"] = ra;
|
||||||
|
}
|
||||||
|
if (acl.writeAccess.TryGetValue(key, out bool wa)) {
|
||||||
|
access["write"] = wa;
|
||||||
|
}
|
||||||
|
result[key] = access;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object EncodeRelation(LCRelation<LCObject> relation) {
|
public static object EncodeRelation(LCRelation<LCObject> relation) {
|
||||||
|
|
|
@ -40,13 +40,18 @@ namespace LeanCloud.Storage.Internal.Object {
|
||||||
} else if (key == "objectId") {
|
} else if (key == "objectId") {
|
||||||
objectData.ObjectId = value.ToString();
|
objectData.ObjectId = value.ToString();
|
||||||
} else if (key == "createdAt" && DateTime.TryParse(value.ToString(), out DateTime createdAt)) {
|
} else if (key == "createdAt" && DateTime.TryParse(value.ToString(), out DateTime createdAt)) {
|
||||||
objectData.CreatedAt = createdAt;
|
objectData.CreatedAt = createdAt.ToLocalTime();
|
||||||
} else if (key == "updatedAt" && DateTime.TryParse(value.ToString(), out DateTime updatedAt)) {
|
} else if (key == "updatedAt" && DateTime.TryParse(value.ToString(), out DateTime updatedAt)) {
|
||||||
objectData.UpdatedAt = updatedAt;
|
objectData.UpdatedAt = updatedAt.ToLocalTime();
|
||||||
|
} else {
|
||||||
|
if (key == "ACL" &&
|
||||||
|
value is Dictionary<string, object> dic) {
|
||||||
|
objectData.CustomPropertyDict[key] = LCDecoder.DecodeACL(dic);
|
||||||
} else {
|
} else {
|
||||||
objectData.CustomPropertyDict[key] = LCDecoder.Decode(value);
|
objectData.CustomPropertyDict[key] = LCDecoder.Decode(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return objectData;
|
return objectData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +66,10 @@ namespace LeanCloud.Storage.Internal.Object {
|
||||||
dict["objectId"] = objectData.ObjectId;
|
dict["objectId"] = objectData.ObjectId;
|
||||||
}
|
}
|
||||||
if (objectData.CreatedAt != null) {
|
if (objectData.CreatedAt != null) {
|
||||||
dict["createdAt"] = objectData.CreatedAt;
|
dict["createdAt"] = objectData.CreatedAt.ToUniversalTime();
|
||||||
}
|
}
|
||||||
if (objectData.UpdatedAt != null) {
|
if (objectData.UpdatedAt != null) {
|
||||||
dict["updatedAt"] = objectData.UpdatedAt;
|
dict["updatedAt"] = objectData.UpdatedAt.ToUniversalTime();
|
||||||
}
|
}
|
||||||
if (objectData.CustomPropertyDict != null) {
|
if (objectData.CustomPropertyDict != null) {
|
||||||
foreach (KeyValuePair<string, object> kv in objectData.CustomPropertyDict) {
|
foreach (KeyValuePair<string, object> kv in objectData.CustomPropertyDict) {
|
||||||
|
|
|
@ -24,6 +24,10 @@ namespace LeanCloud.Storage.Internal.Query {
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IncludeACL {
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
public LCCompositionalCondition(string composition = And) {
|
public LCCompositionalCondition(string composition = And) {
|
||||||
this.composition = composition;
|
this.composition = composition;
|
||||||
Skip = 0;
|
Skip = 0;
|
||||||
|
@ -217,6 +221,9 @@ namespace LeanCloud.Storage.Internal.Query {
|
||||||
if (selectedKeys != null && selectedKeys.Count > 0) {
|
if (selectedKeys != null && selectedKeys.Count > 0) {
|
||||||
dict["keys"] = string.Join(",", selectedKeys);
|
dict["keys"] = string.Join(",", selectedKeys);
|
||||||
}
|
}
|
||||||
|
if (IncludeACL) {
|
||||||
|
dict["returnACL"] = "true";
|
||||||
|
}
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,22 +10,32 @@ namespace LeanCloud.Storage {
|
||||||
|
|
||||||
const string RoleKeyPrefix = "role:";
|
const string RoleKeyPrefix = "role:";
|
||||||
|
|
||||||
internal HashSet<string> readers;
|
internal Dictionary<string, bool> readAccess = new Dictionary<string, bool>();
|
||||||
internal HashSet<string> writers;
|
internal Dictionary<string, bool> writeAccess = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
public static LCACL CreateWithOwner(LCUser owner) {
|
||||||
|
if (owner == null) {
|
||||||
|
throw new ArgumentNullException(nameof(owner));
|
||||||
|
}
|
||||||
|
LCACL acl = new LCACL();
|
||||||
|
acl.SetUserReadAccess(owner, true);
|
||||||
|
acl.SetUserWriteAccess(owner, true);
|
||||||
|
return acl;
|
||||||
|
}
|
||||||
|
|
||||||
public bool PublicReadAccess {
|
public bool PublicReadAccess {
|
||||||
get {
|
get {
|
||||||
return GetAccess(readers, PublicKey);
|
return GetAccess(readAccess, PublicKey);
|
||||||
} set {
|
} set {
|
||||||
SetAccess(readers, PublicKey, value);
|
SetAccess(readAccess, PublicKey, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool PublicWriteAccess {
|
public bool PublicWriteAccess {
|
||||||
get {
|
get {
|
||||||
return GetAccess(writers, PublicKey);
|
return GetAccess(writeAccess, PublicKey);
|
||||||
} set {
|
} set {
|
||||||
SetAccess(writers, PublicKey, value);
|
SetAccess(writeAccess, PublicKey, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,28 +43,28 @@ namespace LeanCloud.Storage {
|
||||||
if (string.IsNullOrEmpty(userId)) {
|
if (string.IsNullOrEmpty(userId)) {
|
||||||
throw new ArgumentNullException(nameof(userId));
|
throw new ArgumentNullException(nameof(userId));
|
||||||
}
|
}
|
||||||
return GetAccess(readers, userId);
|
return GetAccess(readAccess, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetUserIdReadAccess(string userId, bool value) {
|
public void SetUserIdReadAccess(string userId, bool value) {
|
||||||
if (string.IsNullOrEmpty(userId)) {
|
if (string.IsNullOrEmpty(userId)) {
|
||||||
throw new ArgumentNullException(nameof(userId));
|
throw new ArgumentNullException(nameof(userId));
|
||||||
}
|
}
|
||||||
SetAccess(readers, userId, value);
|
SetAccess(readAccess, userId, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetUserIdWriteAccess(string userId) {
|
public bool GetUserIdWriteAccess(string userId) {
|
||||||
if (string.IsNullOrEmpty(userId)) {
|
if (string.IsNullOrEmpty(userId)) {
|
||||||
throw new ArgumentNullException(nameof(userId));
|
throw new ArgumentNullException(nameof(userId));
|
||||||
}
|
}
|
||||||
return GetAccess(writers, userId);
|
return GetAccess(writeAccess, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetUserIdWriteAccess(string userId, bool value) {
|
public void SetUserIdWriteAccess(string userId, bool value) {
|
||||||
if (string.IsNullOrEmpty(userId)) {
|
if (string.IsNullOrEmpty(userId)) {
|
||||||
throw new ArgumentNullException(nameof(userId));
|
throw new ArgumentNullException(nameof(userId));
|
||||||
}
|
}
|
||||||
SetAccess(writers, userId, value);
|
SetAccess(writeAccess, userId, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetUserReadAccess(LCUser user) {
|
public bool GetUserReadAccess(LCUser user) {
|
||||||
|
@ -90,7 +100,7 @@ namespace LeanCloud.Storage {
|
||||||
throw new ArgumentNullException(nameof(role));
|
throw new ArgumentNullException(nameof(role));
|
||||||
}
|
}
|
||||||
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
||||||
return GetAccess(readers, roleKey);
|
return GetAccess(readAccess, roleKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRoleReadAccess(LCRole role, bool value) {
|
public void SetRoleReadAccess(LCRole role, bool value) {
|
||||||
|
@ -98,7 +108,7 @@ namespace LeanCloud.Storage {
|
||||||
throw new ArgumentNullException(nameof(role));
|
throw new ArgumentNullException(nameof(role));
|
||||||
}
|
}
|
||||||
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
||||||
SetAccess(readers, roleKey, value);
|
SetAccess(readAccess, roleKey, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetRoleWriteAccess(LCRole role) {
|
public bool GetRoleWriteAccess(LCRole role) {
|
||||||
|
@ -106,7 +116,7 @@ namespace LeanCloud.Storage {
|
||||||
throw new ArgumentNullException(nameof(role));
|
throw new ArgumentNullException(nameof(role));
|
||||||
}
|
}
|
||||||
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
||||||
return GetAccess(writers, roleKey);
|
return GetAccess(writeAccess, roleKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRoleWriteAccess(LCRole role, bool value) {
|
public void SetRoleWriteAccess(LCRole role, bool value) {
|
||||||
|
@ -114,34 +124,16 @@ namespace LeanCloud.Storage {
|
||||||
throw new ArgumentNullException(nameof(role));
|
throw new ArgumentNullException(nameof(role));
|
||||||
}
|
}
|
||||||
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
string roleKey = $"{RoleKeyPrefix}{role.ObjectId}";
|
||||||
SetAccess(writers, roleKey, value);
|
SetAccess(writeAccess, roleKey, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LCACL() {
|
bool GetAccess(Dictionary<string, bool> access, string key) {
|
||||||
readers = new HashSet<string>();
|
return access.ContainsKey(key) ?
|
||||||
writers = new HashSet<string>();
|
access[key] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LCACL CreateWithOwner(LCUser owner) {
|
void SetAccess(Dictionary<string, bool> access, string key, bool value) {
|
||||||
if (owner == null) {
|
access[key] = value;
|
||||||
throw new ArgumentNullException(nameof(owner));
|
|
||||||
}
|
|
||||||
LCACL acl = new LCACL();
|
|
||||||
acl.SetUserReadAccess(owner, true);
|
|
||||||
acl.SetUserWriteAccess(owner, true);
|
|
||||||
return acl;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetAccess(HashSet<string> set, string key) {
|
|
||||||
return set.Contains(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetAccess(HashSet<string> set, string key, bool value) {
|
|
||||||
if (value) {
|
|
||||||
set.Add(key);
|
|
||||||
} else {
|
|
||||||
set.Remove(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,20 +8,31 @@ namespace LeanCloud.Storage {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LCCloud {
|
public static class LCCloud {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 调用云函数,结果为 Dictionary 类型
|
/// 调用云函数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
/// <returns></returns>
|
/// <returns>返回类型为 Dictionary<string, object></returns>
|
||||||
public static async Task<Dictionary<string, object>> Run(string name, Dictionary<string, object> parameters = null) {
|
public static async Task<Dictionary<string, object>> Run(string name,
|
||||||
|
Dictionary<string, object> parameters = null) {
|
||||||
string path = $"functions/{name}";
|
string path = $"functions/{name}";
|
||||||
Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>(path, data: parameters);
|
object encodeParams = LCEncoder.Encode(parameters);
|
||||||
|
Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>(path,
|
||||||
|
data: encodeParams);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<object> RPC(string name, Dictionary<string, object> parameters = null) {
|
/// <summary>
|
||||||
|
/// 调用 RPC 云函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <returns>返回类型为 LCObject 容器类型</returns>
|
||||||
|
public static async Task<object> RPC(string name, object parameters = null) {
|
||||||
string path = $"call/{name}";
|
string path = $"call/{name}";
|
||||||
Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>(path, data: parameters);
|
object encodeParams = LCEncoder.Encode(parameters);
|
||||||
|
Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>(path,
|
||||||
|
data: encodeParams);
|
||||||
return LCDecoder.Decode(response["result"]);
|
return LCDecoder.Decode(response["result"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,7 +462,10 @@ namespace LeanCloud.Storage {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return JsonConvert.SerializeObject(LCObjectData.Encode(data));
|
Dictionary<string, object> originalData = LCObjectData.Encode(data);
|
||||||
|
Dictionary<string, object> currentData = estimatedData.Union(originalData.Where(kv => !estimatedData.ContainsKey(kv.Key)))
|
||||||
|
.ToDictionary(k => k.Key, v => v.Value);
|
||||||
|
return JsonConvert.SerializeObject(currentData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -333,6 +333,17 @@ namespace LeanCloud.Storage {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否包含 ACL
|
||||||
|
/// </summary>
|
||||||
|
public bool IncludeACL {
|
||||||
|
get {
|
||||||
|
return Condition.IncludeACL;
|
||||||
|
} set {
|
||||||
|
Condition.IncludeACL = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 跳过
|
/// 跳过
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -49,13 +49,13 @@ namespace LeanCloud.Storage {
|
||||||
|
|
||||||
public bool EmailVerified {
|
public bool EmailVerified {
|
||||||
get {
|
get {
|
||||||
return (bool)this["emailVerified"];
|
return Convert.ToBoolean(this["emailVerified"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MobileVerified {
|
public bool MobileVerified {
|
||||||
get {
|
get {
|
||||||
return (bool)this["mobilePhoneVerified"];
|
return Convert.ToBoolean(this["mobilePhoneVerified"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue