├── .gitignore ├── BmobTest ├── BmobTask.cs ├── BmobTest.csproj ├── BmobTestBase.cs ├── GameObject.cs ├── Properties │ └── AssemblyInfo.cs ├── SimpleTest.cs └── alpha.orderedtest ├── LICENSE ├── README.md ├── build.simple.bat └── core ├── BmobCore.Desktop.csproj ├── BmobCore.Unity.csproj ├── BmobCore.WP8.csproj ├── BmobCore.Win8_1.csproj ├── Properties └── AssemblyInfo.cs └── src ├── Extensions ├── BmobObjectExtension.cs └── MiscExtensions.cs ├── HelloBmob.cs ├── api ├── Bmob.OO.cs ├── Bmob.Task.cs ├── Bmob.cs ├── BmobUnity.cs ├── BmobWindows.cs ├── BmobWindowsPhone.cs └── IBmobAPI.cs ├── config └── Configuration.cs ├── example └── GameObject.cs ├── exception └── BmobException.cs ├── http ├── BmobCommand.cs ├── BmobInteractionObject.cs └── Http.cs ├── io ├── BmobACL.cs ├── BmobDate.cs ├── BmobFile.cs ├── BmobGeoPoint.cs ├── BmobInput.cs ├── BmobInstallation.cs ├── BmobKV.cs ├── BmobObject.cs ├── BmobOutput.cs ├── BmobPointer.cs ├── BmobQuery.cs ├── BmobRelation.cs ├── BmobRole.cs ├── BmobTable.cs ├── BmobTable2.cs ├── BmobUser.cs ├── IBmobOperator.cs ├── IBmobValue.cs ├── IBmobWritable.cs ├── basic │ ├── BmobBoolean.cs │ ├── BmobDouble.cs │ ├── BmobInt.cs │ ├── BmobLong.cs │ └── BmobNumber.cs ├── operator │ ├── Add.cs │ ├── AddRelation.cs │ ├── AddUnique.cs │ ├── Delete.cs │ ├── Increment.cs │ ├── Operate.cs │ ├── Remove.cs │ └── RemoveRelation.cs └── paramater │ ├── BmobBatch.cs │ ├── BmobLocalFile.cs │ ├── BmobRemote.cs │ ├── PushParamter.cs │ ├── SMSParamter.cs │ └── ThumbnailParameter.cs ├── json ├── JsonAdapter.cs ├── SimpleJson.cs └── SimpleJsonParser.cs ├── response ├── BmobResponseParser.cs ├── Create.cs ├── Delete.cs ├── Empty.cs ├── EndPoint.cs ├── Query.cs ├── SMS.cs ├── Status.cs ├── TimeStamp.cs ├── Update.cs └── Upload.cs └── tools ├── BmobArrays.cs ├── BmobDebug.cs └── Utilities.cs /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | 6 | # Autogenerated VS/MD solution and project files 7 | #*.csproj 8 | #*.unityproj 9 | *.sln 10 | *.suo 11 | *.tmp 12 | *.user 13 | *.userprefs 14 | *.pidb 15 | *.booproj 16 | 17 | # Unity3D generated meta files 18 | *.pidb.meta 19 | 20 | # Unity3D Generated File On Crash Reports 21 | sysinfo.txt 22 | 23 | ## 24 | *.log 25 | .vs 26 | bin 27 | target 28 | TestResults 29 | bmob-demo-csharp 30 | -------------------------------------------------------------------------------- /BmobTest/BmobTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {E43B2230-DDC0-4FF6-95D2-37C4EDFF8812} 7 | Library 8 | Properties 9 | BmobTest 10 | BmobTest 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | false 39 | 40 | 41 | 42 | 43 | 3.5 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | {5da85313-cd98-4998-a882-5002fa2ef6e2} 68 | BmobCore 69 | 70 | 71 | 72 | 73 | 74 | 75 | False 76 | 77 | 78 | False 79 | 80 | 81 | False 82 | 83 | 84 | False 85 | 86 | 87 | 88 | 89 | 90 | 91 | 98 | -------------------------------------------------------------------------------- /BmobTest/BmobTestBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | using System.Threading; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | using System.IO; 9 | using cn.bmob.io; 10 | using cn.bmob.json; 11 | using cn.bmob.tools; 12 | using cn.bmob.exception; 13 | 14 | using cn.bmob.api; 15 | 16 | namespace cn.bmob.api.unit 17 | { 18 | 19 | public abstract class BmobTestBase : BmobObject 20 | { 21 | 22 | protected static BmobWindows Bmob = new BmobWindows(); 23 | 24 | private static String LatestObjectIdFile = System.IO.Path.GetTempPath() + "/BmobTest_LatestObjectId"; 25 | public static String LatestObjectId 26 | { 27 | get 28 | { 29 | using (var sr = new StreamReader(LatestObjectIdFile)) 30 | { 31 | return sr.ReadToEnd(); 32 | } 33 | } 34 | set 35 | { 36 | using (var sw = new StreamWriter(LatestObjectIdFile)) 37 | { 38 | sw.Write(value); 39 | } 40 | 41 | } 42 | } 43 | private static String LatestSessionTokenFile = System.IO.Path.GetTempPath() + "/BmobTest_LatestSessionToken"; 44 | public static String LatestSessionToken 45 | { 46 | get 47 | { 48 | using (var sr = new StreamReader(LatestSessionTokenFile)) 49 | { 50 | return sr.ReadToEnd(); 51 | } 52 | } 53 | set 54 | { 55 | using (var sw = new StreamWriter(LatestSessionTokenFile)) 56 | { 57 | sw.Write(value); 58 | } 59 | 60 | } 61 | } 62 | 63 | static BmobTestBase() 64 | { 65 | Bmob.initialize("4414150cb439afdf684d37dc184e0f9f", "e1deb317442129c125b228ddf78e5f22"); 66 | BmobDebug.Register(msg => { Debug.WriteLine(msg); }); 67 | BmobDebug.level = BmobDebug.Level.TRACE; 68 | } 69 | 70 | public virtual void FinishedCallback(T resp, BmobException ex) 71 | { 72 | if (resp != null) 73 | { 74 | var pObjectId = resp.GetType().GetProperty("objectId"); 75 | if (pObjectId != null) 76 | { 77 | var value = (String)pObjectId.GetValue(resp, null); 78 | if (!Utilities.Empty(value)) 79 | LatestObjectId = value; 80 | } 81 | 82 | var pSessionToken = resp.GetType().GetProperty("sessionToken"); 83 | if (pSessionToken != null) 84 | { 85 | var value = (String)pSessionToken.GetValue(resp, null); 86 | if (!Utilities.Empty(value)) 87 | LatestSessionToken = value; 88 | } 89 | } 90 | 91 | Console.WriteLine(); 92 | Console.WriteLine("\n返回结果打印输出(用户可以获取的数据): " + JsonAdapter.JSON.ToDebugJsonString(resp) ); 93 | Console.WriteLine("\n返回结果: " + JsonAdapter.JSON.ToDebugJsonString(resp)); 94 | Console.WriteLine("\n返回结果异常信息输出: " + ex); 95 | 96 | if (ex != null) 97 | { 98 | Assert.Fail(ex.Message); 99 | } 100 | 101 | } 102 | 103 | public String toJson(IBmobWritable data) 104 | { 105 | return ToString(data); 106 | } 107 | 108 | } 109 | 110 | public abstract class WaitRequestFinishTest : BmobTestBase 111 | { 112 | 113 | // http://club.sm160.com/showtopic-886147.aspx 114 | public static ManualResetEvent WaitUnitFinish = new ManualResetEvent(false); 115 | 116 | public static void releaseLock() 117 | { 118 | WaitUnitFinish.Set(); 119 | } 120 | 121 | //~WaitRequestFinishTest() 122 | //{ 123 | // WaitUnitFinish.Close(); 124 | //} 125 | 126 | public override void FinishedCallback(T resp, BmobException ex) 127 | { 128 | try 129 | { 130 | base.FinishedCallback(resp, ex); 131 | } 132 | finally 133 | { 134 | releaseLock(); 135 | } 136 | } 137 | 138 | #region 附加测试特性 139 | // 140 | //使用 TestInitialize 在运行每个测试前先运行代码 141 | public virtual void setup() 142 | { 143 | WaitUnitFinish.Reset(); 144 | } 145 | // 146 | //使用 TestCleanup 在运行完每个测试后运行代码 147 | public virtual void teardown() 148 | { 149 | WaitUnitFinish.WaitOne(); 150 | } 151 | // 152 | #endregion 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /BmobTest/GameObject.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.io; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace cn.bmob.api.unit 9 | { 10 | public class GameObject : BmobTable 11 | { 12 | public override string table 13 | { 14 | get 15 | { 16 | if (fTable != null) 17 | { 18 | return fTable; 19 | } 20 | return base.table; 21 | } 22 | } 23 | 24 | private String fTable; 25 | public GameObject() { } 26 | 27 | public GameObject(string table) 28 | { 29 | this.fTable = table; 30 | } 31 | 32 | public List arrint { get; set; } 33 | public List arrstring { get; set; } 34 | public BmobInt jo { get; set; } 35 | public BmobInt jo2 { get; set; } 36 | public BmobInt obj { get; set; } 37 | public string s { get; set; } 38 | 39 | public BmobPointer user { get; set; } 40 | 41 | public override void readFields(BmobInput input) 42 | { 43 | base.readFields(input); 44 | 45 | this.arrint = input.getList("arrint"); 46 | this.arrstring = input.getList("arrstring"); 47 | this.jo = input.getInt("jo"); 48 | this.jo2 = input.getInt("jo2"); 49 | this.obj = input.getInt("obj"); 50 | this.s = input.getString("s"); 51 | 52 | 53 | this.user = input.Get>("user"); 54 | } 55 | 56 | public override void write(BmobOutput output, Boolean all) 57 | { 58 | base.write(output, all); 59 | 60 | output.Put("arrint", this.arrint); 61 | output.Put("arrstring", this.arrstring); 62 | 63 | output.Put("jo", this.jo); 64 | output.Put("jo2", this.jo2); 65 | output.Put("obj", this.obj); 66 | output.Put("s", this.s); 67 | 68 | output.Put("user", this.user); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /BmobTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下特性集 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("BmobTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("BmobTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | // 请将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("e43b2230-ddc0-4ff6-95d2-37c4edff8812")] 24 | 25 | // 程序集的版本信息由以下四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BmobTest/SimpleTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using cn.bmob.io; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace BmobTest 7 | { 8 | [TestClass] 9 | public class SimpleTest 10 | { 11 | 12 | [TestMethod()] 13 | public void BmobDateTest() 14 | { 15 | BmobDate d = DateTime.Now; 16 | Console.WriteLine(d); 17 | } 18 | 19 | [TestMethod()] 20 | public void RegexTest() 21 | { 22 | var ss = "HTTP/1.1 400 abc.txt"; 23 | ss = Regex.Replace(ss, @"[^ ]* (\d*) .*", "$1"); 24 | Console.WriteLine(ss); 25 | } 26 | 27 | [TestMethod()] 28 | public void BmobIntTest() 29 | { 30 | // set 31 | BmobInt i = new BmobInt(1); 32 | BmobInt i2 = 1; // 有隐士转换 33 | 34 | // get 35 | int iv = i.Get(); 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /BmobTest/alpha.orderedtest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BmobSharp 2 | 3 | Bmob Api Client for .Net 4 | 5 | ## Bmob C# SDK下载地址: 6 | 7 | 8 | 9 | ## 支持平台 10 | 11 | * Windows Deskstop 即.Net C#的项目 12 | * WindowsPhone8 13 | * Windows 8.1 14 | * Unity 15 | 16 | ## 示例 17 | 18 | 参见[bmob-demo-csharp](https://github.com/bmob/bmob-demo-csharp),examples目录下三个项目windows-destop、unity、windowphone8简单介绍了Bmob的基本功能,是了解bmob和学习bmob的不二之选。 19 | 20 | ## 文档 21 | 22 | 源代码中注释比较少,如果对源码中功能弄的不是很明白,查看[文档](https://github.com/bmob/bmob-demo-csharp/wiki)对理解代码和使用有更深的认识。 23 | 24 | * 25 | 26 | ## 开发环境搭建 27 | 28 | * 软件下载/安装 29 | 30 | * [Visual Studio Community 2015](https://www.visualstudio.com/zh-cn/visual-studio-homepage-vs.aspx) 31 | * [Unity3d](http://unity3d.com/cn/get-unity/download?ref=personal) 32 | 33 | * 开发环境说明 34 | 35 | * Window10 / VS2015 / Unity 5.1.0f3 36 | * Mac OS X 10.9 / Xcode 5.1 / Unity 5.2.1f1 37 | 38 | 如果仅仅是编译项目,可以不需要安装Unity3d,下载Unity3d的Engine和Editor动态链接库文件就行了。 39 | 40 | 41 | * 文件结构说明 42 | 43 | * core 全部源代码放在这个目录下。直接运行csproj就可以编辑运行代码了。 44 | * BmobTest 提供了基于desktop平台的测试用例,便于接口的调试。 45 | * 源码中提供了**build.simple.bat**用于一键生成各个平台的dll文件。 46 | 47 | * Unity源码调试设置 48 | 49 | * 删除原来的`Assets/libs/Bmob-Unity.dll`。 50 | * 把源代码`core/src`目录拷贝到`Assets/classes/`下。 51 | * 打开Unity重新编译,把BmobUntiy对象拖拽到摄像机上,重新设置AppId和RestKey。 52 | ![](https://cloud.githubusercontent.com/assets/667902/10300818/2742146a-6c2e-11e5-8367-b2304abfc2dd.jpg) 53 | 54 | * Unity输出日志位置: 55 | 56 | * Unity Mac环境配置 57 | 58 | ![](https://raw.githubusercontent.com/bmob/bmob-demo-csharp/master/images/unity-ios-simulator.png) 59 | 60 | ![](https://cloud.githubusercontent.com/assets/667902/10384088/a2ff6304-6e69-11e5-8f2e-3221e8ac7851.png) 61 | 62 | ![](https://cloud.githubusercontent.com/assets/667902/10384074/637611a6-6e69-11e5-9406-a68414742547.png) 63 | 64 | ## 注意事项 65 | 66 | ### 文件/图片无法上传的问题 67 | 68 | - 直接使用源码,不要用dll文件 69 | - 也可以在原来源码基础上,修改[Configuration.cs](`https://github.com/bmob/BmobSharp/blob/master/core/src/config/Configuration.cs`) 文件为最新版 70 | 71 | 72 | ### Bmob Vip域名加速服务 73 | 74 | - 修改[Configuration.cs](`https://github.com/bmob/BmobSharp/blob/master/core/src/config/Configuration.cs`) 文件 75 | 76 | ### Bmob Vip域名加速服务 77 | 78 | 2022年支持重置域名,Bmob.resetDomain("http://api.xxx.com"); 初始化前修改未自己备案api域名。 79 | 80 | ### 兼容Unity2017、2018的问题 81 | 82 | - 直接使用源码,不要用dll文件 83 | -------------------------------------------------------------------------------- /build.simple.bat: -------------------------------------------------------------------------------- 1 | @echo on 2 | 3 | set config=%1 4 | if "%config%" == "" ( 5 | set config=Release 6 | ) 7 | 8 | REM Build 9 | %WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe core/BmobCore.Desktop.csproj /p:Configuration=%config% /m /v:M /fl /flp:LogFile=msbuild.Desktop.log;Verbosity=Normal /nr:true /p:BuildInParallel=true /p:RestorePackages=true /t:Clean,Rebuild 10 | if not "%errorlevel%"=="0" goto failure 11 | 12 | %WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe core/BmobCore.Unity.csproj /p:Configuration=%config% /m /v:M /fl /flp:LogFile=msbuild.Unity.log;Verbosity=Normal /nr:true /p:BuildInParallel=true /p:RestorePackages=true /t:Clean,Rebuild 13 | if not "%errorlevel%"=="0" goto failure 14 | 15 | %WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe core/BmobCore.Win8_1.csproj /p:Configuration=%config% /m /v:M /fl /flp:LogFile=msbuild.Win8_1.log;Verbosity=Normal /nr:true /p:BuildInParallel=true /p:RestorePackages=true /t:Clean,Rebuild 16 | if not "%errorlevel%"=="0" goto failure 17 | 18 | REM 没有安装wp8 SDK了 19 | REM %WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe core/BmobCore.WP8.csproj /p:Configuration=%config% /m /v:M /fl /flp:LogFile=msbuild.WP8.log;Verbosity=Normal /nr:true /p:BuildInParallel=true /p:RestorePackages=true /t:Clean,Rebuild 20 | REM if not "%errorlevel%"=="0" goto failure 21 | 22 | REM delete the old stuff 23 | 24 | rd target /s /q 25 | rd bmob-demo-csharp\examples\bmob-desktop-demo\lib\ /s /q 26 | rd bmob-demo-csharp\examples\bmob-unity-demo\Assets\libs /s /q 27 | rd bmob-demo-csharp\examples\bmob-windowsphone-demo\lib\ /s /q 28 | 29 | if not exist target\Unity mkdir target\Unity\ 30 | if not exist target\Windows mkdir target\Windows\ 31 | if not exist target\WindowsPhone8 mkdir target\WindowsPhone8\ 32 | if not exist target\Win8_1 mkdir target\Win8_1\ 33 | 34 | if not exist bmob-demo-csharp\examples\bmob-desktop-demo\lib\ mkdir bmob-demo-csharp\examples\bmob-desktop-demo\lib\ 35 | if not exist bmob-demo-csharp\examples\bmob-unity-demo\Assets\libs mkdir bmob-demo-csharp\examples\bmob-unity-demo\Assets\libs 36 | if not exist bmob-demo-csharp\examples\bmob-windowsphone-demo\lib\ mkdir bmob-demo-csharp\examples\bmob-windowsphone-demo\lib\ 37 | 38 | rem unity 39 | 40 | copy Core\bin\Release\Bmob-Unity.dll target\Unity\ 41 | 42 | copy Core\bin\Release\Bmob-Unity.XML target\Unity 43 | 44 | rem desktop 45 | 46 | copy Core\bin\Release\Bmob-Windows.dll target\Windows\ 47 | 48 | copy Core\bin\Release\Bmob-Windows.XML target\Windows\ 49 | 50 | rem wp8 51 | 52 | copy Core\bin\Release\Bmob-WP8.dll target\WindowsPhone8\ 53 | 54 | copy Core\bin\Release\Bmob-WP8.XML target\WindowsPhone8\ 55 | 56 | rem win8_1 57 | 58 | copy Core\bin\Release\Bmob-Win8_1.dll target\Win8_1\ 59 | 60 | copy Core\bin\Release\Bmob-Win8_1.XML target\Win8_1\ 61 | 62 | copy Core\bin\Release\Bmob-Unity.dll bmob-demo-csharp\examples\bmob-unity-demo\Assets\libs\ 63 | copy Core\bin\Release\Bmob-WP8.dll bmob-demo-csharp\examples\bmob-windowsphone-demo\lib\ 64 | copy Core\bin\Release\Bmob-Windows.dll bmob-demo-csharp\examples\bmob-desktop-demo\lib\ 65 | 66 | :success 67 | 68 | REM compile success 69 | 70 | goto end 71 | 72 | :failure 73 | 74 | REM compile fail 75 | 76 | goto end 77 | 78 | :end 79 | 80 | pause -------------------------------------------------------------------------------- /core/BmobCore.Desktop.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5DA85313-CD98-4998-A882-5002FA2EF6E2} 8 | Library 9 | Properties 10 | cn.bmob 11 | Bmob-Windows 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | TRACE;DEBUG;FRAMEWORK,NET4 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE;FRAMEWORK,NET4 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Code 45 | 46 | 47 | Code 48 | 49 | 50 | Code 51 | 52 | 53 | Code 54 | 55 | 56 | Code 57 | 58 | 59 | 60 | Code 61 | 62 | 63 | Code 64 | 65 | 66 | Code 67 | 68 | 69 | Code 70 | 71 | 72 | 73 | 74 | Code 75 | 76 | 77 | Code 78 | 79 | 80 | Code 81 | 82 | 83 | Code 84 | 85 | 86 | Code 87 | 88 | 89 | Code 90 | 91 | 92 | Code 93 | 94 | 95 | Code 96 | 97 | 98 | Code 99 | 100 | 101 | Code 102 | 103 | 104 | Code 105 | 106 | 107 | Code 108 | 109 | 110 | 111 | Code 112 | 113 | 114 | Code 115 | 116 | 117 | Code 118 | 119 | 120 | Code 121 | 122 | 123 | Code 124 | 125 | 126 | Code 127 | 128 | 129 | Code 130 | 131 | 132 | Code 133 | 134 | 135 | 136 | Code 137 | 138 | 139 | Code 140 | 141 | 142 | Code 143 | 144 | 145 | Code 146 | 147 | 148 | Code 149 | 150 | 151 | Code 152 | 153 | 154 | Code 155 | 156 | 157 | Code 158 | 159 | 160 | Code 161 | 162 | 163 | Code 164 | 165 | 166 | Code 167 | 168 | 169 | 170 | 171 | Code 172 | 173 | 174 | 175 | 176 | Code 177 | 178 | 179 | Code 180 | 181 | 182 | 183 | 184 | 185 | Code 186 | 187 | 188 | Code 189 | 190 | 191 | Code 192 | 193 | 194 | Code 195 | 196 | 197 | Code 198 | 199 | 200 | Code 201 | 202 | 203 | Code 204 | 205 | 206 | 207 | 208 | Code 209 | 210 | 211 | Code 212 | 213 | 214 | Code 215 | 216 | 217 | Code 218 | 219 | 220 | Code 221 | 222 | 223 | 224 | 231 | -------------------------------------------------------------------------------- /core/BmobCore.Unity.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {BE007CD7-75A3-4839-A074-6A9732CB7CA4} 9 | Library 10 | Properties 11 | cn.bmob 12 | Bmob-Unity 13 | v3.5 14 | 512 15 | 16 | 17 | True 18 | full 19 | False 20 | bin\Debug\ 21 | TRACE;DEBUG;Unity 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | True 28 | bin\Release\ 29 | TRACE;Unity 30 | prompt 31 | 4 32 | bin\Release\Bmob-Unity.XML 33 | 34 | 35 | 36 | 37 | 38 | C:\Program Files\Unity\Editor\Data\Managed\UnityEditor.dll 39 | 40 | 41 | C:\Program Files\Unity\Editor\Data\Managed\UnityEngine.dll 42 | 43 | 44 | 45 | 46 | Code 47 | 48 | 49 | Code 50 | 51 | 52 | Code 53 | 54 | 55 | Code 56 | 57 | 58 | Code 59 | 60 | 61 | 62 | Code 63 | 64 | 65 | Code 66 | 67 | 68 | Code 69 | 70 | 71 | Code 72 | 73 | 74 | 75 | 76 | Code 77 | 78 | 79 | Code 80 | 81 | 82 | Code 83 | 84 | 85 | Code 86 | 87 | 88 | Code 89 | 90 | 91 | Code 92 | 93 | 94 | Code 95 | 96 | 97 | Code 98 | 99 | 100 | Code 101 | 102 | 103 | Code 104 | 105 | 106 | Code 107 | 108 | 109 | Code 110 | 111 | 112 | 113 | Code 114 | 115 | 116 | Code 117 | 118 | 119 | Code 120 | 121 | 122 | Code 123 | 124 | 125 | Code 126 | 127 | 128 | Code 129 | 130 | 131 | Code 132 | 133 | 134 | Code 135 | 136 | 137 | 138 | Code 139 | 140 | 141 | Code 142 | 143 | 144 | Code 145 | 146 | 147 | Code 148 | 149 | 150 | Code 151 | 152 | 153 | Code 154 | 155 | 156 | Code 157 | 158 | 159 | Code 160 | 161 | 162 | Code 163 | 164 | 165 | Code 166 | 167 | 168 | Code 169 | 170 | 171 | 172 | 173 | Code 174 | 175 | 176 | 177 | 178 | Code 179 | 180 | 181 | Code 182 | 183 | 184 | 185 | 186 | 187 | Code 188 | 189 | 190 | Code 191 | 192 | 193 | Code 194 | 195 | 196 | Code 197 | 198 | 199 | Code 200 | 201 | 202 | Code 203 | 204 | 205 | Code 206 | 207 | 208 | 209 | 210 | Code 211 | 212 | 213 | Code 214 | 215 | 216 | Code 217 | 218 | 219 | Code 220 | 221 | 222 | Code 223 | 224 | 225 | 226 | 233 | -------------------------------------------------------------------------------- /core/BmobCore.WP8.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {5148698C-E455-4B0B-9AB6-42A8BA8775EB} 9 | {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 10 | Library 11 | Properties 12 | cn.bmob 13 | Bmob-WP8 14 | WindowsPhone 15 | v8.0 16 | $(TargetFrameworkVersion) 17 | false 18 | true 19 | 11.0 20 | true 21 | 22 | 23 | true 24 | full 25 | false 26 | Bin\Debug 27 | TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE;WP8 28 | true 29 | true 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | pdbonly 37 | true 38 | Bin\Release 39 | TRACE;SILVERLIGHT;WINDOWS_PHONE;WP8 40 | true 41 | true 42 | prompt 43 | 4 44 | Bin\Release\Bmob-WP8.XML 45 | 46 | 47 | true 48 | full 49 | false 50 | Bin\x86\Debug 51 | DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE 52 | true 53 | true 54 | prompt 55 | 4 56 | 57 | 58 | pdbonly 59 | true 60 | Bin\x86\Release 61 | TRACE;SILVERLIGHT;WINDOWS_PHONE 62 | true 63 | true 64 | prompt 65 | 4 66 | 67 | 68 | true 69 | full 70 | false 71 | Bin\ARM\Debug 72 | DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE 73 | true 74 | true 75 | prompt 76 | 4 77 | 78 | 79 | pdbonly 80 | true 81 | Bin\ARM\Release 82 | TRACE;SILVERLIGHT;WINDOWS_PHONE 83 | true 84 | true 85 | prompt 86 | 4 87 | 88 | 89 | 90 | 91 | Code 92 | 93 | 94 | Code 95 | 96 | 97 | Code 98 | 99 | 100 | Code 101 | 102 | 103 | Code 104 | 105 | 106 | 107 | Code 108 | 109 | 110 | Code 111 | 112 | 113 | Code 114 | 115 | 116 | Code 117 | 118 | 119 | 120 | 121 | Code 122 | 123 | 124 | Code 125 | 126 | 127 | Code 128 | 129 | 130 | Code 131 | 132 | 133 | Code 134 | 135 | 136 | Code 137 | 138 | 139 | Code 140 | 141 | 142 | Code 143 | 144 | 145 | Code 146 | 147 | 148 | Code 149 | 150 | 151 | Code 152 | 153 | 154 | Code 155 | 156 | 157 | 158 | Code 159 | 160 | 161 | Code 162 | 163 | 164 | Code 165 | 166 | 167 | Code 168 | 169 | 170 | Code 171 | 172 | 173 | Code 174 | 175 | 176 | Code 177 | 178 | 179 | Code 180 | 181 | 182 | 183 | Code 184 | 185 | 186 | Code 187 | 188 | 189 | Code 190 | 191 | 192 | Code 193 | 194 | 195 | Code 196 | 197 | 198 | Code 199 | 200 | 201 | Code 202 | 203 | 204 | Code 205 | 206 | 207 | Code 208 | 209 | 210 | Code 211 | 212 | 213 | Code 214 | 215 | 216 | 217 | 218 | Code 219 | 220 | 221 | 222 | 223 | Code 224 | 225 | 226 | Code 227 | 228 | 229 | 230 | 231 | 232 | Code 233 | 234 | 235 | Code 236 | 237 | 238 | Code 239 | 240 | 241 | Code 242 | 243 | 244 | Code 245 | 246 | 247 | Code 248 | 249 | 250 | Code 251 | 252 | 253 | 254 | 255 | Code 256 | 257 | 258 | Code 259 | 260 | 261 | Code 262 | 263 | 264 | Code 265 | 266 | 267 | Code 268 | 269 | 270 | 271 | 272 | 273 | 280 | -------------------------------------------------------------------------------- /core/BmobCore.Win8_1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 12.0 6 | Debug 7 | AnyCPU 8 | {2A2610D3-DA6D-4F15-BF4A-B57B85FED05C} 9 | Library 10 | Properties 11 | cn.bmob 12 | Bmob-Win8_1 13 | zh-CN 14 | 512 15 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 16 | Profile32 17 | v4.6 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | TRACE;DEBUG;NETFX_CORE;WINDOWS_UAP;FRAMEWORK;WIN8_1 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE;NETFX_CORE;WINDOWS_UAP;FRAMEWORK;WIN8_1 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Code 46 | 47 | 48 | Code 49 | 50 | 51 | Code 52 | 53 | 54 | Code 55 | 56 | 57 | Code 58 | 59 | 60 | 61 | Code 62 | 63 | 64 | Code 65 | 66 | 67 | Code 68 | 69 | 70 | Code 71 | 72 | 73 | 74 | 75 | Code 76 | 77 | 78 | Code 79 | 80 | 81 | Code 82 | 83 | 84 | Code 85 | 86 | 87 | Code 88 | 89 | 90 | Code 91 | 92 | 93 | Code 94 | 95 | 96 | Code 97 | 98 | 99 | Code 100 | 101 | 102 | Code 103 | 104 | 105 | Code 106 | 107 | 108 | Code 109 | 110 | 111 | 112 | Code 113 | 114 | 115 | Code 116 | 117 | 118 | Code 119 | 120 | 121 | Code 122 | 123 | 124 | Code 125 | 126 | 127 | Code 128 | 129 | 130 | Code 131 | 132 | 133 | Code 134 | 135 | 136 | 137 | Code 138 | 139 | 140 | Code 141 | 142 | 143 | Code 144 | 145 | 146 | Code 147 | 148 | 149 | Code 150 | 151 | 152 | Code 153 | 154 | 155 | Code 156 | 157 | 158 | Code 159 | 160 | 161 | Code 162 | 163 | 164 | Code 165 | 166 | 167 | Code 168 | 169 | 170 | 171 | 172 | Code 173 | 174 | 175 | 176 | 177 | Code 178 | 179 | 180 | Code 181 | 182 | 183 | 184 | 185 | 186 | Code 187 | 188 | 189 | Code 190 | 191 | 192 | Code 193 | 194 | 195 | Code 196 | 197 | 198 | Code 199 | 200 | 201 | Code 202 | 203 | 204 | Code 205 | 206 | 207 | 208 | 209 | Code 210 | 211 | 212 | Code 213 | 214 | 215 | Code 216 | 217 | 218 | Code 219 | 220 | 221 | Code 222 | 223 | 224 | 225 | 232 | -------------------------------------------------------------------------------- /core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Bmob Core")] 9 | [assembly: AssemblyDescription("Bmob CSharp API")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("广州市比目网络科技有限公司")] 12 | [assembly: AssemblyProduct("Bmob SDK")] 13 | [assembly: AssemblyCopyright("Copyright © Bmob 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("5da85313-cd98-4998-a882-5002fa2ef6e2")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.5.2.0")] 36 | [assembly: AssemblyFileVersion("1.5.2.0")] 37 | 38 | [assembly: InternalsVisibleTo("BmobTest")] 39 | -------------------------------------------------------------------------------- /core/src/Extensions/BmobObjectExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | using cn.bmob.api; 3 | using cn.bmob.io; 4 | using cn.bmob.response; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Linq.Expressions; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace cn.bmob.Extensions 13 | { 14 | public static class BmobObjectExtensions 15 | { 16 | public static Object Select(this BmobObject input) 17 | { 18 | return null; 19 | } 20 | 21 | public static BmobQuery Select(this BmobQuery input) 22 | { 23 | return input; 24 | } 25 | 26 | public static BmobQuery Where(this String input, Expression> predicate) 27 | { 28 | return input; 29 | } 30 | 31 | public static BmobQuery Order(this BmobQuery input) 32 | { 33 | return input; 34 | } 35 | } 36 | } 37 | */ -------------------------------------------------------------------------------- /core/src/Extensions/MiscExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net; 6 | using System.Text; 7 | 8 | namespace cn.bmob.Extensions 9 | { 10 | /// 11 | /// copy restsharp 12 | /// 13 | public static class MiscExtensions 14 | { 15 | #if WIN8_1 16 | public static void Close(this HttpWebResponse m) 17 | { 18 | m.Dispose(); 19 | } 20 | 21 | public static Type[] GetGenericArguments(this Type t) 22 | { 23 | return System.Reflection.IntrospectionExtensions.GetTypeInfo(t).GenericTypeArguments; 24 | } 25 | 26 | public static bool IsAssignableFrom(this Type a, Type b) 27 | { 28 | var at = System.Reflection.IntrospectionExtensions.GetTypeInfo(a); 29 | var bt = System.Reflection.IntrospectionExtensions.GetTypeInfo(b); 30 | return at.IsAssignableFrom(bt); 31 | } 32 | #endif 33 | 34 | public static bool IsGenericType(this Type t) 35 | { 36 | #if WIN8_1 37 | return System.Reflection.IntrospectionExtensions.GetTypeInfo(t).IsGenericType; 38 | #else 39 | return t.IsGenericType; 40 | #endif 41 | } 42 | 43 | /// 44 | /// Read a stream into a byte array 45 | /// 46 | /// Stream to read 47 | /// byte[] 48 | public static byte[] ReadAsBytes(this Stream input) 49 | { 50 | byte[] buffer = new byte[16 * 1024]; 51 | using (MemoryStream ms = new MemoryStream()) 52 | { 53 | int read; 54 | while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 55 | { 56 | ms.Write(buffer, 0, read); 57 | } 58 | return ms.ToArray(); 59 | } 60 | } 61 | 62 | public static byte[] GetBytes(this string s) 63 | { 64 | return Encoding.UTF8.GetBytes(s); 65 | } 66 | 67 | public static String ToBase64(this string s) 68 | { 69 | return Convert.ToBase64String(s.GetBytes()); 70 | } 71 | 72 | public static String ToBase64(this byte[] s) 73 | { 74 | return Convert.ToBase64String(s); 75 | } 76 | 77 | public static String FromBase64(this string s) 78 | { 79 | return Convert.FromBase64String(s).AsString(); 80 | } 81 | 82 | private static char[] HEX_ALPHA = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 83 | public static String ToHexString(this byte[] src) 84 | { 85 | if (src == null || src.Length <= 0) 86 | { 87 | return null; 88 | } 89 | 90 | StringBuilder sb = new StringBuilder(); 91 | for (int i = 0; i < src.Length; i++) 92 | { 93 | sb.Append(HEX_ALPHA[src[i] >> 4 & 0xF]); 94 | sb.Append(HEX_ALPHA[src[i] & 0xF]); 95 | } 96 | return sb.ToString(); 97 | } 98 | 99 | /// 100 | /// Converts a byte array to a string, using its byte order mark to convert it to the right encoding. 101 | /// http://www.shrinkrays.net/code-snippets/csharp/an-extension-method-for-converting-a-byte-array-to-a-string.aspx 102 | /// 103 | /// An array of bytes to convert 104 | /// The byte as a string. 105 | public static string AsString(this byte[] buffer) 106 | { 107 | if (buffer == null) return ""; 108 | 109 | // UTF8 as default 110 | Encoding encoding = Encoding.UTF8; 111 | 112 | #if FRAMEWORK 113 | return encoding.GetString(buffer, 0, buffer.Length); 114 | #else 115 | if (buffer == null || buffer.Length == 0) 116 | return ""; 117 | 118 | /* 119 | EF BB BF UTF-8 120 | FF FE UTF-16 little endian 121 | FE FF UTF-16 big endian 122 | FF FE 00 00 UTF-32, little endian 123 | 00 00 FE FF UTF-32, big-endian 124 | */ 125 | 126 | if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) 127 | { 128 | encoding = Encoding.UTF8; 129 | } 130 | else if (buffer[0] == 0xfe && buffer[1] == 0xff) 131 | { 132 | encoding = Encoding.Unicode; 133 | } 134 | else if (buffer[0] == 0xfe && buffer[1] == 0xff) 135 | { 136 | encoding = Encoding.BigEndianUnicode; // utf-16be 137 | } 138 | 139 | using (MemoryStream stream = new MemoryStream()) 140 | { 141 | stream.Write(buffer, 0, buffer.Length); 142 | stream.Seek(0, SeekOrigin.Begin); 143 | using (StreamReader reader = new StreamReader(stream, encoding)) 144 | { 145 | return reader.ReadToEnd(); 146 | } 147 | } 148 | #endif 149 | } 150 | 151 | /// 152 | /// 将列表连接为字符串,连接符为,号 153 | /// 154 | /// 列表 155 | /// 连接之后的字符串 156 | public static String join(this IList list) 157 | { 158 | return list.join(','); 159 | } 160 | 161 | /// 162 | /// 将列表连接为字符串 163 | /// 164 | /// 列表 165 | /// 连接符 166 | /// 连接之后的字符串 167 | public static String join(this IList list, char separator) 168 | { 169 | StringBuilder result = new StringBuilder(); 170 | 171 | bool first = true; 172 | foreach (object ele in list) 173 | { 174 | if (first) 175 | { 176 | first = false; 177 | } 178 | else 179 | { 180 | result.Append(separator); 181 | } 182 | 183 | result.Append(ele.ToString()); 184 | } 185 | return result.ToString(); 186 | } 187 | 188 | public static string UrlEncode(this string input) 189 | { 190 | const int maxLength = 32766; 191 | if (input == null) 192 | throw new ArgumentNullException("input"); 193 | 194 | if (input.Length <= maxLength) 195 | return Uri.EscapeDataString(input); 196 | 197 | StringBuilder sb = new StringBuilder(input.Length * 2); 198 | int index = 0; 199 | while (index < input.Length) 200 | { 201 | int length = Math.Min(input.Length - index, maxLength); 202 | string subString = input.Substring(index, length); 203 | sb.Append(Uri.EscapeDataString(subString)); 204 | index += subString.Length; 205 | } 206 | 207 | return sb.ToString(); 208 | } 209 | 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /core/src/api/Bmob.OO.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.exception; 2 | using cn.bmob.http; 3 | using cn.bmob.io; 4 | using cn.bmob.response; 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace cn.bmob.api 9 | { 10 | public partial class Bmob 11 | { 12 | 13 | 14 | /// 15 | /// 文件上传 16 | /// 17 | /// 18 | /// 19 | public void FileUpload(String localPath, BmobCallback callback) 20 | { 21 | #if !WIN8_1 22 | this.FileUpload(new BmobLocalFile(localPath), callback); 23 | #else 24 | callback(null, new BmobException("SDK WIN8.1暂不支持该方法!!!")); 25 | #endif 26 | } 27 | 28 | public void RequestSmsCode(string mobilePhoneNumber, BmobCallback callback) 29 | { 30 | this.RequestSmsCode(mobilePhoneNumber, null, callback); 31 | } 32 | 33 | public void Endpoint(String eMethod, BmobCallback> callback) 34 | { 35 | this.Endpoint(eMethod, new Dictionary(), callback); 36 | } 37 | 38 | public void Create(T data, BmobCallback callback) where T : BmobTable 39 | { 40 | this.Create(data.table, data, callback); 41 | } 42 | 43 | public void Get(T data, BmobCallback callback) where T : BmobTable 44 | { 45 | this.Get(data.table, data.objectId, callback); 46 | } 47 | 48 | public void Update(T data, BmobCallback callback) where T : BmobTable 49 | { 50 | this.Update(data.table, data.objectId, data, callback); 51 | } 52 | 53 | public void Delete(T data, BmobCallback callback) where T : BmobTable 54 | { 55 | this.Delete(data.table, data.objectId, callback); 56 | } 57 | 58 | /// 59 | /// 登录 60 | /// 61 | /// 返回内置的BmobUser对象。如果User表中添加了字段,请使用Login泛型调用方式。 62 | public void Login(String username, String pwd, BmobCallback callback) 63 | { 64 | this.Login(username, pwd, callback); 65 | } 66 | 67 | /// 68 | /// 使用默认的BmobUser进行注册。即不添加任何额外的字段情况下使用。 69 | /// 70 | public void Signup(BmobUser user, BmobCallback callback) 71 | { 72 | this.Signup(user, callback); 73 | } 74 | 75 | public void UpdateUser(T data, BmobCallback callback) where T : BmobUser 76 | { 77 | this.UpdateUser(data.objectId, data, data.sessionToken, callback); 78 | } 79 | 80 | public void DeleteUser(T data, BmobCallback callback) where T : BmobUser 81 | { 82 | this.DeleteUser(data.objectId, data.sessionToken, callback); 83 | } 84 | 85 | public void FileDelete(BmobFile file, BmobCallback callback) 86 | { 87 | this.FileDelete(file.url, callback); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /core/src/api/BmobUnity.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5 || UNITY_4 || UNITY_4_6 || UNITY_2017 || UNITY_2018 2 | #define Unity 3 | #endif 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | using System.Text; 9 | using System.Collections; 10 | using System.Linq; 11 | using cn.bmob.io; 12 | using cn.bmob.http; 13 | using cn.bmob.config; 14 | using cn.bmob.exception; 15 | using cn.bmob.response; 16 | using System.Text.RegularExpressions; 17 | 18 | #if Unity 19 | 20 | using UnityEngine; 21 | using System.Collections.ObjectModel; 22 | using cn.bmob.tools; 23 | 24 | namespace System 25 | { 26 | //public delegate void Action(T1 arg1, T2 arg2); 27 | 28 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); 29 | 30 | public class AggregateException : Exception 31 | { 32 | // 33 | // Properties 34 | // 35 | public ReadOnlyCollection InnerExceptions 36 | { 37 | get; 38 | private set; 39 | } 40 | 41 | // 42 | // Constructors 43 | // 44 | public AggregateException(IEnumerable innerExceptions) 45 | { 46 | this.InnerExceptions = new ReadOnlyCollection(innerExceptions.ToList()); 47 | } 48 | 49 | // 50 | // Methods 51 | // 52 | public AggregateException Flatten() 53 | { 54 | List list = new List(); 55 | foreach (Exception current in this.InnerExceptions) 56 | { 57 | AggregateException ex = current as AggregateException; 58 | if (ex != null) 59 | { 60 | list.AddRange(ex.Flatten().InnerExceptions); 61 | } 62 | else 63 | { 64 | list.Add(current); 65 | } 66 | } 67 | return new AggregateException(list); 68 | } 69 | 70 | public override string ToString() 71 | { 72 | StringBuilder stringBuilder = new StringBuilder(base.ToString()); 73 | foreach (Exception current in this.InnerExceptions) 74 | { 75 | stringBuilder.AppendLine("\n-----------------"); 76 | stringBuilder.AppendLine(current.ToString()); 77 | } 78 | return stringBuilder.ToString(); 79 | } 80 | } 81 | 82 | namespace Threading 83 | { 84 | namespace Tasks 85 | { 86 | } 87 | } 88 | 89 | } 90 | 91 | 92 | namespace cn.bmob.api 93 | { 94 | 95 | public partial class Bmob : MonoBehaviour 96 | { 97 | } 98 | 99 | /// 100 | /// Bmob SDK入口类,开发者直接调用该类即可获取Bmob提供的各种服务。 101 | /// 102 | public class BmobUnity : Bmob 103 | { 104 | 105 | private MonoBehaviour go; 106 | 107 | /// 108 | /// Unity Behavior 109 | /// 110 | public void Update() { } 111 | 112 | public BmobUnity() 113 | { 114 | Configuration.PLATFORM = SDKTarget.Unity; 115 | go = this; 116 | } 117 | 118 | /// 119 | /// 仅用于在界面设置 120 | /// 121 | public String ApplicationId; 122 | public String RestKey; 123 | 124 | internal override string appKey 125 | { 126 | get 127 | { 128 | return ApplicationId; 129 | } 130 | set 131 | { 132 | ApplicationId = value; 133 | base.appKey = value; 134 | } 135 | } 136 | internal override String restKey 137 | { 138 | get { return RestKey; } 139 | set 140 | { 141 | RestKey = value; 142 | base.restKey = value; 143 | } 144 | } 145 | 146 | 147 | internal override void submit(BmobCommand command, BmobCallback callback) 148 | { 149 | this.go.StartCoroutine(execute(command, callback)); 150 | } 151 | 152 | /// 153 | /// 调用 154 | /// 155 | private IEnumerator execute(BmobCommand command, BmobCallback callback) 156 | { 157 | return command.execute(Request, callback); 158 | } 159 | 160 | protected virtual IEnumerator Request(String url, String method, String contentType, byte[] postData, IDictionary headers, Action callback) 161 | { 162 | BmobOutput.Save(headers, "Content-Type", contentType); 163 | 164 | // http://answers.unity3d.com/questions/785798/put-with-wwwform.html 165 | // www不支持PUT和DELETE操作,需要服务端支持!!服务端已添加filter 2015年9月25日09:57:52 166 | BmobOutput.Save(headers, "X-HTTP-Method-Override", method); 167 | 168 | return RequestInternal(url, method, postData, headers, callback); 169 | } 170 | 171 | private IEnumerator RequestInternal(String url, String method, byte[] postData, IDictionary headers, Action callback) 172 | { 173 | var table = new Dictionary(); 174 | foreach (var header in headers) 175 | { 176 | table.Add(header.Key, header.Value); 177 | } 178 | WWW www = new WWW(url, method.Equals("GET") ? null : postData, table); 179 | 180 | yield return www; 181 | 182 | var error = www.error; 183 | var text = www.text; 184 | 185 | BmobDebug.T("[ BmobUnity ] after fetch www message, Response: '" + text + "', Error: ' " + error + "'"); 186 | 187 | 188 | var status = new Status(200, error); 189 | 190 | // if (www.responseHeaders.ContainsKey("STATUS")) 191 | // { 192 | // var respStatus = www.responseHeaders["STATUS"]; 193 | // var statusCode = Regex.Replace(respStatus, @"[^ ]* (\d*) .*", "$1"); 194 | // status.code = Convert.ToInt32(statusCode); 195 | // } 196 | try{ 197 | if (www.responseHeaders.ContainsKey("STATUS")) 198 | { 199 | var respStatus = www.responseHeaders["STATUS"]; 200 | var statusCode = Regex.Replace(respStatus, @"[^ ]* (\d*) .*", "$1"); 201 | status.code = Convert.ToInt32(statusCode); 202 | } 203 | }catch(NullReferenceException e){ 204 | BmobDebug.T("www.responseHeaders方法有问题: "+e); 205 | // Unity 2017.2.0f3 (64-bit) 版本,www.responseHeaders方法在真机上有问题。zq,2017.10.24 206 | if(error != null){ 207 | foreach (Match match in Regex.Matches(error, @" *(\d*) *")){ 208 | status.code = Convert.ToInt32(match.Value); 209 | break; 210 | } 211 | } 212 | } 213 | 214 | 215 | if (error != null && error != "") 216 | { 217 | // 返回了错误的内容,不表示返回的内容就为空!! 218 | callback(text, status, new BmobException(error)); 219 | } 220 | else 221 | { 222 | callback(text, status, null); 223 | } 224 | } 225 | 226 | } 227 | 228 | } 229 | 230 | #endif 231 | -------------------------------------------------------------------------------- /core/src/api/BmobWindows.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using cn.bmob.io; 5 | using cn.bmob.response; 6 | using System.Text; 7 | using System.Collections; 8 | using System.Net; 9 | using System.IO; 10 | using System.Diagnostics; 11 | using cn.bmob.http; 12 | using cn.bmob.Extensions; 13 | using cn.bmob.config; 14 | using cn.bmob.exception; 15 | using System.Text.RegularExpressions; 16 | 17 | namespace cn.bmob.api 18 | { 19 | 20 | #if FRAMEWORK || WINDOWS_PHONE 21 | public class BmobWindows : Bmob 22 | { 23 | 24 | public BmobWindows() 25 | { 26 | Configuration.PLATFORM = SDKTarget.WindowsDesktop; 27 | } 28 | 29 | internal override void submit(BmobCommand command, BmobCallback callback) 30 | { 31 | command.execute(Request, callback); 32 | } 33 | 34 | /* internal */ 35 | public int Request(String url, String method, String contentType, byte[] postData, IDictionary headers, Action callback) 36 | { 37 | return requestInternal(url, method, contentType, postData, headers, callback); 38 | } 39 | 40 | private int requestInternal(String url, String method, string ContentType, byte[] postData, IDictionary headers, Action callback) 41 | { 42 | var http = new Http(); 43 | http.Method = method; 44 | http.RequestContentType = ContentType; 45 | http.Headers = headers; 46 | http.RequestBodyBytes = postData; 47 | http.Url = new Uri(url); 48 | 49 | // http模块有包括了网络异常的处理 50 | http.ExecuteAsync((raw, _) => 51 | { 52 | var status = new Status((int)raw.StatusCode, raw.StatusDescription); 53 | callback(raw.Content, status, raw.ErrorException != null ? new BmobException(raw.ErrorException) : null); 54 | }); 55 | 56 | return 0; 57 | } 58 | } 59 | #endif 60 | 61 | } 62 | -------------------------------------------------------------------------------- /core/src/api/IBmobAPI.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.http; 2 | using cn.bmob.io; 3 | using cn.bmob.response; 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace cn.bmob.api 8 | { 9 | /// 10 | /// SDK对外API抽象接口类 11 | /// 12 | public interface IBmobAPI 13 | { 14 | 15 | void initialize(string appKey, String restKey); 16 | void resetDomain(string url); 17 | 18 | // / 19 | 20 | void Create(string tablename, IBmobWritable data, BmobCallback callback); 21 | void Update(string tablename, string objectId, IBmobWritable data, BmobCallback callback); 22 | void Delete(string tablename, string objectId, BmobCallback callback); 23 | void Get(string tablename, string objectId, BmobCallback callback); 24 | void Find(string tablename, BmobQuery query, BmobCallback> callback); 25 | 26 | // / 27 | 28 | void Signup(T user, BmobCallback callback) where T : BmobUser; 29 | void Login(string username, string pwd, BmobCallback callback) where T : BmobUser; 30 | 31 | void UpdateUser(string objectId, BmobUser data, string sessionToken, BmobCallback callback); 32 | void DeleteUser(string objectId, string sessionToken, BmobCallback callback); 33 | 34 | void Reset(string email, BmobCallback callback); 35 | void EmailVerify(string email, BmobCallback callback); 36 | 37 | // / 38 | 39 | void Batch(BmobBatch requests, BmobCallback>> callback); 40 | void Endpoint(string eMethod, IDictionary parameters, BmobCallback> callback); 41 | 42 | void FileUpload(BmobLocalFile file, BmobCallback callback); 43 | void FileDelete(String url, BmobCallback callback); 44 | 45 | void Thumbnail(ThumbnailParameter param, BmobCallback callback); 46 | void Push(PushParamter param, BmobCallback callback); 47 | 48 | void Timestamp(BmobCallback callback); 49 | void Sql(string bql, List values, BmobCallback> callback); 50 | 51 | void RequestSmsCode(string mobilePhoneNumber, string template, BmobCallback callback); 52 | void VerifySmsCode(string mobilePhoneNumber, string smsId, BmobCallback callback); 53 | void QuerySms(String smsId, BmobCallback callback); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/src/config/Configuration.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.tools; 2 | using System; 3 | using System.Reflection; 4 | 5 | namespace cn.bmob.config 6 | { 7 | 8 | internal class Configuration 9 | { 10 | 11 | /// 12 | /// 此SDK版本号 13 | /// 14 | public static String BUILD_VERSION = Utilities.Version(); 15 | 16 | /// 17 | /// 平台识别字段 18 | /// 19 | /// 默认为WindowsDisktop。 20 | /// 21 | internal static SDKTarget PLATFORM = SDKTarget.WindowsDesktop; 22 | 23 | /// 24 | /// 平台序列号 25 | /// 26 | internal const String PLATFORM_KEY = "4"; 27 | 28 | internal static string CLIENT_REQ_UID = Guid.NewGuid().ToString().Replace("-", ""); 29 | 30 | internal static string DATA_URL = "https://api.codenow.cn/1"; 31 | 32 | internal static string FILE_URL ="https://api.codenow.cn/2"; 33 | 34 | /// 35 | /// 请求Bmob后端接口版本号 36 | /// 37 | /*internal const String VERSION = "1"; 38 | 39 | /// 40 | /// 请求Bmob后端'文件'接口版本号 41 | /// 42 | internal const String VERSION_NEW = "2"; 43 | 44 | //public String FILE_NET = "https://api.codenow.cn/" + VERSION_NEW; 45 | 46 | internal static String OUTER_NET = "https://api.codenow.cn/" + VERSION; 47 | 48 | /// 49 | /// 请求Bmob后端'文件'接口url前缀 50 | /// 51 | internal static String NEW_OUTER_NET = "https://api.codenow.cn/" + VERSION_NEW; 52 | 53 | public static String Url 54 | { 55 | get 56 | { 57 | return this.NEW_OUTER_NET; 58 | } 59 | set 60 | { 61 | this.NEW_OUTER_NET=value; 62 | } 63 | }*/ 64 | 65 | public const String CHARSET = "UTF-8"; 66 | internal const String JSON_CONTENT_TYPE = "application/json; charset=" + CHARSET; 67 | 68 | //设置获得响应的超时时间(10秒) 69 | internal static int REQUEST_TIMEOUT = 10 * 1000; 70 | 71 | } 72 | 73 | public enum SDKTarget 74 | { 75 | WindowsDesktop, 76 | WindowsPhone, //WP8 77 | Windows81, // Win8 or WP8.1 78 | Unity 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /core/src/example/GameObject.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.io; 2 | using cn.bmob.api; 3 | using cn.bmob.json; 4 | using cn.bmob.tools; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace cn.bmob.example 11 | { 12 | //Game表对应的模型类 13 | class GameObject : BmobTable 14 | { 15 | 16 | private String fTable; 17 | //以下对应云端字段名称 18 | public BmobInt score { get; set; } 19 | public String playerName { get; set; } 20 | public BmobBoolean cheatMode { get; set; } 21 | 22 | //构造函数 23 | public GameObject() { } 24 | 25 | //构造函数 26 | public GameObject(String tableName) 27 | { 28 | this.fTable = tableName; 29 | } 30 | 31 | public override string table 32 | { 33 | get 34 | { 35 | if (fTable != null) 36 | { 37 | return fTable; 38 | } 39 | return base.table; 40 | } 41 | } 42 | 43 | //读字段信息 44 | public override void readFields(BmobInput input) 45 | { 46 | base.readFields(input); 47 | 48 | this.score = input.getInt("score"); 49 | this.cheatMode = input.getBoolean("cheatMode"); 50 | this.playerName = input.getString("playerName"); 51 | } 52 | 53 | //写字段信息 54 | public override void write(BmobOutput output, bool all) 55 | { 56 | base.write(output, all); 57 | 58 | output.Put("score", this.score); 59 | output.Put("cheatMode", this.cheatMode); 60 | output.Put("playerName", this.playerName); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /core/src/exception/BmobException.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.response; 2 | using System; 3 | 4 | namespace cn.bmob.exception 5 | { 6 | /// 7 | /// Bmob自定义异常处理类 8 | /// 9 | public class BmobException : Exception 10 | { 11 | public Status status { get; private set; } 12 | 13 | public BmobException(Status status) : base(status.ToString()) 14 | { 15 | this.status = status; 16 | } 17 | 18 | public BmobException(string msg) : base(msg) { } 19 | 20 | public BmobException(Exception real) : base(real.Message, real) { } 21 | 22 | public BmobException(string msg, Exception real) : base(msg, real) { } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/http/BmobCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using cn.bmob.api; 4 | using cn.bmob.response; 5 | using System.Collections; 6 | using System.Text; 7 | using System.IO; 8 | using cn.bmob.tools; 9 | using cn.bmob.io; 10 | using cn.bmob.json; 11 | using cn.bmob.Extensions; 12 | using cn.bmob.config; 13 | using cn.bmob.exception; 14 | 15 | namespace cn.bmob.http 16 | { 17 | /// 18 | /// 请求回调函数 19 | /// 20 | /// Bmob服务器请求到数据后调用该委托实现。 21 | /// 22 | /// 23 | /// 返回类型 24 | /// 请求返回数据 25 | /// 调用过程中发生的异常,包括调用执行过程中的校验和服务端返回状态非200情况。 26 | public delegate void BmobCallback(T response, BmobException exception); 27 | 28 | internal class BmobCommand 29 | { 30 | private BmobInteractObject receiver; 31 | 32 | public BmobCommand(BmobInteractObject mReceiver) 33 | { 34 | this.receiver = mReceiver; 35 | } 36 | 37 | internal BmobInteractObject getReceiver() 38 | { 39 | return receiver; 40 | } 41 | 42 | protected virtual IDictionary getHeaders() 43 | { 44 | if (receiver.AppKey == null || receiver.RestKey == null) 45 | { 46 | throw new BmobException("applicationid and restkey must be set!!! please invoke Bmob#initialize first. "); 47 | } 48 | IDictionary headers = new Dictionary(); 49 | headers.Add("X-Bmob-Application-Id", receiver.AppKey); 50 | headers.Add("X-Bmob-REST-API-Key", receiver.RestKey); 51 | 52 | if (receiver.MasterKey != null) 53 | { 54 | headers.Add("X-Bmob-Master-Key", receiver.MasterKey); 55 | } 56 | 57 | // 如果是用户表修改的请求需要检查是否设置了sessiontoken 58 | if (receiver.SessionToken != null) 59 | headers.Add("X-Bmob-Session-Token", receiver.SessionToken); 60 | 61 | // XXX 默认Unity WWW已经添加了压缩标志; WindowsPhone8默认不支持GzipStream,暂时不添加压缩! 62 | // headers.Add("Accept-Encoding", "gzip,deflate"); 63 | return headers; 64 | } 65 | 66 | /// 操作返回值类型 67 | /// 参数对应为: url, contenttype, requestData, headers, callback(请求服务器数据返回值回调函数) 68 | /// 返回结果回调函数 69 | /// 操作返回值 70 | public virtual R execute(Func, Action, R> request, BmobCallback fCallback) 71 | { 72 | var url = receiver.Url; 73 | 74 | var contentType = receiver.ContentType; 75 | var postData = getPostData(); 76 | var headers = getHeaders(); 77 | 78 | return Execute(request, url, contentType, postData, headers, fCallback); 79 | } 80 | 81 | 82 | protected R Execute(Func, Action, R> request, 83 | String url, String contentType, Byte[] postData, IDictionary headers, BmobCallback fCallback) 84 | { 85 | 86 | 87 | BmobDebug.T("\r\n\t请求的URL : " + url 88 | + "\r\n\t交互对象(以请求的数据为准): " + JsonAdapter.JSON.ToRawString(receiver) 89 | + "\r\n\t请求的数据: " + JsonAdapter.JSON.ToJsonString(receiver.Data)); 90 | 91 | return request.Invoke(url, receiver.Method, contentType, postData, headers, (resp, status, ex) => 92 | { 93 | if (BmobDebug.Debug) 94 | { 95 | BmobDebug.D("返回数据内容为: " + resp); 96 | } 97 | else 98 | { 99 | var rp = resp.Length > 400 ? resp.Substring(0, 200) + " ... ... ... ... ... ... " + resp.Substring(resp.Length - 200) : resp; 100 | BmobDebug.I("返回数据内容为: " + rp); 101 | } 102 | 103 | onPostExecute(resp, status, ex, fCallback); 104 | }); 105 | 106 | } 107 | 108 | protected virtual byte[] getPostData() 109 | { 110 | if (receiver.Data == null || receiver.Method.Equals("GET")) 111 | { 112 | return null; 113 | } 114 | 115 | var data = JsonAdapter.JSON.ToJsonString(receiver.Data); 116 | return data.GetBytes(); 117 | } 118 | 119 | protected void onPostExecute(String result, Status status, BmobException exception, BmobCallback fCallback) 120 | { 121 | T data; 122 | BmobException ex; 123 | if (exception != null) 124 | { 125 | data = default(T); 126 | if (result == null) 127 | ex = exception; 128 | else 129 | ex = new BmobException(exception.Message + ", and response content is " + result, exception.InnerException); 130 | } 131 | else 132 | { 133 | BmobResponseParser parser = getResponseParser(status); 134 | parser.parse(result); 135 | 136 | data = parser.data; 137 | ex = parser.exception; 138 | } 139 | 140 | if (ex != null) 141 | { 142 | BmobDebug.T("[ BmobCommand ] after parse response, error: '" + ex.Message + "'"); 143 | } 144 | 145 | fCallback(data, ex); 146 | } 147 | 148 | protected virtual BmobResponseParser getResponseParser(Status status) 149 | { 150 | return new BmobResponseParser(status); 151 | } 152 | 153 | } 154 | 155 | internal class BmobFileCommand : BmobCommand 156 | { 157 | public BmobFileCommand(BmobInteractObject mReceiver) : base(mReceiver) 158 | { 159 | } 160 | 161 | protected override byte[] getPostData() 162 | { 163 | var data = getReceiver().Data as BmobLocalFile; 164 | return data.Content(); 165 | } 166 | } 167 | 168 | } 169 | -------------------------------------------------------------------------------- /core/src/http/BmobInteractionObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using cn.bmob.io; 4 | using System.Collections.Generic; 5 | using cn.bmob.config; 6 | using cn.bmob.tools; 7 | using System.Text; 8 | using cn.bmob.Extensions; 9 | using cn.bmob.json; 10 | 11 | namespace cn.bmob.http 12 | { 13 | 14 | /// 15 | /// request请求的包装类 16 | /// 17 | internal class BmobInteractObject 18 | { 19 | protected Func calcUrlAction; 20 | 21 | public BmobInteractObject(String method) : this(method, null) 22 | { 23 | } 24 | 25 | public BmobInteractObject(String method, Func calcUrlAction) 26 | { 27 | this.Method = method; 28 | this.calcUrlAction = calcUrlAction; 29 | } 30 | 31 | /// 32 | /// 请求的类型POST/PUT/DELETE/GET 33 | /// 34 | public String Method { get; internal set; } 35 | 36 | public String AppKey { get; set; } 37 | 38 | public String RestKey { get; set; } 39 | 40 | public String MasterKey { get; set; } 41 | 42 | private String fContentType = Configuration.JSON_CONTENT_TYPE; 43 | public String ContentType 44 | { 45 | get { return this.fContentType; } 46 | set { this.fContentType = value; } 47 | } 48 | 49 | 50 | /// 51 | /// 请求数据,相当于curl的-d参数的值 52 | /// 53 | public Object Data { get; set; } 54 | 55 | /// 56 | /// 更新|删除,当c="_User"时,必须先登录获取sessionToken的值。然后作为X-Bmob-Session-Token的Http头部操作ACL数据 57 | /// 58 | public String SessionToken { get; set; } 59 | 60 | /// 61 | /// 云端代码的名称 62 | /// 63 | public String EndPointName { get; set; } 64 | 65 | public String ObjectId { get; set; } 66 | public String Table { get; set; } 67 | 68 | public virtual String Url { get { return Utilities.getBaseURL() + calcUrlAction(this); } } 69 | 70 | // TODO 1.6 URL整体优化 71 | private static String getURLTablePart(String tablename) 72 | { 73 | if (tablename.StartsWith("_")) 74 | { 75 | switch (tablename) 76 | { 77 | case "_Installation": 78 | return "/installations"; 79 | case "_User": 80 | return "/users"; 81 | case "_Role": 82 | return "/roles"; 83 | default: 84 | throw new ArgumentException("unknow special table: " + tablename); 85 | } 86 | } 87 | else 88 | { 89 | return "/classes/" + tablename; 90 | } 91 | } 92 | 93 | public static BmobInteractObject Create { get { return new BmobInteractObject("POST", bio => getURLTablePart(bio.Table)); } } 94 | public static BmobInteractObject Get { get { return new BmobInteractObject("GET", bio => getURLTablePart(bio.Table) + "/" + bio.ObjectId); } } 95 | 96 | public static BmobInteractObject Find { get { return new GetInteractObject(bio => getURLTablePart(bio.Table)); } } 97 | 98 | public static BmobInteractObject Update { get { return new BmobInteractObject("PUT", bio => getURLTablePart(bio.Table) + "/" + bio.ObjectId); } } 99 | public static BmobInteractObject Delete { get { return new BmobInteractObject("DELETE", bio => getURLTablePart(bio.Table) + "/" + bio.ObjectId); } } 100 | 101 | public static BmobInteractObject Signup { get { return new BmobInteractObject("POST", bio => getURLTablePart(bio.Table)); } } 102 | 103 | public static BmobInteractObject Login { get { return new GetInteractObject(bio => "/login"); } } 104 | 105 | public static BmobInteractObject PwdReset { get { return new BmobInteractObject("POST", bio => "/requestPasswordReset"); } } 106 | public static BmobInteractObject EmailVerify { get { return new BmobInteractObject("POST", bio => "/requestEmailVerify"); } } 107 | 108 | public static BmobInteractObject Files 109 | { 110 | get 111 | { 112 | return new NewBmobInteractObject( 113 | "POST", 114 | bio => 115 | { 116 | var data = bio.Data as BmobLocalFile; 117 | return "/files/" + data.Filename(); 118 | } 119 | ); 120 | } 121 | } 122 | public static BmobInteractObject FileDelete 123 | { 124 | get 125 | { 126 | return new NewBmobInteractObject( 127 | "DELETE ", 128 | bio => 129 | { 130 | var data = bio.Data as BmobKV; 131 | return "/files/" + data["filename"]; 132 | } 133 | ); 134 | } 135 | } 136 | 137 | public static BmobInteractObject Thumbnail { get { return new BmobInteractObject("POST", bio => "/images/thumbnail"); } } 138 | 139 | public static BmobInteractObject Batch { get { return new BmobInteractObject("POST", bio => "/batch"); } } 140 | public static BmobInteractObject Endpoint { get { return new BmobInteractObject("POST", bio => "/functions/" + bio.EndPointName); } } 141 | public static BmobInteractObject Push { get { return new BmobInteractObject("POST", bio => "/push"); } } 142 | 143 | public static BmobInteractObject Timestamp { get { return new GetInteractObject(bio => "/timestamp"); } } 144 | public static BmobInteractObject BQL { get { return new GetInteractObject(bio => "/cloudQuery"); } } 145 | 146 | public static BmobInteractObject RequestSMS { get { return new BmobInteractObject("POST", bio => "/requestSmsCode"); } } 147 | public static BmobInteractObject VerifySMS 148 | { 149 | get 150 | { 151 | return new BmobInteractObject("POST", bio => 152 | { 153 | var data = bio.Data as SMSParamter; 154 | return "/verifySmsCode/" + data.code; 155 | }); 156 | } 157 | } 158 | public static BmobInteractObject QuerySMS 159 | { 160 | get 161 | { 162 | return new GetInteractObject(bio => 163 | { 164 | var data = bio.Data as SMSParamter; 165 | return "/querySms/" + data.smsId; 166 | }); 167 | } 168 | } 169 | 170 | 171 | #region GET 172 | public class GetInteractObject : BmobInteractObject 173 | { 174 | public GetInteractObject(Func calcUrlAction) : base("GET", calcUrlAction) 175 | { 176 | } 177 | 178 | public override String Url 179 | { 180 | get 181 | { 182 | var querystring = new StringBuilder(); 183 | var data = this.Data as IBmobWritable; 184 | if (data != null) 185 | { 186 | var bo = new BmobOutput(); 187 | data.write(bo, false); 188 | var kv = bo.getData(); 189 | foreach (var key in kv.Keys) 190 | { 191 | var name = key as String; 192 | if (name == null) 193 | { 194 | continue; 195 | } 196 | 197 | Object valueObject = kv[key]; 198 | String value = valueObject is String ? (String)valueObject : JsonAdapter.JSON.ToJsonString(valueObject); 199 | if (querystring.Length > 1) 200 | querystring.Append("&"); 201 | querystring.AppendFormat("{0}={1}", name.UrlEncode(), value.UrlEncode()); 202 | } 203 | 204 | } 205 | 206 | var baseUrl = Utilities.getBaseURL() + calcUrlAction(this); 207 | return querystring.Length > 1 ? baseUrl + "?" + querystring.ToString() : baseUrl; 208 | 209 | } 210 | } 211 | 212 | } 213 | #endregion 214 | 215 | public class NewBmobInteractObject : BmobInteractObject{ 216 | 217 | public NewBmobInteractObject(String method, Func calcUrlAction) : base(method, calcUrlAction) 218 | { 219 | } 220 | 221 | public override String Url 222 | { 223 | get 224 | { 225 | return (Utilities.getNewBaseURL() + calcUrlAction(this)); 226 | } 227 | } 228 | } 229 | 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /core/src/io/BmobACL.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using System.Collections; 6 | using cn.bmob.json; 7 | 8 | namespace cn.bmob.io 9 | { 10 | /// 11 | /// ACL基础类 12 | /// 13 | /// !!SimpleJson处理Dictionary才正常 14 | /// 15 | public class BmobACL : IBmobValue> 16 | { 17 | private Dictionary acls = new Dictionary(); //new Dictionary>(); 18 | 19 | /// 20 | /// 获取ACL权限信息 { key : {write : true}, key2 : {read: true} } 21 | /// 22 | /// 返回ACL列表, Object的内容为Dictionary可进行强转 23 | public Dictionary Get() 24 | { 25 | return acls; 26 | } 27 | 28 | public void Set(Object acls) 29 | { 30 | if (acls is Dictionary) 31 | { 32 | this.acls = (Dictionary)acls; 33 | } 34 | else if (acls is IDictionary) 35 | { 36 | IDictionary kvs = (IDictionary)acls; 37 | foreach (var entry in kvs) 38 | { 39 | this.acls.Add(entry.Key, entry.Value); 40 | } 41 | } 42 | 43 | } 44 | 45 | /// 46 | /// key是objectId(用户表某个用户对应的objectId)或者是 *(表示公共的访问权限),ACL 的值是 "读和写的权限", 这个JSON对象的key总是权限名, 而这些key的值总是 true 47 | /// 48 | public BmobACL ReadAccess(String objectId) 49 | { 50 | BmobOutput.Composite(acls, objectId, "read", true); 51 | return this; 52 | } 53 | 54 | public BmobACL WriteAccess(String objectId) 55 | { 56 | BmobOutput.Composite(acls, objectId, "write", true); 57 | return this; 58 | } 59 | 60 | public BmobACL RoleReadAccess(String rolename) 61 | { 62 | BmobOutput.Composite(acls, "role:" + rolename, "read", true); 63 | return this; 64 | } 65 | 66 | public BmobACL RoleWriteAccess(String rolename) 67 | { 68 | BmobOutput.Composite(acls, "role:" + rolename, "write", true); 69 | return this; 70 | } 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /core/src/io/BmobDate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// BmobDate时间类 7 | /// 8 | public sealed class BmobDate : BmobObject 9 | { 10 | /// 11 | /// 返回类型标识 12 | /// 13 | public override String _type { get { return "Date"; } } 14 | 15 | /// 16 | /// 时间的IOS格式(yyyy-MM-dd HH:mm:ss) 17 | /// 18 | public String iso { get; set; } 19 | 20 | /// 21 | /// 构造函数 22 | /// 23 | public BmobDate() 24 | { 25 | } 26 | 27 | public override void readFields(BmobInput input) 28 | { 29 | this.iso = input.getString("iso"); 30 | } 31 | 32 | public override void write(BmobOutput output, Boolean all) 33 | { 34 | output.Put(TYPE_NAME, this._type); 35 | output.Put("iso", this.iso); 36 | } 37 | 38 | #region Implicit Conversions 39 | public static implicit operator BmobDate(DateTime data) 40 | { 41 | var date = new BmobDate(); 42 | date.iso = data.ToString("yyyy-MM-dd HH:mm:ss"); 43 | return date; 44 | } 45 | 46 | #endregion 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/io/BmobFile.cs: -------------------------------------------------------------------------------- 1 |  2 | using cn.bmob.config; 3 | 4 | namespace cn.bmob.io 5 | { 6 | /// 7 | /// 文件处理类 8 | /// 9 | public class BmobFile : BmobObject 10 | { 11 | 12 | public override string _type 13 | { 14 | get 15 | { 16 | return "File"; 17 | } 18 | } 19 | 20 | /// 21 | /// 文件名 22 | /// 23 | public string filename { get; set; } 24 | 25 | /// 26 | /// 文件的组名 27 | /// 28 | public string group { get; set; } 29 | 30 | /// 31 | /// 文件的cdn名 32 | /// 33 | public string cdn { get; set; } 34 | 35 | /// 36 | /// 相对于Bmob文件服务器的位置,结果需要附加上http://file.codenow.cn 37 | /// 38 | public string url { get; set; } 39 | 40 | /// 41 | /// 获取文件地址 42 | /// 43 | /// 文件地址 44 | public string getPath() 45 | { 46 | return Configuration.FILE_URL + this.url; 47 | //return Configuration.FILE_NET + this.url; 48 | } 49 | 50 | //public Image Image 51 | //{ 52 | // get 53 | // { 54 | // return 55 | // } 56 | //} 57 | 58 | public override void readFields(BmobInput input) 59 | { 60 | base.readFields(input); 61 | this.cdn = input.getString("cdn"); 62 | this.filename = input.getString("filename"); 63 | this.group = input.getString("group"); 64 | this.url = input.getString("url"); 65 | } 66 | 67 | public override void write(BmobOutput output, bool all) 68 | { 69 | base.write(output, all); 70 | output.Put(TYPE_NAME, this._type); 71 | output.Put("cdn",this.cdn); 72 | output.Put("filename", this.filename); 73 | output.Put("group", this.group); 74 | output.Put("url", this.url); 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /core/src/io/BmobGeoPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// 地理位置处理类 7 | /// 8 | /// 纬度的范围应该是在-90.0到90.0之间。经度的范围应该是在-180.0到180.0之间。 9 | /// 10 | public sealed class BmobGeoPoint : BmobObject 11 | { 12 | /// 13 | /// 构造函数 14 | /// 15 | public BmobGeoPoint() { } 16 | 17 | /// 18 | /// 构造函数 19 | /// 20 | /// 纬度 21 | /// 经度 22 | public BmobGeoPoint(double latitude, double longitude) 23 | { 24 | this.Latitude = latitude; 25 | this.Longitude = longitude; 26 | } 27 | 28 | /// 29 | /// 获取类型信息 30 | /// 31 | public override string _type { get { return "GeoPoint"; } } 32 | 33 | private BmobDouble latitude; 34 | /// 35 | /// 纬度 [-90, 90] 36 | /// 37 | public BmobDouble Latitude 38 | { 39 | get { return this.latitude; } 40 | set 41 | { 42 | this.latitude = value; 43 | if (this.latitude.Get() < -90 || this.latitude.Get() > 90) 44 | { 45 | throw new InvalidOperationException(); 46 | } 47 | } 48 | } 49 | 50 | private BmobDouble longitude; 51 | /// 52 | /// 经度 [-180, 180] 53 | /// 54 | public BmobDouble Longitude 55 | { 56 | get { return this.longitude; } 57 | set 58 | { 59 | this.longitude = value; 60 | if (this.longitude.Get() < -180 || this.longitude.Get() > 180) 61 | { 62 | throw new InvalidOperationException(); 63 | } 64 | } 65 | } 66 | 67 | public override void readFields(BmobInput input) 68 | { 69 | this.latitude = input.getDouble("latitude"); 70 | this.longitude = input.getDouble("longitude"); 71 | } 72 | 73 | public override void write(BmobOutput output, Boolean all) 74 | { 75 | output.Put(TYPE_NAME, this._type); 76 | output.Put("latitude", this.latitude); 77 | output.Put("longitude", this.longitude); 78 | } 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /core/src/io/BmobInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using cn.bmob.json; 5 | using cn.bmob.tools; 6 | using cn.bmob.Extensions; 7 | 8 | namespace cn.bmob.io 9 | { 10 | public class BmobInput 11 | { 12 | private IDictionary real; 13 | 14 | internal BmobInput() { } 15 | 16 | internal BmobInput(IDictionary real) 17 | { 18 | this.real = real; 19 | } 20 | 21 | public Boolean Contains(string name) 22 | { 23 | return real.ContainsKey(name); 24 | } 25 | 26 | public ICollection keySet() 27 | { 28 | return real.Keys; 29 | } 30 | 31 | /// 32 | /// 简单类型/简单类型的键值对 33 | /// 34 | internal object getRaw(string name) 35 | { 36 | if (Contains(name)) 37 | { 38 | return real[name]; 39 | } 40 | else 41 | { 42 | return null; 43 | } 44 | } 45 | 46 | /// 47 | /// 这里获取到的list是没有被序列化的,list中的元素还是hashtable/valuetype对象,没有对应到用户自定义的类型的! 48 | /// 49 | /// 50 | /// 51 | private IList getListRaw(string name) 52 | { 53 | return getRaw(name) as IList; 54 | } 55 | 56 | /// 57 | /// 获取对象 58 | /// 59 | /// 获取数据对应的模型类型 60 | /// 字段名 61 | public W Get(string name) 62 | { 63 | return Parse(getRaw(name)); 64 | } 65 | 66 | /// 67 | /// 获取列表 68 | /// 69 | /// 列表中对象的具体类型 70 | /// 字段名 71 | public List getList(String name) 72 | { 73 | IList raw = getListRaw(name); 74 | if (raw == null) 75 | { 76 | BmobDebug.D("获取" + name + "的列表数据为空!"); 77 | return null; 78 | } 79 | 80 | Type type = typeof(U); 81 | List result = new List(raw.Count); 82 | 83 | foreach (var element in raw) 84 | { 85 | result.Add(Parse(element)); 86 | } 87 | 88 | return result; 89 | } 90 | 91 | // / 包装方法 92 | 93 | public BmobDate getDate(string name) 94 | { 95 | return Get(name); 96 | } 97 | 98 | public BmobGeoPoint getGeoPoint(string name) 99 | { 100 | return Get(name); 101 | } 102 | 103 | public BmobFile getFile(string name) 104 | { 105 | return Get(name); 106 | } 107 | 108 | public BmobBoolean getBoolean(string name) 109 | { 110 | return Parse(getRaw(name)); 111 | } 112 | 113 | public BmobInt getInt(string name) 114 | { 115 | return Parse(getRaw(name)); 116 | } 117 | 118 | public BmobLong getLong(string name) 119 | { 120 | return Parse(getRaw(name)); 121 | } 122 | 123 | public BmobDouble getDouble(String name) 124 | { 125 | return Parse(getRaw(name)); 126 | } 127 | 128 | public string getString(String name) 129 | { 130 | return Parse(getRaw(name)); 131 | } 132 | 133 | // / 134 | 135 | // / 私有核心方法 136 | 137 | /// 138 | /// 对象转换的公共类 139 | /// 140 | // 支持List<>/Dictionary/int/long/double/:BmobWritable/:BmobValue的类型 141 | // SDK会把JSON解析为List和Dictionary。 值对象,可以传入null 142 | public static W Parse(object value) 143 | { 144 | if (value == null) 145 | { 146 | return default(W); 147 | } 148 | 149 | W w = (W)convert(typeof(W), value); 150 | 151 | if (w == null) 152 | { 153 | BmobDebug.E("最外层对象**推荐**使用IBmobWritable对象,序列化定制化程度更高!"); 154 | 155 | // 搞不定,使用反射方式重新解析 156 | string json = JsonAdapter.JSON.ToDebugJsonString(value); 157 | BmobDebug.E("反序列化不正确,使用默认的JSON反序列化方式再次处理! " + json); 158 | w = JsonAdapter.JSON.ToObject(json); 159 | } 160 | 161 | return w; 162 | } 163 | 164 | // covert dispatch 165 | private static object convert(Type type, Object data) 166 | { 167 | 168 | if (data.GetType() == type || type == typeof(Object)) 169 | { 170 | return data; 171 | } 172 | 173 | // 基本类型 174 | if (type == typeof(int)) 175 | { 176 | return toInt(data); 177 | } 178 | else if (type == typeof(long)) 179 | { 180 | return toLong(data); 181 | } 182 | else if (type == typeof(double)) 183 | { 184 | return toDouble(data); 185 | } 186 | else if (type == typeof(bool)) 187 | { 188 | return toBoolean(data); 189 | } 190 | else if (type == typeof(string)) 191 | { 192 | return toString(data); 193 | } 194 | 195 | // Bmob包装类型 196 | if (type == typeof(BmobInt)) 197 | { 198 | return new BmobInt(toInt(data)); 199 | } 200 | else if (type == typeof(BmobLong)) 201 | { 202 | return new BmobLong(toLong(data)); 203 | } 204 | else if (type == typeof(BmobDouble)) 205 | { 206 | return new BmobDouble(toDouble(data)); 207 | } 208 | else if (type == typeof(BmobBoolean)) 209 | { 210 | return new BmobBoolean(toBoolean(data)); 211 | } 212 | 213 | 214 | // 复杂类型 215 | if (typeof(IBmobWritable).IsAssignableFrom(type)) 216 | { 217 | IDictionary raw = (IDictionary)data; 218 | 219 | IBmobWritable result = (IBmobWritable)Activator.CreateInstance(type); 220 | result.readFields(new BmobInput(raw)); 221 | 222 | return result; 223 | } 224 | else if (typeof(IBmobValue).IsAssignableFrom(type)) 225 | { 226 | 227 | IDictionary raw = (IDictionary)data; 228 | 229 | IBmobValue result = (IBmobValue)Activator.CreateInstance(type); 230 | result.Set(raw); 231 | 232 | return result; 233 | } 234 | 235 | if (typeof(IList).IsAssignableFrom(type)) 236 | { 237 | IList raw = (IList)data; 238 | 239 | IList result = (IList)Activator.CreateInstance(type); 240 | foreach (var element in raw) 241 | { 242 | var isGeneric = type.IsGenericType(); 243 | var dataType = isGeneric ? type.GetGenericArguments()[0] : null; 244 | 245 | isGeneric = isGeneric && dataType != typeof(Object); 246 | result.Add(isGeneric ? convert(dataType, element) : element); 247 | } 248 | 249 | return result; 250 | } 251 | else if (typeof(IDictionary).IsAssignableFrom(type)) 252 | { 253 | IDictionary raw = (IDictionary)data; 254 | 255 | IDictionary result = (IDictionary)Activator.CreateInstance(type); 256 | 257 | var isGeneric = type.IsGenericType(); 258 | var vt = isGeneric ? type.GetGenericArguments()[1] : null; 259 | foreach (var entry in raw) 260 | { 261 | isGeneric = isGeneric && type != typeof(Object); 262 | result.Add(entry.Key, isGeneric ? convert(vt, entry.Value) : entry.Value); 263 | } 264 | 265 | return result; 266 | } 267 | 268 | throw new ArgumentException("UnExcept type: " + type + ". Use Generic Type List/Dictionary instead!"); 269 | } 270 | 271 | private static int toInt(Object data) 272 | { 273 | if (data is int) return (int)data; 274 | else if (data is long) return (int)((long)data); 275 | else if (data is double) return (int)((double)data); 276 | else 277 | { 278 | BmobDebug.Log("[ERROR] 获取数值类型失败,原值为:" + JsonAdapter.JSON.ToDebugJsonString(data)); 279 | } 280 | 281 | return 0; 282 | } 283 | private static long toLong(Object data) 284 | { 285 | if (data is int) return (int)data; 286 | else if (data is long) return (long)data; 287 | else if (data is double) return (long)((double)data); 288 | else 289 | { 290 | BmobDebug.Log("[ERROR] 获取数值类型失败,原值为:" + JsonAdapter.JSON.ToDebugJsonString(data)); 291 | } 292 | 293 | return 0; 294 | } 295 | private static double toDouble(Object data) 296 | { 297 | if (data is int) return (int)data; 298 | else if (data is long) return (long)data; 299 | else if (data is double) return (double)data; 300 | else 301 | { 302 | BmobDebug.Log("[ERROR] 获取数值类型失败,原值为:" + JsonAdapter.JSON.ToDebugJsonString(data)); 303 | } 304 | 305 | return 0; 306 | } 307 | private static bool toBoolean(Object data) 308 | { 309 | return (bool)data; 310 | } 311 | private static String toString(Object data) 312 | { 313 | return (String)data; 314 | } 315 | 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /core/src/io/BmobInstallation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace cn.bmob.io 5 | { 6 | /// 7 | /// 订阅配置表 8 | /// 9 | /// 继承该类,定制更通用的推送。 10 | /// 11 | public partial class BmobInstallation : BmobTable 12 | { 13 | public const String DeviceType = "windows phone"; 14 | public const String TABLE = "_Installation"; 15 | 16 | public override string table 17 | { 18 | get 19 | { 20 | return TABLE; 21 | } 22 | } 23 | 24 | public BmobInt badge { get; set; } // iOS应用中右上角的图标标识,这会在服务端修改,用于未来推送消息的自增统计 25 | public List channels { get; set; } // 当前这个设备订阅的渠道名称数组 26 | public String timeZone { get; set; } // 设备所在位置的时区, 如Asia/Shanghai,这个会在每个Installation对象更新时同步(只读) 27 | 28 | /// 29 | /// 设备的类型, 值为:"ios" 或 "android",或"windows phone" (只读) 30 | /// 31 | public String deviceType { get; set; } 32 | 33 | /// 34 | /// Bmob使用的设备唯一号,唯一标示(与用于一对一即可!). Android设备是必须的,iOS可选 (只读) 35 | /// 36 | /// 如果仅仅为了进行数据推送,可以使用UUID生成,然后把该值写入到用户表中!**该字段是前后端联系的枢纽**!! 37 | /// 38 | public String installationId { get; set; } 39 | public String deviceToken { get; set; } // iOS设备由Apple APNS生成的唯一性token标识 (只读) 40 | public String notificationUri { get; internal set; } // Microsoft WindowsPhone的设备通知标识 41 | public String deviceId { get; internal set; } // 设备标识 42 | 43 | /// 44 | /// 订阅 45 | /// 46 | public void subscribe(List channels) 47 | { 48 | this.AddUnique("channels", channels); 49 | } 50 | 51 | /// 52 | /// 取消订阅 53 | /// 54 | public void unsubscribe(List channels) 55 | { 56 | this.Remove("channels", channels); 57 | } 58 | 59 | public override void readFields(BmobInput input) 60 | { 61 | base.readFields(input); 62 | 63 | this.badge = input.getInt("badge"); 64 | this.channels = input.getList("channels"); 65 | this.timeZone = input.getString("timeZone"); 66 | this.deviceType = input.getString("deviceType"); 67 | 68 | this.installationId = input.getString("installationId"); 69 | this.deviceToken = input.getString("deviceToken"); 70 | this.notificationUri = input.getString("notificationUri"); 71 | this.deviceId = input.getString("deviceId"); 72 | } 73 | 74 | public override void write(BmobOutput output, bool all) 75 | { 76 | base.write(output, all); 77 | 78 | output.Put("badge", this.badge); 79 | output.Put("channels", this.channels); 80 | output.Put("timeZone", this.timeZone); 81 | output.Put("deviceType", this.deviceType); 82 | 83 | output.Put("installationId", this.installationId); 84 | output.Put("deviceToken", this.deviceToken); 85 | output.Put("notificationUri", this.notificationUri); 86 | output.Put("deviceId", this.deviceId); 87 | 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /core/src/io/BmobKV.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace cn.bmob.io 5 | { 6 | /// 7 | /// 主要用于请求参数,推荐在一次性场景下使用! 8 | /// 9 | public class BmobKV : Dictionary, IBmobWritable 10 | { 11 | public string _type { get { return "Bmo-KV"; } } 12 | 13 | public BmobKV Put(String key, Object value) 14 | { 15 | this.Add(key, value); 16 | return this; 17 | } 18 | 19 | public BmobKV PutAll(IDictionary kvs) 20 | { 21 | foreach (var entry in kvs) 22 | { 23 | this.Put(entry.Key, entry.Value); 24 | } 25 | return this; 26 | } 27 | 28 | public void readFields(BmobInput input) 29 | { 30 | foreach (var key in input.keySet()) 31 | { 32 | this.Add(key, input.getRaw(key)); 33 | } 34 | } 35 | 36 | public void write(BmobOutput output, Boolean all) 37 | { 38 | foreach (var entry in this) 39 | { 40 | output.Put(entry.Key, entry.Value); 41 | } 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /core/src/io/BmobObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using cn.bmob.json; 3 | using System.Collections; 4 | 5 | namespace cn.bmob.io 6 | { 7 | /// 8 | /// 所有键值对对象的基类。 9 | /// 10 | /// 重写ToString方法,实现打印输出当前对象的JSON字符串。 11 | /// 12 | public class BmobObject : IBmobWritable 13 | { 14 | public const String TYPE_NAME = "__type"; 15 | 16 | public virtual String _type { get { return "Object"; } } 17 | 18 | public virtual void write(BmobOutput output, Boolean all) 19 | { 20 | } 21 | 22 | public virtual void readFields(BmobInput input) 23 | { 24 | } 25 | 26 | /// 27 | /// 输出当前对象的字符串 28 | /// 29 | /// 字符串 30 | public override string ToString() 31 | { 32 | return GetType().FullName + " " + ToString(this); 33 | } 34 | 35 | /// 36 | /// 输出对象的JSON字符串 37 | /// 38 | /// 需要转换为JSON字符串的对象 39 | /// 字符串 40 | public static string ToString(IBmobWritable ele) 41 | { 42 | return JsonAdapter.JSON.ToDebugJsonString(ele); 43 | } 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/io/BmobOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using cn.bmob.tools; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using cn.bmob.Extensions; 6 | 7 | namespace cn.bmob.io 8 | { 9 | public class BmobOutput 10 | { 11 | 12 | private IDictionary real = new Dictionary(); 13 | 14 | /// 15 | /// internal 16 | /// 17 | public IDictionary getData() 18 | { 19 | return real; 20 | } 21 | 22 | public void PutIfNotNull(string key, object value) 23 | { 24 | if (value == null) 25 | { 26 | return; 27 | } 28 | 29 | Put(key, value); 30 | } 31 | 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// cannot be null !!! 37 | public void Put(string key, object value) 38 | { 39 | var type = value.GetType(); 40 | if (type == typeof(bool)) 41 | { 42 | Put(key, (bool)value); 43 | } 44 | else if (type == typeof(String)) 45 | { 46 | Put(key, (String)value); 47 | } 48 | else if (type == typeof(int)) 49 | { 50 | Put(key, (int)value); 51 | } 52 | else if (type == typeof(long)) 53 | { 54 | Put(key, (long)value); 55 | } 56 | else if (type == typeof(double)) 57 | { 58 | Put(key, (double)value); 59 | } 60 | else if (typeof(BmobLong).IsAssignableFrom(type)) 61 | { 62 | Put(key, (BmobLong)value); 63 | } 64 | else if (typeof(BmobInt).IsAssignableFrom(type)) 65 | { 66 | Put(key, (BmobInt)value); 67 | } 68 | else if (typeof(BmobDouble).IsAssignableFrom(type)) 69 | { 70 | Put(key, (BmobDouble)value); 71 | } 72 | else if (typeof(BmobBoolean).IsAssignableFrom(type)) 73 | { 74 | Put(key, (BmobBoolean)value); 75 | } 76 | else if (typeof(IDictionary).IsAssignableFrom(type)) 77 | { 78 | Put(key, (IDictionary)value); 79 | } 80 | else if (typeof(IDictionary).IsAssignableFrom(type)) 81 | { 82 | Put(key, (IDictionary)value); 83 | } 84 | else if (typeof(IBmobWritable).IsAssignableFrom(type)) 85 | { 86 | Put(key, (IBmobWritable)value); 87 | } 88 | else if (typeof(IList).IsAssignableFrom(type)) 89 | { 90 | Put(key, (IList)value); 91 | } 92 | else 93 | { 94 | throw new NotSupportedException(); 95 | } 96 | } 97 | 98 | /// 99 | /// 添加键值对。加入已经存在的键时,会覆盖原有的值!不同与Hashtable#Add方法抛出异常的方式。 100 | /// 101 | /// 102 | /// 103 | public void Put(string key, IBmobWritable value) 104 | { 105 | Save(real, key, value); 106 | } 107 | 108 | /// 109 | /// 添加键值对。加入已经存在的键时,会覆盖原有的值!不同与Hashtable#Add方法抛出异常的方式。 110 | /// 111 | /// 112 | /// 113 | /// 114 | public void Put(string key, IBmobValue value) 115 | { 116 | Save(real, key, value); 117 | } 118 | 119 | /// 120 | /// 添加键值对。加入已经存在的键时,会覆盖原有的值!不同与Hashtable#Add方法抛出异常的方式。 121 | /// 122 | /// 123 | /// 124 | /// 125 | public void Put(string key, List list) 126 | { 127 | Save(real, key, list); 128 | } 129 | 130 | /// 131 | /// 实现 {column: {key: value}} 的效果 132 | /// 133 | internal static void Composite(IDictionary data, String column, String key, Object value) 134 | { 135 | var part = data[column]; 136 | if (part == null || !(part is IDictionary)) 137 | { 138 | // !!SimpleJson处理Dictionary才正常 139 | part = new Dictionary(); 140 | } 141 | ((IDictionary)part).Add(key, value); 142 | 143 | BmobOutput.Save(data, column, part); 144 | } 145 | 146 | /// 147 | /// 如果data中已经存在key,则覆盖为value 148 | /// 149 | internal static void Save(IDictionary data, String key, Object value) 150 | { 151 | if (value == null) 152 | return; 153 | 154 | try 155 | { 156 | data.Add(key, value); 157 | } 158 | catch (ArgumentException e) 159 | { 160 | BmobDebug.Log("ERROR: " + e.Message); 161 | 162 | // 处理重复修改同一列的值 163 | if (data.Contains(key)) 164 | { 165 | data.Remove(key); 166 | data.Add(key, value); 167 | } 168 | } 169 | } 170 | 171 | internal static void Save(IDictionary data, String key, V value) 172 | { 173 | if (value == null) 174 | return; 175 | 176 | try 177 | { 178 | data.Add(key, value); 179 | } 180 | catch (ArgumentException e) 181 | { 182 | BmobDebug.Log("ERROR: " + e.Message); 183 | 184 | // 处理重复修改同一列的值 185 | if (data.ContainsKey(key)) 186 | { 187 | data.Remove(key); 188 | data.Add(key, value); 189 | } 190 | } 191 | } 192 | 193 | /// 194 | /// 195 | /// 196 | /// 197 | /// 198 | public void Put(string key, bool value) 199 | { 200 | Put(key, new BmobBoolean(value)); 201 | } 202 | 203 | public void Put(string key, int value) 204 | { 205 | Put(key, new BmobInt(value)); 206 | } 207 | 208 | public void Put(string key, long value) 209 | { 210 | Put(key, new BmobLong(value)); 211 | } 212 | 213 | public void Put(string key, double value) 214 | { 215 | Put(key, new BmobDouble(value)); 216 | } 217 | 218 | public void Put(string key, string value) 219 | { 220 | Save(real, key, value); 221 | } 222 | 223 | /// 224 | /// value的键值对都是基础类型,或为hashtable类型!否则请实现IBmobWritable来处理该数据。 225 | /// 226 | /// 227 | /// 228 | public void Put(string key, IDictionary value) 229 | { 230 | Save(real, key, value); 231 | } 232 | 233 | public void Put(string key, IDictionary value) 234 | { 235 | Save(real, key, value); 236 | } 237 | 238 | public void Put(string key, IList value) 239 | { 240 | Save(real, key, value); 241 | } 242 | 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /core/src/io/BmobPointer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | 6 | namespace cn.bmob.io 7 | { 8 | /// 9 | /// Pointer 类型是当前对象要指向另一个对象时使用,它包含了 className 和 objectId 作为一个指针正确指向的必填值。 10 | /// T类型必须继承自BmobTable! 11 | /// 12 | /// 如果你使用 13 | /// 14 | /// 如,指向用户对象的 Pointer 的 className 为_User, 前面加一个下划线表示开发者不能定义的类名, 而且所指的类是系统内置的。 15 | /// 16 | public class BmobPointer : BmobObject where T : BmobTable 17 | { 18 | 19 | /// 20 | /// 构造函数 21 | /// 22 | public BmobPointer() { } 23 | 24 | /// 25 | /// 构造函数 26 | /// 27 | /// 指针数据 28 | public BmobPointer(T t) 29 | { 30 | this.reference = t; 31 | } 32 | 33 | /// 34 | /// 指针类型 35 | /// 36 | public override string _type { get { return "Pointer"; } } 37 | 38 | /// 39 | /// 关联表的名称 40 | /// 41 | public string className 42 | { 43 | get { return reference == null ? "" : reference.table; } 44 | } 45 | 46 | // TODO 获取其他字段时远程请求 47 | public T reference { get; set; } 48 | 49 | /// 50 | /// 序列化时优先获取refObjectId的值,refObjectId值为null时才取reference的objectId值。 51 | /// 52 | private string _refObjectId; 53 | 54 | /// 55 | /// use T.objectId instead. 56 | /// 57 | [Obsolete] 58 | public string refObjectId 59 | { 60 | get 61 | { 62 | if (_refObjectId == null && reference != null) 63 | { 64 | return reference.objectId; 65 | } 66 | 67 | return _refObjectId; 68 | } 69 | set { this._refObjectId = value; } 70 | } 71 | 72 | public override void write(BmobOutput output, bool all) 73 | { 74 | base.write(output, all); 75 | 76 | output.Put(TYPE_NAME, this._type); 77 | output.Put("className", this.className); 78 | output.Put("objectId", refObjectId); 79 | } 80 | 81 | public override void readFields(BmobInput input) 82 | { 83 | base.readFields(input); 84 | 85 | var className = input.getString("className"); 86 | var objectId = input.getString("objectId"); 87 | var type = input.getString(TYPE_NAME); 88 | 89 | // 返回了对象的详细信息时,type字段值为空。 90 | if (type == this._type) 91 | { 92 | this.refObjectId = objectId; 93 | } 94 | else 95 | { 96 | this.reference = Activator.CreateInstance(); 97 | this.reference.readFields(input); 98 | } 99 | 100 | } 101 | 102 | #region Implicit Conversions 103 | public static implicit operator BmobPointer(T data) 104 | { 105 | return new BmobPointer(data); 106 | } 107 | 108 | #endregion 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /core/src/io/BmobRelation.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace cn.bmob.io 4 | { 5 | public class BmobRelation : List> where T : BmobTable 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /core/src/io/BmobRole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// BmobRole角色管理类 7 | /// 8 | public class BmobRole : BmobTable 9 | { 10 | /// 11 | /// 获取表名 12 | /// 13 | public override string table 14 | { 15 | get 16 | { 17 | return "_Role"; 18 | } 19 | } 20 | 21 | /// 22 | /// 23 | /// 24 | public String name { get; set; } 25 | 26 | public BmobRole AddUsers(BmobRelation value) 27 | { 28 | AddRelation("users", value); 29 | return this; 30 | } 31 | public BmobRole RemoveUsers(BmobRelation value) 32 | { 33 | RemoveRelation("users", value); 34 | return this; 35 | } 36 | 37 | /// 38 | /// 一个角色可以包含另一个,可以为 2 个角色建立一个父-子关系。 这个关系的结果就是任何被授予父角色的权限隐含地被授予子角色。 39 | /// 40 | /// 这样的关系类型通常在用户管理的内容类的应用上比较常见, 比如在论坛中,有一些少数的用户是 "管理员(Administartors)", 有最高的权限,可以调整系统设置、 创建新的论坛等等。 另一类用户是 "版主(Moderators)",他们可以对用户发帖的内容进行管理。可见,任何有管理员权限的人都应该有版主的权限。为建立起这种关系, 您应该把 "Administartors" 的角色设置为 "Moderators" 的子角色, 具体来说就是把 "Administrators" 这个角色加入 "Moderators" 对象的 roles 关系之中 41 | /// 42 | public BmobRole AddRoles(BmobRelation value) 43 | { 44 | AddRelation("roles", value); 45 | return this; 46 | } 47 | public BmobRole RemoveRoles(BmobRelation value) 48 | { 49 | RemoveRelation("roles", value); 50 | return this; 51 | } 52 | 53 | public override void write(BmobOutput output, bool all) 54 | { 55 | base.write(output, all); 56 | 57 | output.Put("name", this.name); 58 | } 59 | 60 | public override void readFields(BmobInput input) 61 | { 62 | base.readFields(input); 63 | 64 | this.name = input.getString("name"); 65 | } 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /core/src/io/BmobTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections; 4 | 5 | namespace cn.bmob.io 6 | { 7 | /// 8 | /// 数据表操作类 9 | /// 10 | public class BmobTable : BmobObject, IBmobOperator 11 | { 12 | 13 | public sealed override string _type { get { return this.table; } } 14 | 15 | /// 16 | /// 获取表名, 默认为对象的名称 17 | /// 18 | public virtual String table { get { return this.GetType().Name; } } 19 | 20 | /// 21 | /// 数据的唯一标识。放开set功能! 22 | /// 23 | /// TODO 如果设置了objectId则为更新!!! 24 | /// 25 | public String objectId { get; set; } 26 | 27 | /// 28 | /// 创建时间 29 | /// 30 | public String createdAt { get; internal set; } 31 | 32 | /// 33 | /// 更新时间 34 | /// 35 | public String updatedAt { get; internal set; } 36 | 37 | /// 38 | /// ACL信息,每条数据默认都有ACL信息 39 | /// 40 | public BmobACL ACL { get; set; } 41 | 42 | private IDictionary operates = new Dictionary(); 43 | 44 | internal IBmobOperator handle(String column, Operate op) 45 | { 46 | BmobOutput.Save(operates, column, op); 47 | return this; 48 | } 49 | 50 | public IBmobOperator Increment(String column, int amount) 51 | { 52 | var value = new Increment(); 53 | value.amount = amount; 54 | return handle(column, value); 55 | } 56 | 57 | /// 58 | /// 自增操作 59 | /// 60 | /// 需要自增的字段 61 | /// 62 | public IBmobOperator Increment(String column) 63 | { 64 | return Increment(column, 1); 65 | } 66 | 67 | /// 68 | /// 删除一个对象中一个字段 69 | /// 70 | /// 需要删除的字段名 71 | /// 72 | public IBmobOperator Delete(String column) 73 | { 74 | var value = new Delete(); 75 | return handle(column, value); 76 | } 77 | 78 | /// 79 | /// 更新数组类型字段的数据。 80 | /// 81 | /// 举个例子,技能skills是一个类似于集合的数组类型,那么我们可以使用该方法在原有skills值基础上添加一些对象(只有在skills原来的对象中不包含这些值的情况下才会被加入) 82 | /// 83 | public IBmobOperator AddUnique(String column, List values) 84 | { 85 | var value = new AddUnique(); 86 | value.objects = values; 87 | return handle(column, value); 88 | } 89 | 90 | /// 91 | /// 添加数组数据。 92 | /// 93 | /// 添加一行记录时创建一个普通的类似于列表的数组类型字段。 94 | /// 95 | public IBmobOperator Add(String column, List values) 96 | { 97 | var value = new Add(); 98 | value.objects = values; 99 | return handle(column, value); 100 | } 101 | 102 | /// 103 | /// 删除数组数据。 104 | /// 105 | /// 把values这些对象从column字段值中移除 106 | /// 107 | public IBmobOperator Remove(String column, List values) 108 | { 109 | var value = new Remove(); 110 | value.objects = values; 111 | return handle(column, value); 112 | } 113 | 114 | /// 115 | /// 添加关联信息 116 | /// 117 | /// 泛型 118 | /// 字段 119 | /// 关联信息 120 | /// 121 | public IBmobOperator AddRelation(String column, BmobRelation values) where T : BmobTable 122 | { 123 | var value = new AddRelation(); 124 | value.objects = values; 125 | return handle(column, value); 126 | } 127 | 128 | /// 129 | /// 删除关联信息 130 | /// 131 | /// 泛型 132 | /// 字段 133 | /// 关联信息 134 | /// 135 | public IBmobOperator RemoveRelation(String column, BmobRelation values) where T : BmobTable 136 | { 137 | var value = new RemoveRelation(); 138 | value.objects = values; 139 | return handle(column, value); 140 | } 141 | 142 | public override void readFields(BmobInput input) 143 | { 144 | base.readFields(input); 145 | 146 | this.objectId = input.getString("objectId"); 147 | this.createdAt = input.getString("createdAt"); 148 | this.updatedAt = input.getString("updatedAt"); 149 | this.ACL = input.Get("ACL"); 150 | } 151 | 152 | public override void write(BmobOutput output, Boolean all) 153 | { 154 | base.write(output, all); 155 | output.Put("ACL", this.ACL); 156 | 157 | foreach (String key in operates.Keys) 158 | { 159 | output.Put(key, (Operate)operates[key]); 160 | } 161 | 162 | if (all) 163 | { 164 | output.Put("objectId", this.objectId); 165 | output.Put("createdAt", this.createdAt); 166 | output.Put("updatedAt", this.updatedAt); 167 | } 168 | } 169 | 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /core/src/io/BmobTable2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections; 4 | 5 | namespace cn.bmob.io 6 | { 7 | /// 8 | /// 数据表操作类 9 | /// 10 | public class BmobTable2 : BmobTable 11 | { 12 | private String _table; 13 | public BmobTable2(String tablename) 14 | : base() 15 | { 16 | this._table = tablename; 17 | } 18 | 19 | public override String table { get { return this._table; } } 20 | 21 | private Dictionary kvs = new Dictionary(); 22 | 23 | public BmobTable2 Set(Dictionary value) 24 | { 25 | this.kvs = value; 26 | return this; 27 | } 28 | 29 | public BmobTable2 Put(String key, Object value) 30 | { 31 | kvs.Add(key, value); 32 | return this; 33 | } 34 | 35 | public override void readFields(BmobInput input) 36 | { 37 | base.readFields(input); 38 | 39 | foreach (var key in input.keySet()) 40 | { 41 | kvs.Add(key, input.getRaw(key)); 42 | } 43 | } 44 | 45 | public override void write(BmobOutput output, Boolean all) 46 | { 47 | base.write(output, all); 48 | 49 | foreach (var entry in kvs) 50 | { 51 | var key = entry.Key; 52 | if (key == "objectId" || key == "createdAt" || key == "updatedAt") 53 | { 54 | continue; 55 | } 56 | output.Put(key, entry.Value); 57 | } 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /core/src/io/BmobUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// 用户操作类 7 | /// 8 | public class BmobUser : BmobTable 9 | { 10 | /// 11 | /// 对应的操作数据表,注意:操作对应的表是_User,这是系统内置的表 12 | /// 13 | public const String TABLE = "_User"; 14 | 15 | /// 16 | /// 获取当前用户 17 | /// 18 | public static BmobUser CurrentUser { get; internal set; } 19 | 20 | /// 21 | /// 退出登录 22 | /// 23 | public static void LogOut() 24 | { 25 | CurrentUser = null; 26 | } 27 | 28 | /// 29 | /// 获取表名 30 | /// 31 | public override sealed string table { get { return TABLE; } } 32 | 33 | /// 34 | /// 用户名 35 | /// 36 | public String username { get; set; } 37 | 38 | /// 39 | /// 密码 40 | /// 41 | public String password { get; set; } 42 | 43 | /// 44 | /// 手机号,接收修改密码短信验证码 45 | /// 46 | public String phone { get; set; } 47 | 48 | /// 49 | /// 邮箱验证信息 50 | /// 51 | public BmobBoolean emailVerified { get; set; } 52 | 53 | /// 54 | /// 邮箱,用于校验和重置密码! 55 | /// 56 | public String email { get; set; } 57 | 58 | /// 59 | /// 登录之后的会话信息 60 | /// 61 | public String sessionToken { get; set; } 62 | 63 | public override void readFields(BmobInput input) 64 | { 65 | base.readFields(input); 66 | 67 | this.username = input.getString("username"); 68 | this.password = input.getString("password"); 69 | this.email = input.getString("email"); 70 | this.sessionToken = input.getString("sessionToken"); 71 | 72 | this.emailVerified = input.getBoolean("emailVerified"); 73 | } 74 | 75 | public override void write(BmobOutput output, Boolean all) 76 | { 77 | base.write(output, all); 78 | 79 | if (all) 80 | { 81 | output.Put("sessionToken", this.sessionToken); 82 | } 83 | 84 | output.Put("username", this.username); 85 | output.Put("password", this.password); 86 | output.Put("email", this.email); 87 | } 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /core/src/io/IBmobOperator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace cn.bmob.io 3 | { 4 | 5 | /// 6 | /// 操作类。可以作用于任一对象的任何字段,这里提取出来作为公共的基类。 7 | /// 8 | public interface IBmobOperator 9 | { 10 | IBmobOperator Increment(string column); 11 | IBmobOperator Increment(string column, int amount); 12 | 13 | IBmobOperator Add(string column, System.Collections.Generic.List values); 14 | IBmobOperator AddUnique(string column, System.Collections.Generic.List values); 15 | IBmobOperator Remove(string column, System.Collections.Generic.List values); 16 | 17 | IBmobOperator AddRelation(string column, BmobRelation values) where T : BmobTable; 18 | IBmobOperator RemoveRelation(string column, BmobRelation values) where T : BmobTable; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/io/IBmobValue.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace cn.bmob.io 3 | { 4 | /// 5 | /// 实现该接口的类直接进行赋值 6 | /// 7 | /// Visible For API! 暂时仅支持API自带的值类型. 由于泛型T,导致在JSON解析注册时很麻烦,不推荐用户实现值类型! 8 | /// 9 | public interface IBmobValue : IBmobValue 10 | { 11 | T Get(); 12 | } 13 | 14 | public interface IBmobValue 15 | { 16 | void Set(object data); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/io/IBmobWritable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// Bmob自定义的序列化反序列化的对象,Hashtable仅支持简单类型和Hashtable。对象就是简单类型的组合! 7 | /// 8 | public interface IBmobWritable 9 | { 10 | /// 11 | /// 获取自定义对象的类型 12 | /// 13 | string _type { get; } 14 | 15 | /// 16 | /// 把服务端返回的数据转化为本地对象值 17 | /// 18 | /// 19 | void readFields(BmobInput input); 20 | 21 | /// 22 | /// 把本地对象写入到output,后续序列化提交到服务器 23 | /// 24 | /// 25 | /// 用于区分请求/打印输出序列化 26 | void write(BmobOutput output, Boolean all); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /core/src/io/basic/BmobBoolean.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | 6 | namespace cn.bmob.io 7 | { 8 | public sealed class BmobBoolean : IBmobValue 9 | { 10 | private Boolean value; 11 | 12 | public BmobBoolean() { } 13 | 14 | public BmobBoolean(bool value) 15 | { 16 | this.value = value; 17 | } 18 | 19 | public Boolean Get() 20 | { 21 | return this.value; 22 | } 23 | 24 | public void Set(object o) 25 | { 26 | if (o is Boolean) 27 | { 28 | this.value = (Boolean)o; 29 | } 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return Get().ToString(); 35 | } 36 | 37 | #region Implicit Conversions 38 | public static implicit operator BmobBoolean(Boolean data) 39 | { 40 | return new BmobBoolean(data); 41 | } 42 | 43 | #endregion 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/io/basic/BmobDouble.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | 6 | namespace cn.bmob.io 7 | { 8 | public sealed class BmobDouble : BmobNumber 9 | { 10 | 11 | public BmobDouble() 12 | : base() 13 | { } 14 | 15 | public BmobDouble(double value) 16 | : base(value) 17 | { 18 | } 19 | 20 | #region Implicit Conversions 21 | public static implicit operator BmobDouble(double data) 22 | { 23 | return new BmobDouble(data); 24 | } 25 | 26 | #endregion 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/io/basic/BmobInt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | 6 | namespace cn.bmob.io 7 | { 8 | public sealed class BmobInt : BmobNumber 9 | { 10 | 11 | public BmobInt() 12 | : base() 13 | { } 14 | 15 | public BmobInt(int value) 16 | : base(value) 17 | { 18 | } 19 | 20 | #region Implicit Conversions 21 | public static implicit operator BmobInt(int data) 22 | { 23 | return new BmobInt(data); 24 | } 25 | 26 | #endregion 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/io/basic/BmobLong.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | 6 | namespace cn.bmob.io 7 | { 8 | public sealed class BmobLong : BmobNumber 9 | { 10 | 11 | public BmobLong() 12 | : base() 13 | { } 14 | 15 | public BmobLong(long value) 16 | : base(value) 17 | { 18 | } 19 | 20 | #region Implicit Conversions 21 | public static implicit operator BmobLong(long data) 22 | { 23 | return new BmobLong(data); 24 | } 25 | 26 | #endregion 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/io/basic/BmobNumber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | 6 | namespace cn.bmob.io 7 | { 8 | public abstract class BmobNumber : IBmobValue 9 | { 10 | private T value; 11 | 12 | public BmobNumber() { } 13 | 14 | public BmobNumber(T value) 15 | { 16 | this.value = value; 17 | } 18 | 19 | public T Get() 20 | { 21 | return this.value; 22 | } 23 | 24 | public void Set(Object o) 25 | { 26 | if (o is T) 27 | { 28 | this.value = (T)o; 29 | } 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return Get().ToString(); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/src/io/operator/Add.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace cn.bmob.io 4 | { 5 | internal class Add : Operate 6 | { 7 | 8 | public List objects { get; set; } 9 | 10 | public override void write(BmobOutput output, bool all) 11 | { 12 | base.write(output, all); 13 | 14 | output.Put(OP_NAME, "Add"); 15 | output.Put("objects", this.objects); 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/io/operator/AddRelation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace cn.bmob.io 3 | { 4 | /// 5 | /// Relation 类型被用在多对多的类型上, 移动端的库将使用 BmobRelation 作为值, 它有一个 className 字段表示目标对象的类名 6 | /// 7 | /// 当使用查询时, Relation 对象的行为很像是 Pointer 的数组, 任何操作针对于 Pointer 的数组的 (除了 include) 都可以对 Relation 起作用. 8 | /// 9 | internal class AddRelation : Operate where T : BmobTable 10 | { 11 | public BmobRelation objects { get; set; } 12 | 13 | public override void write(BmobOutput output, bool all) 14 | { 15 | base.write(output, all); 16 | 17 | output.Put(OP_NAME, "AddRelation"); 18 | output.Put("objects", this.objects); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/io/operator/AddUnique.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace cn.bmob.io 4 | { 5 | internal class AddUnique : Operate 6 | { 7 | public List objects { get; set; } 8 | 9 | public override void write(BmobOutput output, bool all) 10 | { 11 | base.write(output, all); 12 | 13 | output.Put(OP_NAME, "AddUnique"); 14 | output.Put("objects", this.objects); 15 | } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/io/operator/Delete.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace cn.bmob.io 3 | { 4 | internal class Delete : Operate 5 | { 6 | 7 | public override void write(BmobOutput output, bool all) 8 | { 9 | base.write(output, all); 10 | output.Put(OP_NAME, "Delete"); 11 | } 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /core/src/io/operator/Increment.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// 原子计数器 7 | /// 8 | internal class Increment : Operate 9 | { 10 | 11 | protected string op { get { return "Increment"; } } 12 | 13 | public int amount { get; set; } 14 | 15 | public override void write(BmobOutput output, Boolean all) 16 | { 17 | output.Put("__op", this.op); 18 | output.Put("amount", this.amount); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/io/operator/Operate.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace cn.bmob.io 3 | { 4 | internal class Operate : BmobObject 5 | { 6 | public const string OP_NAME = "__op"; 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /core/src/io/operator/Remove.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace cn.bmob.io 6 | { 7 | internal class Remove : Operate 8 | { 9 | 10 | public List objects { get; set; } 11 | 12 | public override void write(BmobOutput output, bool all) 13 | { 14 | base.write(output, all); 15 | 16 | output.Put(OP_NAME, "Remove"); 17 | output.Put("objects", this.objects); 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/io/operator/RemoveRelation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace cn.bmob.io 3 | { 4 | internal class RemoveRelation : Operate where T : BmobTable 5 | { 6 | public BmobRelation objects { get; set; } 7 | 8 | public override void write(BmobOutput output, bool all) 9 | { 10 | base.write(output, all); 11 | 12 | output.Put(OP_NAME, "RemoveRelation"); 13 | output.Put("objects", this.objects); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/io/paramater/BmobBatch.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.api; 2 | using cn.bmob.exception; 3 | using cn.bmob.http; 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | 8 | using System.Text; 9 | 10 | namespace cn.bmob.io 11 | { 12 | /// 13 | /// 为了减少因为网络通讯次数太多而带来的时间浪费, 你可以使用下面的批量(batch)操作,在一个请求中对多个普通对象(不支持系统内置的用户对象)进行添加(create)、更新(update)、删除(delete) 操作 14 | /// 15 | /// 上限为50个, 这些操作会以发送过去的顺序来执行 16 | /// 17 | public sealed class BmobBatch : BmobObject 18 | { 19 | 20 | private class __Bmob : Bmob 21 | { 22 | private List requests = new List(); 23 | 24 | internal override void submit(BmobCommand command, BmobCallback callback) 25 | { 26 | requests.Add(command.getReceiver()); 27 | } 28 | 29 | public List Requests { get { return requests; } } 30 | 31 | } 32 | 33 | private __Bmob BmobWrapper = new __Bmob(); 34 | 35 | private void NonCallback(T resp, BmobException ex) { } 36 | 37 | public override void write(BmobOutput output, bool all) 38 | { 39 | base.write(output, all); 40 | 41 | var requests = new List(); 42 | foreach (BmobInteractObject req in BmobWrapper.Requests) 43 | { 44 | String method = req.Method; 45 | if (method == null) 46 | { 47 | continue; 48 | } 49 | 50 | // XXX 1.6 根据restful接口优化 51 | String path = ""; 52 | if (method.Equals("POST")) 53 | { 54 | path = "/1/classes/" + req.Table; 55 | } 56 | else if (method.Equals("DELETE") || method.Equals("PUT")) 57 | { 58 | path = "/1/classes/" + req.Table + "/" + req.ObjectId; 59 | } 60 | 61 | IDictionary one = new Dictionary(); 62 | 63 | BmobOutput.Save(one, "method", method); 64 | if (BmobUser.CurrentUser != null) 65 | BmobOutput.Save(one, "token", BmobUser.CurrentUser.sessionToken); 66 | BmobOutput.Save(one, "path", path); 67 | BmobOutput.Save(one, "body", req.Data); 68 | requests.Add(one); 69 | } 70 | 71 | output.Put("requests", requests); 72 | } 73 | 74 | #region GenCode 75 | 76 | public BmobBatch Create(String tablename, IBmobWritable data) 77 | { 78 | BmobWrapper.Create(tablename, data, NonCallback); 79 | return this; 80 | } 81 | 82 | public BmobBatch Create(T data) where T : cn.bmob.io.BmobTable 83 | { 84 | BmobWrapper.Create(data, NonCallback); 85 | return this; 86 | } 87 | 88 | public BmobBatch Delete(String tablename, String objectId) 89 | { 90 | BmobWrapper.Delete(tablename, objectId, NonCallback); 91 | return this; 92 | } 93 | 94 | public BmobBatch Delete(T data) where T : cn.bmob.io.BmobTable 95 | { 96 | BmobWrapper.Delete(data, NonCallback); 97 | return this; 98 | } 99 | 100 | public BmobBatch Update(String tablename, String objectId, IBmobWritable data) 101 | { 102 | BmobWrapper.Update(tablename, objectId, data, NonCallback); 103 | return this; 104 | } 105 | 106 | public BmobBatch Update(T data) where T : cn.bmob.io.BmobTable 107 | { 108 | BmobWrapper.Update(data, NonCallback); 109 | return this; 110 | } 111 | 112 | #endregion 113 | 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /core/src/io/paramater/BmobLocalFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | using cn.bmob.api; 6 | using cn.bmob.exception; 7 | 8 | namespace cn.bmob.io 9 | { 10 | /// 11 | /// 文件处理类 12 | /// 13 | /// byte[]优先级最高,流,最后才是判断filename获取本地文件的内容 14 | /// 15 | public sealed class BmobLocalFile 16 | { 17 | private String filename; 18 | private byte[] datas; 19 | private Stream inputStream; 20 | 21 | public BmobLocalFile(byte[] datas) 22 | { 23 | this.datas = datas; 24 | } 25 | 26 | public BmobLocalFile(Stream inputStream) 27 | { 28 | this.inputStream = inputStream; 29 | } 30 | 31 | /// 32 | /// 上传附件内容构造函数 33 | /// 34 | /// 文件内容 35 | /// 文件标识,[文件名称.后缀]的形式组成,如: bmob.png。上传成功后回调的filename属性的值 36 | public BmobLocalFile(byte[] datas, string name) 37 | { 38 | this.datas = datas; 39 | this.filename = name; 40 | } 41 | 42 | /// 43 | /// 上传附件内容构造函数 44 | /// 45 | /// 附件流 46 | /// 文件标识,[文件名称.后缀]的形式组成,如: bmob.png。上传成功后回调的filename属性的值 47 | public BmobLocalFile(Stream inputStream, string name) 48 | { 49 | this.inputStream = inputStream; 50 | this.filename = name; 51 | } 52 | 53 | #if !WIN8_1 54 | 55 | /// 56 | /// 构造函数(设置文件路径) 57 | /// 58 | /// 文件路径 59 | public BmobLocalFile(String path) 60 | { 61 | this.filename = path; 62 | } 63 | 64 | /// 65 | /// 构造函数(设置文件路径) 66 | /// 67 | /// 文件对象 68 | public BmobLocalFile(FileInfo file) 69 | { 70 | this.filename = file.FullName; 71 | } 72 | #endif 73 | 74 | ///// 75 | ///// 获得文本文件的内容信息 76 | ///// 77 | ///// 文件内容 78 | //public string Get() 79 | //{ 80 | // // // byte[] ContentsBody = System.IO.File.ReadAllBytes(filepath); 81 | // return File.ReadAllText(filename); 82 | //} 83 | 84 | /// 85 | /// 获取文件流 86 | /// 87 | /// 文件流 88 | public byte[] Content() 89 | { 90 | var data = contentData(); 91 | if (data.Length > 10 * 1024 * 1024) 92 | { 93 | throw new BmobException("file maxsize is 10M, but upload file size is " + data.Length); 94 | } 95 | 96 | return data; 97 | } 98 | 99 | private byte[] contentData() 100 | { 101 | // 要上传的文件 102 | // byte[] ContentsBody = System.IO.File.ReadAllBytes(filepath); 103 | //byte[] ContentsBody; 104 | //using (var filestream = File.OpenRead(filepath)) 105 | //{ 106 | // int fileLen = (int)filestream.Length; 107 | // ContentsBody = new byte[fileLen]; 108 | // filestream.Read(ContentsBody, 0, fileLen); 109 | //} 110 | if (datas != null) 111 | { 112 | return datas; 113 | } 114 | else 115 | { 116 | #if !WIN8_1 117 | Boolean close = false; 118 | try 119 | { 120 | if (inputStream == null) 121 | { 122 | close = true; 123 | inputStream = File.OpenRead(filename); 124 | } 125 | 126 | int fileLen = (int)inputStream.Length; 127 | byte[] ContentsBody = new byte[fileLen]; 128 | inputStream.Read(ContentsBody, 0, fileLen); 129 | return ContentsBody; 130 | } 131 | finally 132 | { 133 | if (close && inputStream != null) 134 | { 135 | inputStream.Close(); 136 | } 137 | } 138 | #else 139 | throw new FileNotFoundException("SDK WIN8.1暂不支持传入文件名的方式上传数据!!!"); 140 | #endif 141 | } 142 | 143 | } 144 | 145 | /// 146 | /// 获取文件名 147 | /// 148 | /// 文件名 149 | public String Filename() 150 | { 151 | return this.filename == null 152 | ? "[Binary].bmo" 153 | : this.filename.Replace("_", ""); // 服务端下划线BUG[2014-08-19] 154 | } 155 | 156 | ///// 157 | ///// 获取文件名(BASE64编码处理) 158 | ///// 159 | ///// 160 | //public String getFilenameBase64() 161 | //{ 162 | // return Convert.ToBase64String(Encoding.UTF8.GetBytes(filename)); 163 | //} 164 | 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /core/src/io/paramater/BmobRemote.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.api; 2 | using cn.bmob.exception; 3 | using cn.bmob.http; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | 9 | namespace cn.bmob.io 10 | { 11 | /// 12 | /// 可以参考BmobCloud 13 | /// 14 | public sealed class BmobRemote : BmobObject 15 | { 16 | 17 | private class __Bmob : Bmob 18 | { 19 | private List requests = new List(); 20 | 21 | internal override void submit(BmobCommand command, BmobCallback callback) 22 | { 23 | requests.Add(command.getReceiver()); 24 | } 25 | 26 | public List Requests { get { return requests; } } 27 | 28 | } 29 | 30 | private Bmob BmobWrapper = new __Bmob(); 31 | 32 | private void NonCallback(T resp, BmobException ex) { } 33 | 34 | #region GenCode -------------------------- 35 | 36 | public BmobRemote Batch(BmobBatch requests) 37 | { 38 | BmobWrapper.Batch(requests, NonCallback); 39 | return this; 40 | } 41 | 42 | public BmobRemote Create(String tablename, IBmobWritable data) 43 | { 44 | BmobWrapper.Create(tablename, data, NonCallback); 45 | return this; 46 | } 47 | 48 | public BmobRemote Create(T data) where T : cn.bmob.io.BmobTable 49 | { 50 | BmobWrapper.Create(data, NonCallback); 51 | return this; 52 | } 53 | 54 | public BmobRemote Delete(String tablename, String objectId) 55 | { 56 | BmobWrapper.Delete(tablename, objectId, NonCallback); 57 | return this; 58 | } 59 | 60 | public BmobRemote Delete(T data) where T : cn.bmob.io.BmobTable 61 | { 62 | BmobWrapper.Delete(data, NonCallback); 63 | return this; 64 | } 65 | 66 | public BmobRemote DeleteUser(String objectId, String sessionToken) 67 | { 68 | BmobWrapper.DeleteUser(objectId, sessionToken, NonCallback); 69 | return this; 70 | } 71 | 72 | public BmobRemote DeleteUser(T data) where T : cn.bmob.io.BmobUser 73 | { 74 | BmobWrapper.DeleteUser(data, NonCallback); 75 | return this; 76 | } 77 | 78 | public BmobRemote EmailVerify(String email) 79 | { 80 | BmobWrapper.EmailVerify(email, NonCallback); 81 | return this; 82 | } 83 | 84 | public BmobRemote Endpoint(String eMethod, System.Collections.Generic.IDictionary parameters) 85 | { 86 | BmobWrapper.Endpoint(eMethod, parameters, NonCallback); 87 | return this; 88 | } 89 | 90 | public BmobRemote Endpoint(String eMethod) 91 | { 92 | BmobWrapper.Endpoint(eMethod, NonCallback); 93 | return this; 94 | } 95 | 96 | public BmobRemote FileDelete(String url) 97 | { 98 | BmobWrapper.FileDelete(url, NonCallback); 99 | return this; 100 | } 101 | 102 | public BmobRemote Find(String tablename, BmobQuery query) 103 | { 104 | BmobWrapper.Find(tablename, query, NonCallback); 105 | return this; 106 | } 107 | 108 | public BmobRemote Get(String tablename, String objectId) 109 | { 110 | BmobWrapper.Get(tablename, objectId, NonCallback); 111 | return this; 112 | } 113 | 114 | public BmobRemote Get(T data) where T : cn.bmob.io.BmobTable 115 | { 116 | BmobWrapper.Get(data, NonCallback); 117 | return this; 118 | } 119 | 120 | public BmobRemote Login(String username, String pwd) where T : cn.bmob.io.BmobUser 121 | { 122 | BmobWrapper.Login(username, pwd, NonCallback); 123 | return this; 124 | } 125 | 126 | public BmobRemote Login(String username, String pwd) 127 | { 128 | BmobWrapper.Login(username, pwd, NonCallback); 129 | return this; 130 | } 131 | 132 | public BmobRemote Push(PushParamter param) 133 | { 134 | BmobWrapper.Push(param, NonCallback); 135 | return this; 136 | } 137 | 138 | public BmobRemote Reset(String email) 139 | { 140 | BmobWrapper.Reset(email, NonCallback); 141 | return this; 142 | } 143 | 144 | public BmobRemote Signup(T user) where T : cn.bmob.io.BmobUser 145 | { 146 | BmobWrapper.Signup(user, NonCallback); 147 | return this; 148 | } 149 | 150 | public BmobRemote Signup(BmobUser user) 151 | { 152 | BmobWrapper.Signup(user, NonCallback); 153 | return this; 154 | } 155 | 156 | public BmobRemote Thumbnail(ThumbnailParameter param) 157 | { 158 | BmobWrapper.Thumbnail(param, NonCallback); 159 | return this; 160 | } 161 | 162 | public BmobRemote Update(String tablename, String objectId, IBmobWritable data) 163 | { 164 | BmobWrapper.Update(tablename, objectId, data, NonCallback); 165 | return this; 166 | } 167 | 168 | public BmobRemote Update(T data) where T : cn.bmob.io.BmobTable 169 | { 170 | BmobWrapper.Update(data, NonCallback); 171 | return this; 172 | } 173 | 174 | public BmobRemote UpdateUser(String objectId, BmobUser data, String sessionToken) 175 | { 176 | BmobWrapper.UpdateUser(objectId, data, sessionToken, NonCallback); 177 | return this; 178 | } 179 | 180 | public BmobRemote UpdateUser(T data) where T : cn.bmob.io.BmobUser 181 | { 182 | BmobWrapper.UpdateUser(data, NonCallback); 183 | return this; 184 | } 185 | 186 | #endregion 187 | 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /core/src/io/paramater/PushParamter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | 5 | namespace cn.bmob.io 6 | { 7 | 8 | /// 9 | /// 接收 Windows Phone 的推送通知: http://msdn.microsoft.com/zh-cn/library/hh202945(v=vs.92).aspx 10 | /// 11 | /// 与 Web 服务进行通信的最佳做法包括: 12 | /// * 应用程序应该对其相应的 Web 服务进行身份验证。 13 | /// * 应用程序应该在向其相应的 Web 服务发送 URI 之前对其通知通道 URI 进行加密。 14 | /// * 如果您的 Web 服务将使用 Windows Phone OS 7.0 中不存在的通知属性(Toast 通知的 Parameter 属性和 Tile 通知的 BackTitle、BackBackgroundImage、BackContent 或 Tile ID 属性),则您应将操作系统版本信息传递到您的 Web 服务,以便 Web 服务可以正确降级 Windows Phone OS 7.0 客户端的通知。 15 | /// * Web 服务应该验证从其相应应用程序接收的通知通道 URI 并采用安全方式进行存储。 16 | /// * 当启动应用程序中的会话时,通知通道 URI 应该始终发送到其相应的 Web 服务。 17 | /// * Web 服务应该拥有一个可以发送到其相应应用程序的状态代码,该代码将触发应用程序创建新的通知通道 URI。 18 | /// 19 | public sealed class PushParamter : BmobObject 20 | { 21 | private BmobQuery target = new BmobQuery(); 22 | public BmobQuery Target { get { return target; } } 23 | 24 | private IDictionary message = new Dictionary(); 25 | public IDictionary Message { get { return this.message; } } 26 | 27 | /// 28 | /// "2013-12-04 00:51:13" 29 | /// 30 | public String ExpirationTime; 31 | 32 | /// 33 | /// 相对时间(根据push_time做定期推送,从push_time时间开始算起,直到expiration_interval时间后过期) 34 | /// 35 | /// "2012-01-28 00:51:13" 36 | /// 37 | public String PushTime { get; set; } 38 | /// 39 | /// 518400 40 | /// 41 | public BmobInt ExpirationInterval; 42 | 43 | #if WINDOWS_PHONE || FRAMEWORK 44 | /// 45 | /// http://msdn.microsoft.com/zh-cn/library/hh202945(v=vs.92).aspx 46 | /// 47 | //private void buildMessage(String type, int batchingInterval, String body) 48 | //{ 49 | // IDictionary headers = new Dictionary(); 50 | 51 | // // X-MessageID: 52 | // // X-CallbackURI:callbackUri 53 | 54 | // // 要发送的推送通知的类型。可能的选项为磁贴、Toast 和 Raw。如果此标头不存在,则推送通知将被视为 Raw 通知。 55 | // if (type != null) 56 | // headers.Add("X-WindowsPhone-Target", type); 57 | 58 | // // 批处理间隔,指示推送通知将从推送通知服务发送到应用程序的时间。有关此标头的可能值,请参阅 Toast、磁贴和 Raw 通知部分中的表。如果此标头不存在,则推送通知服务会立即发送该消息。 59 | // headers.Add("X-NotificationClass", batchingInterval + ""); 60 | 61 | // Message.Add("ContentType", "text/xml"); 62 | // Message.Add("body", body); 63 | // Message.Add("headers", headers); 64 | //} 65 | 66 | private static String encode(String origin) 67 | { 68 | if (origin == null) 69 | { 70 | return ""; 71 | } 72 | return WebUtility.HtmlEncode(origin); 73 | } 74 | 75 | /// 76 | /// Toast 通知 77 | /// 78 | /// 可以显示的文本数量取决于在 Toast 消息中使用的字符以及“标题”(粗体)和“内容”(非粗体)的长度。 79 | /// * 如果只设置了一个“标题”,则可以显示大约 40 个字符,之后的字符将被截断。 80 | /// * 如果只设置了“内容”,则可以显示大约 47 个字符。 81 | /// * 如果一个 Toast 在“标题”和“内容”之间平均拆分,则可以显示大约 41 个字符。无法放在 Toast 上的任何文本都将被截断。 82 | /// 83 | /// 标题 84 | /// 内容 85 | /// 参数。如果用户点按 Toast,则将参数值传递给您的应用程序,而不进行显示。该参数可以指示应用程序应该启动到的页面。该参数还包含传递到应用程序的名称-值对。在 XML 架构中,该字符串定义为 Param 属性。 86 | /// 87 | /// 用于设置 Parameter 属性的 Toast 通知只能发送到运行 Windows Phone OS 7.1 或更高版本的设备。将具有 Parameter 属性的通知发送到 Windows Phone OS 7.0 设备将导致 PushErrorTypePayloadFormatInvalid 错误,并且通道会关闭。 88 | /// 89 | /// * /page1.xaml – 定义应用程序启动时导航到的应用程序中的页面。该页面必须以“/”开头。 90 | /// * /page1.xaml?value1=1234 &value2=9876 – 定义应用程序启动时导航到的页面,以及信息的名称/值对。该页面必须以“/”开头。 91 | /// * ?value1=1234 &value2=9876 – 包含传递给应用程序默认开始页面的信息名称/值对。该页面必须以“?”开头。 92 | /// 93 | /// 2 立即发送; 12 在 450 秒内发送; 22 在 900 秒内发送。 94 | public PushParamter toast(String text1, String text2/*, String param, int batchingInterval*/) 95 | { 96 | Message.Add("alert", encode(text1)); 97 | Message.Add("wpAlert", encode(text2)); 98 | Message.Add("wp", 2); 99 | 100 | return this; 101 | } 102 | /* 103 | public PushParamter tokenClear() 104 | { 105 | return token(null, null, null, null, null, null, true, 1); 106 | } 107 | */ 108 | public PushParamter token(String title, int count, String backTitle, String backContent) 109 | { 110 | return token(title, null, count, null, backTitle, backContent, false, 1); 111 | } 112 | 113 | /// 114 | /// 磁贴通知 115 | /// 116 | /// 用于设置 BackTitle、BackBackgroundImage 或 BackContent 属性的磁贴通知或通过在负载中设置磁贴 ID 来指定次要磁贴的通知只能发送到运行 Windows Phone OS 7.1 或更高版本的设备。将具有这些值的通知发送到 Windows Phone OS 7.0 设备将导致 PushErrorTypePayloadFormatInvalid 错误,并且通道会关闭。 117 | /// 118 | /// 添加图片: 119 | /// 在“解决方案资源管理器”中选择 Red.jpg。在“属性”窗口中,将“生成操作”设置为“内容”以将该图形包含在 .xap 文件中。对其他 .jpg 文件重复这些步骤。 120 | /// 121 | /// 图像上一些用于 BackgroundImage 和 BackBackgroundImage 属性的附加说明: 122 | /// * 磁贴图像可以是 .jpg 或 .png 文件。 123 | /// * 由于网络可变性和性能原因,请考虑对磁贴图像使用本地资源。 124 | /// * 对图像使用具有透明部分的 .png 将允许用户透过它显示主题颜色。 125 | /// * 磁贴为 173 x 173 像素。如果您提供的图像具有不同的尺寸,则会将其拉伸以适合 173 x 173 像素的大小。 126 | /// * 可以使用本地或远程资源作为图像。如果使用本地资源,则该资源必须作为 XAP 包的一部分安装。 127 | /// * 如果用户关闭磁贴通知,则磁贴应该包含常规信息。不应该包含任何过时的数据,如过期的天气预报或流量报告。 128 | /// * 不支持 https 作为远程图像。 129 | /// * 远程图像限制为 80 KB 或更少。如果大于 80 KB,则将不会下载。 130 | /// * 远程图像必须在 30 秒或更少的时间内下载,否则将不会下载。 131 | /// * 如果 BackgroundImage 或 BackBackgroundImage 图像由于任何原因无法加载,则不会更改在更新中设置的其他任何属性。 132 | /// 133 | /// Navigation Uri of the Tile to update. 134 | /// 135 | /// Id 指定要更新的磁贴(如果应用程序有次要磁贴)。若要更新应用程序磁贴,可以忽略此 Id; 136 | /// 否则此 ID 应该包含次要磁贴的确切导航 URI. 如: /SecondaryTile.xaml?DefaultTitle=FromTile 137 | /// 若要清除磁贴属性的值,请将 Action 特性设置为该属性的 Clear。最总发送给MPNS时会作为节点属性发送请求。 138 | /// 139 | /// 请注意,不能清除 BackgroundImage 属性,因为您应该始终在磁贴的正面设置背景图像。 140 | /// 标题。指示应用程序标题的字符串。标题必须适合单行文本并且不应该比实际磁贴宽。标题中大约可以包含 15 个字符,多余部分将被截断。 141 | /// BackgroundImage。显示在磁贴正面的图像。建议您在磁贴正面始终拥有背景图像。 142 | /// 计数(也称为徽章)。从 1 到 99 的整数值。如果未设置“计数”的值或者设置为 0,则不会在磁贴上显示圆形图像和值。 143 | /// BackTitle。显示在磁贴背面底部的字符串。BackTitle 必须适合单行文本并且不应该比实际磁贴宽。标题中大约可以包含 15 个字符,多余部分将被截断。 144 | /// BackContent。显示在磁贴背面中心的字符串。磁贴中大约可以包含 40 个字符,多余部分将被截断。 145 | /// BackBackgroundImage。显示在磁贴背面的图像。 146 | /// 1 立即发送; 11 在 450 秒内发送; 21 在 900 秒内发送。 147 | public PushParamter token(/*String Id, */String title, String backgroundImage, int? count, String backBackgroundImage, String backTitle, String backContent, bool clear, int batchingInterval) 148 | { 149 | Message.Add("alert", encode(title)); 150 | Message.Add("backgroundImage", encode(backgroundImage)); 151 | Message.Add("count", count); 152 | Message.Add("backBackgroundImage", encode(backBackgroundImage)); 153 | Message.Add("backTitle", encode(backTitle)); 154 | Message.Add("backContent", encode(backContent)); 155 | Message.Add("wp", 1); 156 | 157 | return this; 158 | } 159 | 160 | /// 161 | /// Raw 通知 162 | /// 163 | /// 可以使用 Raw 通知向您的应用程序发送信息。如果您的应用程序当前未运行,则 Raw 通知会在 Microsoft 推送通知服务上丢弃并且不会发送到设备。 164 | /// 165 | /// 3 立即发送; 13 在 450 秒内发送; 23 在 900 秒内发送。 166 | public PushParamter raw(String message/*, int batchingInterval*/) 167 | { 168 | // string tileMessage = "" + 169 | //"" + 170 | // "" + 171 | // "" + 172 | //"" 173 | // 也可以只传递字节流。下面的代码显示了一个示例。 174 | //new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; 175 | 176 | Message.Add("alert", message); 177 | Message.Add("wpAlert", ""); 178 | Message.Add("wp", 3); 179 | 180 | return this; 181 | } 182 | #endif 183 | 184 | public PushParamter whereChannels(IList channels) 185 | { 186 | Target.WhereEqualTo("channels", channels); 187 | return this; 188 | } 189 | 190 | public PushParamter whereDeviceType(String deviceType) 191 | { 192 | Target.WhereEqualTo("deviceType", deviceType); 193 | return this; 194 | } 195 | 196 | public PushParamter whereInstallationId(String installationId) 197 | { 198 | Target.WhereEqualTo("installationId", installationId); 199 | return this; 200 | } 201 | 202 | public PushParamter whereDeviceToken(String deviceToken) 203 | { 204 | Target.WhereEqualTo("deviceToken", deviceToken); 205 | return this; 206 | } 207 | 208 | public PushParamter whereNotificationUri(String notificationUri) 209 | { 210 | Target.WhereEqualTo("notificationUri", notificationUri); 211 | return this; 212 | } 213 | 214 | public PushParamter where(BmobQuery anotherQuery) 215 | { 216 | this.target = Target.And(anotherQuery); 217 | return this; 218 | } 219 | 220 | public override void write(BmobOutput output, bool all) 221 | { 222 | base.write(output, all); 223 | 224 | output.Put("where", Target.where); 225 | output.Put("data", Message); 226 | 227 | output.Put("expiration_time", ExpirationTime); 228 | 229 | output.Put("push_time", PushTime); 230 | output.Put("expiration_interval", ExpirationInterval); 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /core/src/io/paramater/SMSParamter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | 5 | namespace cn.bmob.io 6 | { 7 | 8 | /// 9 | /// 短信 10 | /// 11 | public sealed class SMSParamter : BmobObject 12 | { 13 | public string mobilePhoneNumber { get; set; } 14 | public string template { get; set; } 15 | 16 | public string code { get; set; } 17 | 18 | public string smsId { get; set; } 19 | 20 | public override void write(BmobOutput output, bool all) 21 | { 22 | base.write(output, all); 23 | 24 | output.Put("mobilePhoneNumber", mobilePhoneNumber); 25 | output.Put("template", template); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/io/paramater/ThumbnailParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace cn.bmob.io 4 | { 5 | /// 6 | /// mode:模式 0: 指定宽, 高自适应,等比例缩放 7 | // 模式 1: 指定高, 宽自适应,等比例缩放 8 | // 模式 2: 指定最长边,短边自适应,等比例缩放 9 | // 模式 3: 指定最短边,长边自适应,等比例缩放 10 | // 模式 4: 指定最大宽高, 等比例缩放 11 | // 模式 5: 固定宽高, 居中裁剪 12 | //image:原图片url 13 | //width:宽度,模式 0, 4, 5必填 14 | //height:高度,模式 1, 4, 5必填 15 | //longEdge:长边,模式 2必填 16 | //shortEdge:短边,模式 3必填 17 | //quality:质量,选填, 范围 1-100 18 | //outType:输出类型,0:默认,输出url;1:输出base64编码的字符串流 19 | /// 20 | public sealed class ThumbnailParameter : BmobObject, IBmobWritable 21 | { 22 | public ThumbnailParameter(double width, double height, String image) 23 | { 24 | Mode = 4; Width = width; Height = height; Quality = 100; OutType = 1; Image = image; 25 | } 26 | 27 | public ThumbnailParameter(double width, String image) 28 | { 29 | Mode = 0; Width = width; Quality = 100; OutType = 1; Image = image; 30 | } 31 | 32 | public ThumbnailParameter() 33 | { 34 | Mode = 0; Quality = 100; OutType = 1; 35 | } 36 | 37 | public BmobInt Mode { get; set; } 38 | public string Image { get; set; } 39 | public BmobDouble Width { get; set; } 40 | public BmobDouble Height { get; set; } 41 | public BmobDouble LongEdge { get; set; } 42 | public BmobDouble ShortEdge { get; set; } 43 | public BmobInt Quality { get; set; } 44 | public BmobInt OutType { get; set; } 45 | 46 | public override void write(BmobOutput output, bool all) 47 | { 48 | base.write(output, all); 49 | 50 | if (Mode != null) output.Put("mode", Mode); 51 | if (Width != null) output.Put("width", Width); 52 | if (Height != null) output.Put("height", Height); 53 | if (LongEdge != null) output.Put("longEdge", LongEdge); 54 | if (ShortEdge != null) output.Put("shortEdge", ShortEdge); 55 | if (Quality != null) output.Put("quality", Quality); 56 | if (OutType != null) output.Put("outType", OutType); 57 | 58 | if (Image != null) output.Put("image", Image); 59 | } 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/src/json/JsonAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using cn.bmob.io; 3 | using System.Collections.Generic; 4 | using System; 5 | 6 | namespace cn.bmob.json 7 | { 8 | /// 9 | /// 对象与JSON互相转换的接口 10 | /// 11 | /// 用于可以自定义JSON转换的实现: 12 | /// 13 | /// 实现IJsonParser 14 | /// 调用JSONAdapter.register(parser)进行注册。 15 | /// 16 | /// 17 | /// 18 | public interface IJsonParser 19 | { 20 | string ToRawString(object data); 21 | 22 | /// 23 | /// 用于打印调试用!结合writable接口的write第二个参数一起使用 24 | /// 25 | /// 26 | /// 27 | string ToDebugJsonString(object data); 28 | 29 | T ToObject(string json); 30 | 31 | /// 32 | /// 把对象转换为JSON字符串. 33 | /// ATTENTION: 只能处理基本的类型,Writable/IDictionary/IList/string/Numeric/Boolean/null 34 | /// 35 | /// 需序列化的对象. 36 | /// JSON字符串. 37 | /*internal*/ 38 | string ToJsonString(object data); 39 | 40 | /// 41 | /// IDictionary | IList | primitive 42 | /// 43 | /// 44 | /// 45 | /*internal*/ 46 | Object ToObject(string json); 47 | 48 | } 49 | 50 | /// 51 | /// 对象和JSON转换的适配器 52 | /// 53 | public class JsonAdapter 54 | { 55 | static JsonAdapter() 56 | { 57 | // Default JSON Parser 58 | //JSON = new NewtonsoftJsonParser(); 59 | JSON = new SimpleJsonParser(); 60 | } 61 | 62 | /// 63 | /// 注册的JsonParser对象 64 | /// 65 | public static IJsonParser JSON 66 | { 67 | get; 68 | internal set; 69 | } 70 | 71 | /// 72 | /// 注册自定义的JsonParser 73 | /// 实现IJsonParser,然后调用该方法。即可以实现自己的JSON序列化的功能。 74 | /// 75 | /// parser 76 | internal static void register(IJsonParser parser) 77 | { 78 | JsonAdapter.JSON = parser; 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /core/src/json/SimpleJsonParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using cn.bmob.io; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using cn.bmob.tools; 7 | using cn.bmob.exception; 8 | using SimpleJson; 9 | 10 | namespace cn.bmob.json 11 | { 12 | internal class SimpleJsonParser : IJsonParser 13 | { 14 | #region 注册自定义的IBmobOject/IBmobValue序列化 15 | 16 | public class BmobWritableConverter : PocoJsonSerializerStrategy, IJsonSerializerStrategy 17 | { 18 | private Boolean isPrint = false; 19 | 20 | public BmobWritableConverter() { } 21 | public BmobWritableConverter(Boolean isPrint) { 22 | this.isPrint = isPrint; 23 | } 24 | 25 | // obj to IDictionary 26 | public override bool TrySerializeNonPrimitiveObject(object input, out object output) 27 | { 28 | try 29 | { 30 | Type objectType = input.GetType(); 31 | 32 | if (/*typeof(IBmobWritable).IsAssignableFrom(objectType)*/ input is IBmobWritable ) 33 | { 34 | IBmobWritable obj = (IBmobWritable)input; 35 | BmobOutput tOutput = new BmobOutput(); 36 | obj.write(tOutput, isPrint); 37 | 38 | output = tOutput.getData(); 39 | return true; 40 | } 41 | else if (objectType == typeof(BmobInt) || 42 | objectType == typeof(BmobLong) || 43 | objectType == typeof(BmobDouble) || 44 | objectType == typeof(BmobBoolean) || 45 | objectType == typeof(BmobACL)) 46 | { 47 | 48 | object value = 0; 49 | if (input is BmobInt) 50 | value = (input as BmobInt).Get(); 51 | else if (input is BmobLong) 52 | value = (input as BmobLong).Get(); 53 | else if (input is BmobDouble) 54 | value = (input as BmobDouble).Get(); 55 | else if (input is BmobBoolean) 56 | value = (input as BmobBoolean).Get(); 57 | else if (input is BmobACL) 58 | value = (input as BmobACL).Get(); 59 | 60 | output = value; 61 | return true; 62 | } 63 | 64 | } 65 | catch (Exception e) 66 | { 67 | BmobDebug.Log(e); 68 | } 69 | 70 | return base.TrySerializeNonPrimitiveObject(input, out output); 71 | } 72 | 73 | // IDictionary/List/primitive to obj 74 | public override object DeserializeObject(object value, Type type) 75 | { 76 | throw new NotSupportedException("在BmobInput中处理!!!"); 77 | } 78 | 79 | } 80 | 81 | #endregion 82 | 83 | /// 84 | /// 使用反射进行序列化 85 | /// 86 | public String ToRawString(object data) 87 | { 88 | return SimpleJson.SimpleJson.SerializeObject(data); 89 | } 90 | 91 | public String ToDebugJsonString(object data) 92 | { 93 | return SimpleJson.SimpleJson.SerializeObject(data, new BmobWritableConverter(true)); 94 | } 95 | 96 | /// 97 | /// 使用反射进行反序列化 98 | /// 99 | public T ToObject(String json) 100 | { 101 | return SimpleJson.SimpleJson.DeserializeObject(json); 102 | } 103 | 104 | public String ToJsonString(object data) 105 | { 106 | return SimpleJson.SimpleJson.SerializeObject(data, new BmobWritableConverter()); 107 | } 108 | 109 | // 先转成Dictionary(解析为基础类型)然后在进行处理。 110 | public Object ToObject(String json) 111 | { 112 | return SimpleJson.SimpleJson.DeserializeObject(json); 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /core/src/response/BmobResponseParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using cn.bmob.json; 4 | using cn.bmob.io; 5 | using System.Collections; 6 | using cn.bmob.exception; 7 | using cn.bmob.Extensions; 8 | using cn.bmob.tools; 9 | 10 | namespace cn.bmob.response 11 | { 12 | internal class BmobResponseParser 13 | { 14 | private Status result; 15 | 16 | public BmobResponseParser(Status status) 17 | { 18 | this.result = status; 19 | } 20 | 21 | protected static BmobException newPaserException(String json) 22 | { 23 | return new BmobException("请求失败!错误信息为: " + json); 24 | } 25 | 26 | public virtual void parse(String json) 27 | { 28 | 29 | if (!result.ok()) 30 | { 31 | // RestAPI 如果不是200,说明返回内容有“错误”,此时解析内容 32 | var raw = (IDictionary)JsonAdapter.JSON.ToObject(json); 33 | var status = BmobInput.Parse(raw); 34 | 35 | this.exception = new BmobException(status.code == null ? result : status); 36 | this.data = default(T); 37 | } 38 | else 39 | { 40 | var type = typeof(T); 41 | if (type.IsArray || typeof(IList).IsAssignableFrom(type)) 42 | { 43 | // batch or ... 44 | var raw = (IList)JsonAdapter.JSON.ToObject(json); 45 | this.data = BmobInput.Parse(raw); 46 | } 47 | else 48 | { 49 | // 解析[CRUD]的返回值对象 50 | var raw = (IDictionary)JsonAdapter.JSON.ToObject(json); 51 | this.data = BmobInput.Parse(raw); 52 | } 53 | } 54 | 55 | } 56 | 57 | /// 58 | /// 对应返回Json字符串的data节点数据对象 59 | /// 60 | public T data { get; set; } 61 | 62 | public BmobException exception { get; set; } 63 | } 64 | 65 | 66 | internal class UploadReponseParser : BmobResponseParser 67 | { 68 | 69 | public UploadReponseParser(Status status) : base(status) { } 70 | 71 | private static object get(IDictionary parent, String name) 72 | { 73 | return parent.ContainsKey(name) ? parent[name] : null; 74 | } 75 | 76 | 77 | public override void parse(String json) 78 | { 79 | // 文件上传返回值 80 | var raw = (IDictionary)JsonAdapter.JSON.ToObject(json); 81 | 82 | var firstR = get(raw, "r"); 83 | if (firstR == null) 84 | { 85 | throw newPaserException(json); 86 | } 87 | 88 | bool isok = firstR is IDictionary; 89 | 90 | object secondR = null; 91 | if (isok) 92 | secondR = get(firstR as IDictionary, "r"); 93 | 94 | if (secondR == null || !(secondR is IDictionary || secondR is IDictionary)) 95 | { 96 | this.exception = new BmobException("文件上传失败!"); 97 | this.data = default(T); 98 | } 99 | else 100 | { 101 | this.data = BmobInput.Parse(secondR as IDictionary); 102 | } 103 | 104 | } 105 | 106 | } 107 | 108 | 109 | 110 | } 111 | -------------------------------------------------------------------------------- /core/src/response/Create.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using cn.bmob.io; 6 | 7 | namespace cn.bmob.response 8 | { 9 | /// 10 | /// 添加数据的回调类,创建成功,返回objectId和createAt信息 11 | /// 12 | public class CreateCallbackData : BmobObject, IBmobWritable 13 | { 14 | /// 15 | /// 创建时间 16 | /// 17 | public string createdAt { get; set; } 18 | 19 | /// 20 | /// objectId 21 | /// 22 | public string objectId { get; set; } 23 | 24 | public override void readFields(BmobInput input) 25 | { 26 | this.createdAt = input.getString("createdAt"); 27 | this.objectId = input.getString("objectId"); 28 | } 29 | 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | public override void write(BmobOutput output, Boolean all) 36 | { 37 | output.Put("createdAt", this.createdAt); 38 | output.Put("objectId", this.objectId); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /core/src/response/Delete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using cn.bmob.io; 5 | 6 | namespace cn.bmob.response 7 | { 8 | /// 9 | /// 删除数据的回调 10 | /// 11 | public class DeleteCallbackData : BmobObject, IBmobWritable 12 | { 13 | /// 14 | /// 返回信息 15 | /// 16 | public string msg { get; set; } 17 | 18 | public override void readFields(BmobInput input) 19 | { 20 | this.msg = input.getString("msg"); 21 | } 22 | 23 | public override void write(BmobOutput output, Boolean all) 24 | { 25 | output.Put("msg", this.msg); 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/response/Empty.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.io; 2 | 3 | namespace cn.bmob.response 4 | { 5 | /// 6 | /// 没有具体内容的返回值 7 | /// 8 | public class EmptyCallbackData : BmobObject, IBmobWritable 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /core/src/response/EndPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using cn.bmob.io; 5 | using System.Collections; 6 | using cn.bmob.exception; 7 | using cn.bmob.json; 8 | using cn.bmob.Extensions; 9 | 10 | namespace cn.bmob.response 11 | { 12 | 13 | /// 14 | /// 云端代码的执行回调 15 | /// 16 | public class EndPointCallbackData : BmobObject, IBmobWritable 17 | { 18 | public BmobException exception { get; set; } 19 | public U data { get; set; } 20 | 21 | public override void readFields(BmobInput input) 22 | { 23 | 24 | // EndPoint直接返回数据,不像Table返回值有Container的概念! 25 | var type = typeof(U); 26 | 27 | // 请求正确,返回数据 28 | Object jsonData = null; 29 | // 请求失败(如,云端方法不存在), 异常状态 30 | Object statData = null; 31 | 32 | var rawResp = input.getString("result"); 33 | if (typeof(IList).IsAssignableFrom(type)) 34 | { 35 | this.data = BmobInput.Parse(JsonAdapter.JSON.ToObject(rawResp)); 36 | } 37 | else 38 | { 39 | var rawRespJson = JsonAdapter.JSON.ToObject(rawResp); 40 | jsonData = rawRespJson; 41 | statData = rawRespJson; 42 | 43 | if (statData is IDictionary || statData is IDictionary) 44 | { 45 | // 要么返回数据,要么就是返回状态值 46 | EndPointCallbackStat status = BmobInput.Parse(statData); 47 | if (status != null && status.sucess != null) 48 | { 49 | this.exception = new BmobException("请求失败!错误信息为: " + status.message); 50 | this.data = default(U); 51 | return; 52 | } 53 | } 54 | 55 | this.data = BmobInput.Parse(rawRespJson); 56 | } 57 | 58 | } 59 | 60 | public override void write(BmobOutput output, bool all) 61 | { 62 | output.Put("result", this.data); 63 | } 64 | } 65 | 66 | /// 67 | /// 云端代码的执行回调 68 | /// 69 | public class EndPointCallbackStat : BmobObject, IBmobWritable 70 | { 71 | 72 | /// 73 | /// 执行结果 74 | /// 75 | public BmobBoolean sucess { get; set; } 76 | 77 | /// 78 | /// 返回信息 79 | /// 80 | public String message 81 | { 82 | get; 83 | set; 84 | } 85 | 86 | public override void readFields(BmobInput input) 87 | { 88 | if (!input.Contains("sucess")) 89 | { 90 | return; 91 | } 92 | 93 | this.message = input.getString("message"); 94 | this.sucess = input.getBoolean("sucess"); 95 | 96 | // // 2014-5-26 13:42:38 返回值 97 | //{ 98 | // "code": 101, 99 | // "error": "object not found for StudentScore." 100 | //} 101 | if (this.message == null) 102 | { 103 | this.message = input.getString("error") + "(" + input.getInt("code") + ")"; 104 | this.sucess = false; 105 | } 106 | 107 | } 108 | 109 | public override void write(BmobOutput output, bool all) 110 | { 111 | output.Put("message", this.message); 112 | output.Put("success", this.sucess); 113 | } 114 | 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /core/src/response/Query.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using cn.bmob.io; 3 | 4 | namespace cn.bmob.response 5 | { 6 | /// 7 | /// 获取数据列表的回调类 8 | /// 9 | /// 用户模型对象 10 | public class QueryCallbackData : BmobObject, IBmobWritable 11 | { 12 | /// 13 | /// 返回结果列表 14 | /// 15 | public List results { get; set; } 16 | 17 | /// 18 | /// 请求数据总数,返回查询结果总数 19 | /// 20 | public BmobInt count { get; set; } 21 | 22 | public override void readFields(BmobInput input) 23 | { 24 | this.count = input.getInt("count"); 25 | this.results = input.getList("results"); 26 | } 27 | 28 | public override void write(BmobOutput output, bool all) 29 | { 30 | output.Put("count", this.count); 31 | output.Put("results", this.results); 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /core/src/response/SMS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using cn.bmob.io; 5 | 6 | namespace cn.bmob.response 7 | { 8 | /// 9 | /// SMS数据的回调类 10 | /// 11 | public class RequestSmsCodeCallbackData : BmobObject, IBmobWritable 12 | { 13 | public BmobInt smsId { get; set; } 14 | 15 | public override void readFields(BmobInput input) 16 | { 17 | this.smsId = input.getInt("smsId"); 18 | } 19 | 20 | public override void write(BmobOutput output, bool all) 21 | { 22 | output.Put("smsId", this.smsId); 23 | } 24 | } 25 | 26 | public class VerifySmsCodeCallbackData : BmobObject, IBmobWritable 27 | { 28 | public string msg { get; set; } 29 | 30 | public override void readFields(BmobInput input) 31 | { 32 | this.msg = input.getString("msg"); 33 | } 34 | 35 | public override void write(BmobOutput output, bool all) 36 | { 37 | output.Put("msg", this.msg); 38 | } 39 | } 40 | 41 | public class QuerySmsCallbackData : BmobObject, IBmobWritable 42 | { 43 | public string sms_state { get; set; } 44 | public BmobBoolean verify_state { get; set; } 45 | 46 | public override void readFields(BmobInput input) 47 | { 48 | this.sms_state = input.getString("sms_state"); 49 | this.verify_state = input.getBoolean("verify_state"); 50 | } 51 | 52 | public override void write(BmobOutput output, bool all) 53 | { 54 | output.Put("sms_state", this.sms_state); 55 | output.Put("verify_state", this.verify_state); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /core/src/response/Status.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using cn.bmob.io; 5 | 6 | namespace cn.bmob.response 7 | { 8 | /// 9 | /// 请求返回值的状态节点 10 | /// 11 | public class Status : BmobObject 12 | { 13 | 14 | public Status() { } 15 | 16 | public Status(int code, String message) 17 | { 18 | this.code = code; 19 | this.message = message; 20 | } 21 | 22 | /// 23 | /// 判断返回状态是否为200 24 | /// 25 | /// true为200 26 | public bool ok() 27 | { 28 | return this.code.Get() < 300; 29 | } 30 | 31 | /// 32 | /// 返回值的状态编码 33 | /// 34 | public BmobInt code { get; internal set; } 35 | 36 | /// 37 | /// 返回值的状态信息 38 | /// 39 | public string message { get; internal set; } 40 | 41 | /// 42 | /// 对象对应的字符串 43 | /// 44 | /// 45 | public override string ToString() 46 | { 47 | return this.message + "(" + this.code + ")"; 48 | } 49 | 50 | public override void readFields(BmobInput input) 51 | { 52 | base.readFields(input); 53 | 54 | this.code = input.getInt("code"); 55 | this.message = input.getString("message"); 56 | if (this.message == null) 57 | { 58 | this.message = input.getString("error"); 59 | } 60 | } 61 | 62 | public override void write(BmobOutput output, Boolean all) 63 | { 64 | base.write(output, all); 65 | 66 | output.Put("code", this.code); 67 | output.Put("message", this.message); 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /core/src/response/TimeStamp.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.io; 2 | 3 | namespace cn.bmob.response 4 | { 5 | /// 6 | /// 获取服务器时间戳 7 | /// 8 | public class TimeStampCallbackData : BmobObject, IBmobWritable 9 | { 10 | /// 11 | /// UTC时间秒数,时间戳 12 | /// 13 | public BmobInt timestamp { get; set; } 14 | 15 | public string datetime { get; set; } 16 | 17 | public override void readFields(BmobInput input) 18 | { 19 | this.timestamp = input.getInt("timestamp"); 20 | this.datetime = input.getString("datetime"); 21 | } 22 | 23 | public override void write(BmobOutput output, bool all) 24 | { 25 | output.Put("timestamp", this.timestamp); 26 | output.Put("datetime", this.datetime); 27 | } 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /core/src/response/Update.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using cn.bmob.io; 5 | 6 | namespace cn.bmob.response 7 | { 8 | /// 9 | /// 更新数据的回调类 10 | /// 11 | public class UpdateCallbackData : BmobObject, IBmobWritable 12 | { 13 | /// 14 | /// 数据的更新时间 15 | /// 16 | public String updatedAt { get; set; } 17 | 18 | public override void readFields(BmobInput input) 19 | { 20 | this.updatedAt = input.getString("updatedAt"); 21 | } 22 | 23 | public override void write(BmobOutput output, bool all) 24 | { 25 | output.Put("updateAt", this.updatedAt); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /core/src/response/Upload.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.io; 2 | 3 | namespace cn.bmob.response 4 | { 5 | /// 6 | /// 上传文件的返回数据回调类 7 | /// 8 | public class UploadCallbackData : BmobFile 9 | { 10 | } 11 | 12 | /// 13 | /// 上传文件的返回数据回调类 14 | /// 15 | public class ThumbnailCallbackData : BmobFile 16 | { 17 | /// 18 | /// 内容的base64 19 | /// 20 | public string file { get; set; } 21 | 22 | public override void readFields(BmobInput input) 23 | { 24 | base.readFields(input); 25 | 26 | this.file = input.getString("file"); 27 | } 28 | 29 | public override void write(BmobOutput output, bool all) 30 | { 31 | base.write(output, all); 32 | 33 | output.Put("file", this.file); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /core/src/tools/BmobArrays.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace cn.bmob.tools 6 | { 7 | /// 8 | /// Bmob提供的数组处理类 9 | /// ps:之所以提供这个类,是因为反序列化的数组只支持List 10 | /// 11 | public class BmobArrays 12 | { 13 | /// 14 | /// 将数组转成强类型列表 15 | /// 16 | /// 泛型 17 | /// 数组 18 | /// 列表 19 | public static List wrap(params U[] eles) 20 | { 21 | List result = new List(); 22 | foreach (U t in eles) 23 | { 24 | result.Add(t); 25 | } 26 | return result; 27 | } 28 | 29 | /// 30 | /// 将列表转换为强类型列表 31 | /// 32 | /// 泛型 33 | /// 列表 34 | /// 列表 35 | public static List wrap(IList list) 36 | { 37 | List result = new List(); 38 | foreach (U t in list) 39 | { 40 | result.Add(t); 41 | } 42 | return result; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /core/src/tools/BmobDebug.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.config; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | 7 | /// 8 | /// Bmob工具集 9 | /// 10 | namespace cn.bmob.tools 11 | { 12 | /// 13 | /// 日志公共类 14 | /// 15 | public class BmobDebug 16 | { 17 | private static Action logger = 18 | #if WIN8_1 19 | msg => System.Diagnostics.Debug.WriteLine(msg); 20 | #else 21 | Console.WriteLine; 22 | #endif 23 | 24 | // 对于大数据量的操作,控制日志输出级别非常重要! 25 | public static Level level = Level.WARN; 26 | 27 | public enum Level 28 | { 29 | TRACE, 30 | DEBUG, 31 | INFO, 32 | WARN, 33 | ERROR 34 | } 35 | 36 | /// 37 | /// 注册打印日志的实现方法 38 | /// 39 | /// 打印日志的输出方法 40 | public static void Register(Action l, Level level) 41 | { 42 | BmobDebug.level = level; 43 | logger = l; 44 | 45 | BmobDebug.I("bmob version " + Configuration.BUILD_VERSION + "/" + Configuration.PLATFORM); 46 | } 47 | 48 | public static void Register(Action l) 49 | { 50 | Register(l, Level.DEBUG); 51 | } 52 | 53 | public static Boolean Debug 54 | { 55 | get { return Level.DEBUG >= level; } 56 | } 57 | 58 | public static void Log(object msg) 59 | { 60 | if (Level.INFO >= level) logger(msg); 61 | } 62 | 63 | // TODO 优化下,使用Action的方式,可以优化一些字符串拼接的消耗 64 | public static void T(object msg) 65 | { 66 | if (Level.TRACE >= level) logger("[TRACE] [Bmob] " + msg); 67 | } 68 | 69 | public static void I(object msg) 70 | { 71 | if (Level.INFO >= level) logger("[INFO ] [Bmob] " + msg); 72 | } 73 | 74 | public static void D(object msg) 75 | { 76 | if (Level.DEBUG >= level) logger("[DEBUG] [Bmob] " + msg); 77 | } 78 | 79 | public static void E(object msg) 80 | { 81 | if (Level.WARN >= level) logger("[ERROR] [Bmob] " + msg); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /core/src/tools/Utilities.cs: -------------------------------------------------------------------------------- 1 | using cn.bmob.config; 2 | using cn.bmob.http; 3 | using System; 4 | using System.Collections; 5 | using System.IO; 6 | using System.Reflection; 7 | using System.Text; 8 | using cn.bmob.exception; 9 | 10 | namespace cn.bmob.tools 11 | { 12 | internal class Utilities 13 | { 14 | // 代码格式化 ctrl + k + d 15 | public static String Version() 16 | { 17 | #if WIN8_1 18 | //Assembly.GetName().Version.ToString(); 19 | AssemblyFileVersionAttribute attr = typeof(Utilities).GetTypeInfo().Assembly.GetCustomAttribute(); 20 | return attr.Version; 21 | #else 22 | return Assembly.GetExecutingAssembly().GetName().Version.ToString(); 23 | #endif 24 | } 25 | 26 | public static void CheckNotNull(Object obj, String throwMesg) 27 | { 28 | if (obj == null) 29 | { 30 | throw new BmobException(throwMesg); 31 | } 32 | } 33 | 34 | public static String getNewBaseURL() 35 | { 36 | return Configuration.DATA_URL; 37 | //return Configuration.Url; 38 | } 39 | 40 | public static String getBaseURL() 41 | { 42 | return Configuration.DATA_URL; 43 | //return Configuration.Url; 44 | } 45 | 46 | public static bool Empty(object obj) 47 | { 48 | return obj == null || (obj is String && obj.Equals("")); 49 | } 50 | 51 | /// 52 | /// t为null,则返回mDefault的值。 53 | /// 54 | public static T value(T t, T mDefault) 55 | { 56 | return t == null ? mDefault : t; 57 | } 58 | 59 | /* 60 | public static T Clone(T obj) 61 | { 62 | T ret = default(T); 63 | if (obj != null) 64 | { 65 | XmlSerializer cloner = new XmlSerializer(typeof(T)); 66 | MemoryStream stream = new MemoryStream(); 67 | cloner.Serialize(stream, obj); 68 | stream.Seek(0, SeekOrigin.Begin); 69 | ret = (T)cloner.Deserialize(stream); 70 | } 71 | return ret; 72 | } 73 | * 没有经过使用测试,可能会用到 74 | 75 | 76 | static T DeepClone(T element) 77 | { 78 | using (MemoryStream ms = new MemoryStream(1000)) 79 | { 80 | BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone)); 81 | bf.Serialize(ms, element); 82 | 83 | ms.Seek(0, SeekOrigin.Begin); 84 | 85 | return (T)bf.Deserialize(ms); 86 | } 87 | } 88 | * 89 | * 本地IP地址 90 | using System.Net; 91 | 92 | IPHostEntry ipHost = Dns.Resolve(Dns.GetHostName()); ; 93 | IPAddress ipaddress = ipHost.AddressList[0]; 94 | string ips = ipaddress.ToString(); 95 | 96 | MAC地址 97 | string strMac = ""; 98 | NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); 99 | foreach (NetworkInterface ni in interfaces) 100 | { 101 | if (ni.OperationalStatus == OperationalStatus.Up) 102 | { 103 | strMac += ni.GetPhysicalAddress().ToString() + "|";//MAC地址 104 | } 105 | } 106 | ni.OperationalStatus.ToString();//网络连接状态 107 | 108 | ------解决方案-------------------- 109 | 110 | C# code 111 | 112 | ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled='True' and MACAddress = '" + MACAddress + "'"); 113 | ManagementObjectCollection queryCollection = query.Get(); 114 | foreach (ManagementObject mo in queryCollection) 115 | { 116 | if ((bool)mo["IPEnabled"] == true) 117 | { 118 | if (mo["IPAddress"] != null) 119 | strIP = ((string[])mo["IPAddress"])[0]; 120 | } 121 | else 122 | { 123 | strIP = "0.0.0.0"; 124 | } 125 | } 126 | */ 127 | /// 128 | /// 129 | /// 130 | /// 131 | /// 132 | /// 133 | /// 134 | /// 设备唯一id 135 | /// 平台标识[1-ios,0-android] 136 | /// 137 | internal static String EndPointHead(String appkey, String longitude, String latitude, String packageName, String aid, String platform) 138 | { 139 | return appkey + "-" + longitude + "-" + latitude + "-" + packageName + "-" + aid + "-" + platform; 140 | } 141 | 142 | } 143 | } 144 | --------------------------------------------------------------------------------