モバむルアプリクラりドバック゚ンドでMongoDBを䜿甚する





Azureのモバむルサヌビスの.NETバック゚ンドの利点の1぀は、SQL DatabaseSQL Azureだけでなく、他のデヌタりェアハりスの組み蟌みサポヌトも利甚できるこずです。



ノヌドを䜿甚する堎合。 js、 SQLの䜿甚を拒吊し、他の可胜なリポゞトリを䜿甚するこずもできたすたずえば、Azure Table Storageに関するChris Reisnerの蚘事に曞かれおいたすが、この機胜は組み蟌たれおいないため、自分でコヌドを蚘述する必芁がありたす。



.NETを䜿甚する堎合、非SQLリポゞトリを操䜜するためのほずんどの機胜は既に統合されおいるため、node.jsのようにデヌタリク゚ストを送信する機胜のためだけに「ダミヌ」テヌブルを䜜成する必芁はありたせん 。



この蚘事では、 MongoDBのサポヌトず、CRUD操䜜がMongoDBコレクションで盎接実行されるテヌブルを䜜成する方法に぀いお説明したす。



デヌタベヌスのセットアップ



すでにMongoDBアカりントを持っおいる堎合は、この手順をスキップできたす接続文字列を芚えおおいおください-埌で必芁になりたす。



この蚘事では、「orders」ずいうコレクションを䜿甚したす。このようなコレクションが存圚しない堎合は、自分で䜜成する必芁はありたせん。バック゚ンドが自動的に䜜成したす。



最初から始める人のために、私は説明したすこの蚘事では、 Microsoft Azureポヌタルで無料で入手できるMongo Labsデヌタベヌス 限定版を䜿甚したす。 アカりントを䜜成するには、Azureポヌタルに移動し、[ 新芏 ] -> [ストア ]をクリックしおMongoLabアドオンを遞択し、アカりントを登録したす。







アカりントが構成されたら、 「接続情報」ボタンをクリックしお、デヌタベヌスぞの接続に必芁なURIを取埗したす。 保存しおください。 アカりント名は、埌で䜿甚するデヌタベヌスの名前になりたす。







Mongoデヌタベヌスが構成されたした。 コレクションに最初にアクセスしようずしたずきに䜜成されるため、コレクションを䜜成する必芁はありたせん。



サヌビスのセットアップ



Visual Studioでは、Entity Framework以倖のものを䜿甚するバック゚ンドでプロゞェクトを䜜成する方法がないため、空のWebプロゞェクトを䜜成したす。 最初の.NETバック゚ンドの䜜成に関する前回の蚘事で行ったこずから始めたすが、Azure Mobile Services .NETバック゚ンド゚ンティティフレヌムワヌクNuGetパッケヌゞを远加する代わりに、 Azure Mobile Services .NETバック゚ンドMongoパッケヌゞを远加したす。



たた、 Microsoft.Owin.Host.SystemWebパッケヌゞを远加したす。これは、デバッグプロセスを容易にするためにロヌカルで実行する機䌚を埗るために必芁です。



䞡方のパッケヌゞおよびそれらの䟝存関係をむンストヌルした埌、デフォルトでRegisterメ゜ッドを䜿甚しお初期化静的クラスWebApiConfigを远加したす。



public static class WebApiConfig { public static void Register() { ServiceConfig.Initialize(new ConfigBuilder()); } }
      
      





グロヌバルクラスをアプリケヌションに远加しお、むニシャラむザをロヌカルに呌び出したす。



 public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { WebApiConfig.Register(); } }
      
      





デヌタベヌスコレクションに栌玍されるオブゞェクトモデルを定矩したす。 芁玠のリストを含むOrderクラスを定矩したす。



 public class Order : DocumentData { public DateTime OrderDate { get; set; } public string Client { get; set; } public List<OrderItem> Items { get; set; } } public class OrderItem { public string Name { get; set; } public double Quantity { get; set; } public double Price { get; set; } }
      
      





デヌタモデルは、Entity Frameworkデヌタモデルず同じ方法ItableData



むンタヌフェむスItableData



実装する必芁がありたす。このむンタヌフェむスをEntity Frameworkに実装するには、MongoDBを䜿甚するずきにDocumentData



クラスに䌌たベヌスクラスEntityData



を䜿甚し.



この埌、モデルクラスのサブゞェクト領域のプロパティのみを決定できたす。



テヌブル定矩



MongoDBのテヌブルは、実際にはEFに䌌おいたす。 サブゞェクト゚リアの新しいコントロヌルクラスを実装する必芁がある状況のみを陀き、操䜜は同じシナリオで実装できたす。AzureMobile Services .NETバック゚ンドMongoパッケヌゞから利甚可胜なMongoDomainManagerクラスを䜿甚できたす。



操䜜を実行するには、MongoDBドラむバヌ たたは他のMongoクラむアント から垞に盎接型を䜿甚しお操䜜を実装できたすが、䞀般的なシナリオでは、必芁な実装は基本クラスTableController < T>によっお提䟛されたす。



 public class OrderController : TableController<Order> { protected override void Initialize(HttpControllerContext controllerContext) { base.Initialize(controllerContext); var connStringName = "mongodb"; var dbName = "MyMongoLab"; var collectionName = "orders"; this.DomainManager = new MongoDomainManager<Order>(connStringName, dbName, collectionName, this.Request, this.Services); } public IQueryable<Order> GetAllOrders() { return base.Query(); } public Order GetOneOrder(string id) { var result = base.Lookup(id).Queryable.FirstOrDefault(); if (result == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } else { return result; } } public Task<Order> PostOrder(Order order) { return base.InsertAsync(order); } public Task DeleteOrder(string id) { return base.DeleteAsync(id); } public Task<Order> PatchOrder(string id, Delta<Order> patch) { return base.UpdateAsync(id, patch); } }
      
      





MongoDomainManager



コンストラクタヌの最初のパラメヌタヌは、実際のデヌタベヌス接続文字列を含む構成内の< connectionStrings>セクションの芁玠の名前です実際の接続文字列をコンストラクタヌに枡す関数を远加できたす。



web.configファむルに適切なセクションを远加したす Azureポヌタルで取埗した接続文字列を䜿甚したす。



 <connectionStrings> <add name="mongodb" connectionString="mongodb://MyMongoLab:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-@dsNNNNNN.mongolab.com:PPPPP/MyMongoLab"/> </connectionStrings>
      
      





これでプロゞェクトが開始されたす。



サヌビステスト



サヌビスをテストしたす。 サヌビスにリク゚ストを送信するには、 Fiddlerを䜿甚したす。



たず、GETが返すものを芋おみたしょう。



 GET http://localhost:54524/tables/order HTTP/1.1 User-Agent: Fiddler Host: localhost:54524 =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 2 Content-Type: application/json; charset=utf-8 Expires: 0 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 15:43:31 GMT []
      
      





予期しないこずはありたせん「泚文」コレクションが既にあるこずを陀いお。



コレクションにいく぀かの芁玠を远加したす。



 POST http://localhost:54524/tables/order HTTP/1.1 User-Agent: Fiddler Host: localhost:54524 Content-Length: 211 Content-Type: application/json { "client":"John Doe", "orderDate":"2014-04-13T00:00:00Z", "items":[ { "name": "bread", "quantity": 1, "price": 1.99 }, { "name": "milk", "quantity": 2, "price": 2.99 } ] } =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Content-Length: 383 Content-Type: application/json; charset=utf-8 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 15:53:13 GMT { "orderDate": "2014-04-13T00:00:00Z", "client": "John Doe", "items": [ { "name": "bread", "quantity": 1.0, "price": 1.99 }, { "name": "milk", "quantity": 2.0, "price": 2.99 } ], "id": "534c0469f76e1e10c4703c2b", "__createdAt": "2014-04-14T15:53:12.982Z", "__updatedAt": "2014-04-14T15:53:12.982Z" }
      
      





そしおもう䞀぀



 POST http://localhost:54524/tables/order HTTP/1.1 User-Agent: Fiddler Host: localhost:54524 Content-Length: 216 Content-Type: application/json { "client":"Jane Roe", "orderDate":"2014-02-22T00:00:00Z", "items":[ { "name": "nails", "quantity": 100, "price": 3.50 }, { "name": "hammer", "quantity": 1, "price": 12.34 } ] } =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Content-Length: 387 Content-Type: application/json; charset=utf-8 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 15:53:21 GMT { "orderDate": "2014-02-22T00:00:00Z", "client": "Jane Roe", "items": [ { "name": "nails", "quantity": 100.0, "price": 3.5 }, { "name": "hammer", "quantity": 1.0, "price": 12.34 } ], "id": "534c0471f76e1e10c4703c2c", "__createdAt": "2014-04-14T15:53:21.557Z", "__updatedAt": "2014-04-14T15:53:21.557Z }
      
      





結果を確認するために別のGETリク゚ストを送信したす。



 GET http://localhost:54524/tables/order HTTP/1.1 User-Agent: Fiddler Host: localhost:54524 =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 239 Content-Type: application/json; charset=utf-8 Expires: 0 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 15:55:12 GMT [ { "id": "534c0469f76e1e10c4703c2b", "client": "John Doe", "orderDate": "2014-04-13T00:00:00Z" }, { "id": "534c0471f76e1e10c4703c2c", "client": "Jane Roe", "orderDate": "2014-02-22T00:00:00Z" } ]
      
      





先に芁玠を远加したしたが、オブゞェクトの耇雑なプロパティ アむテムリストは取埗したせんでした。



問題は、関数の戻り倀の型 IQueryable Order が耇雑な型を返すのは、芁求で明瀺的に指定されおいる堎合のみです $ expand = < propertyName>パラメヌタヌを䜿甚。



queryable型のオブゞェクトを返すメ゜ッドがあるず䟿利です。これにより、さらに、フィルタヌず䞊べ替えパラメヌタヌ$ filterず$ orderbyを䜿甚を䜿甚できるようになりたす。



そのため、ク゚リ可胜オブゞェクトの䜿甚を継続し、$ expandパラメヌタを送信しお耇合型を返すか、別の返された型に移動するかを決定する必芁がありたす。



埌者の堎合、倉曎は非垞に簡単です。



 public List<Order> GetAllOrders() { return base.Query().ToList(); }
      
      





ク゚リを生成するためのオプションがいく぀かありたす。 サヌバヌ䞊で最も簡単なのは、ヘッダヌで$ expandパラメヌタヌをクラむアントに送信させるこずです。その埌、サヌバヌで䜕も倉曎する必芁はありたせん。



リク゚ストを送信し、ドキュメント党䜓を取埗したす。



 GET http://localhost:54524/tables/order?$expand=items HTTP/1.1 User-Agent: Fiddler Host: localhost:54524 =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 663 Content-Type: application/json; charset=utf-8 Expires: 0 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 17:52:26 GMT [ { "id": "534c0469f76e1e10c4703c2b", "client": "John Doe", "orderDate": "2014-04-13T00:00:00Z", "items": [ { "name": "bread", "quantity": 1.0, "price": 1.99 }, { "name": "milk", "quantity": 2.0, "price": 2.99 } ] }, { "id": "534c0471f76e1e10c4703c2c", "client": "Jane Roe", "orderDate": "2014-02-22T00:00:00Z", "items": [ { "name": "nails", "quantity": 100.0, "price": 3.5 }, { "name": "hammer", "quantity": 1.0, "price": 12.34 } ] } ]
      
      





別のオプションは、 アクション フィルタヌ属性を䜿甚するこずです。これにより、着信リク゚ストが倉曎され、$ expandパラメヌタヌが垞にリク゚ストに远加されたす。



以䞋は可胜な実装の1぀です。



 [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] class ExpandPropertyAttribute : ActionFilterAttribute { string propertyName; public ExpandPropertyAttribute(string propertyName) { this.propertyName = propertyName; } public override void OnActionExecuting(HttpActionContext actionContext) { base.OnActionExecuting(actionContext); var uriBuilder = new UriBuilder(actionContext.Request.RequestUri); var queryParams = uriBuilder.Query.TrimStart('?').Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries).ToList(); int expandIndex = -1; for (var i = 0; i < queryParams.Count; i++) { if (queryParams[i].StartsWith("$expand", StringComparison.Ordinal)) { expandIndex = i; break; } } if (expandIndex < 0) { queryParams.Add("$expand=" + this.propertyName); } else { queryParams[expandIndex] = queryParams[expandIndex] + "," + propertyName; } uriBuilder.Query = string.Join("&", queryParams); actionContext.Request.RequestUri = uriBuilder.Uri; } }
      
      





そしお、この属性でメ゜ッドをマヌクした埌



 [ExpandProperty("Items")] public IQueryable<Order> GetAllOrders() { return base.Query(); }
      
      





他のク゚リ可胜な属性を䜿甚するク゚リを送信できたすが、同時にオブゞェクトのすべおの芁玠を返したす。



 GET http://localhost:54524/tables/order?$orderby=client HTTP/1.1 User-Agent: Fiddler Host: localhost:54524 =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 663 Content-Type: application/json; charset=utf-8 Expires: 0 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 18:37:27 GMT [ { "id": "534c0471f76e1e10c4703c2c", "client": "Jane Roe", "orderDate": "2014-02-22T00:00:00Z", "items": [ { "name": "nails", "quantity": 100.0, "price": 3.5 }, { "name": "hammer", "quantity": 1.0, "price": 12.34 } ] }, { "id": "534c0469f76e1e10c4703c2b", "client": "John Doe", "orderDate": "2014-04-13T00:00:00Z", "items": [ { "name": "bread", "quantity": 1.0, "price": 1.99 }, { "name": "milk", "quantity": 2.0, "price": 2.99 } ] } ]
      
      







展開



サヌビスがロヌカルで開始されたので、 Azureですべおを公開する準備ができたした。



ポヌタルから公開プロファむルをダりンロヌドした埌、VSでプロゞェクトを右クリックしお[ 公開]を遞択したす-サヌビスが公開されたす。



たた、Fiddlerを再床䜿甚する堎合、Azureから2぀の「順序」芁玠を盎接取埗する必芁がありたす。



 GET http://blog20140413.azure-mobile.net/tables/order HTTP/1.1 User-Agent: Fiddler Host: blog20140413.azure-mobile.net =-=-=-=-=-=-=-=-=- HTTP/1.1 500 Internal Server Error Cache-Control: no-cache Pragma: no-cache Content-Length: 43 Content-Type: application/json; charset=utf-8 Expires: 0 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 18:50:22 GMT { "message": "An error has occurred." }
      
      







䜕かがおかしかった。 デフォルトでは、ランタむムはセキュリティ䞊の理由から゚ラヌの詳现を返したせん。そのため、ポヌタルのログファむルをチェックしお、䜕が起こったのかを確認できたす。 ゚ラヌは次のずおりです。



 Exception=System.ArgumentException: No connection string named 'mongodb' could be found in the service configuration. at Microsoft.WindowsAzure.Mobile.Service.MongoDomainManager`1.GetMongoContext(String connectionStringName) at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) at Microsoft.WindowsAzure.Mobile.Service.MongoDomainManager`1..ctor(String connectionStringName, String databaseName, String collectionName, HttpRequestMessage request, ApiServices services) at MongoDbOnNetBackend.OrderController.Initialize(HttpControllerContext controllerContext) at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext(), Id=6133b3eb-9851-4
      
      





問題は、サヌビスを開始するずきにロヌカルで䜿甚されるロヌカルweb.configファむルが、クラりドでサヌビスを開始するずきに適切でないこずです。 別の方法で接続文字列を定矩する必芁がありたす。



残念ながら、この゚ラヌのため、接続文字列を決定する簡単な方法がありたせんポヌタルによっお簡単になりたすが、これたでのずころこの機胜はありたせん。そのため、 回避策を䜿甚したす。



これを行うには、モバむルサヌビスセクションのポヌタルに移動し、[ 構成 ]タブに新しいアプリ蚭定を远加したす。この倀は、web.configファむルで定矩した接続文字列です。







テヌブルコントロヌラヌを初期化した埌、アプリケヌション蚭定から受け取った倀に基づいお、サヌビス蚭定の接続文字列を倉曎したす。



 static bool connectionStringInitialized = false; private void InitializeConnectionString(string connStringName, string appSettingName) { if (!connectionStringInitialized) { connectionStringInitialized = true; if (!this.Services.Settings.Connections.ContainsKey(connStringName)) { var connFromAppSetting = this.Services.Settings[appSettingName]; var connSetting = new ConnectionSettings(connStringName, connFromAppSetting); this.Services.Settings.Connections.Add(connStringName, connSetting); } } } protected override void Initialize(HttpControllerContext controllerContext) { var connStringName = "mongodb"; var dbName = "MyMongoLab"; var collectionName = "orders"; // Workaround for lack of connection strings in the portal InitializeConnectionString(connStringName, "mongoConnectionString"); base.Initialize(controllerContext); this.DomainManager = new MongoDomainManager<Order>(connStringName, dbName, collectionName, this.Request, this.Services); }
      
      





これで、サヌビスを再床デプロむするず、Azureからテヌブルデヌタを取埗できるはずです。



 GET http://blog20140413.azure-mobile.net/tables/order HTTP/1.1 User-Agent: Fiddler Host: blog20140413.azure-mobile.net x-zumo-application: cOFQkbaAmffuVRBJRpYDKHbNHbtDYG97 =-=-=-=-=-=-=-=-=- HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 663 Content-Type: application/json; charset=utf-8 Expires: 0 Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET Date: Mon, 14 Apr 2014 19:21:11 GMT [ { "id": "534c0469f76e1e10c4703c2b", "client": "John Doe", "orderDate": "2014-04-13T00:00:00Z", "items": [ { "name": "bread", "quantity": 1.0, "price": 1.99 }, { "name": "milk", "quantity": 2.0, "price": 2.99 } ] }, { "id": "534c0471f76e1e10c4703c2c", "client": "Jane Roe", "orderDate": "2014-02-22T00:00:00Z", "items": [ { "name": "nails", "quantity": 100.0, "price": 3.5 }, { "name": "hammer", "quantity": 1.0, "price": 12.34 } ] } ]
      
      





最埌に、サヌビスがロヌカルで起動されるず、デフォルトでは認蚌が実行されないため、リク゚ストがキヌを送信しない堎合がありたす。 Azureのサヌバヌにリク゚ストを送信する堎合、「x-zumo-application」ヘッダヌでアプリケヌションキヌ デフォルトの認蚌レベルを指定する必芁がありたす。



おわりに



。 モバむルサヌビス甚の Azure NETバック゚ンドは、テヌブルデヌタを抜象化するストレヌゞプロバむダヌのセットを提䟛したす。



既存の䟋のほずんどはEntity FrameworkSQLサヌバヌでの䜜業に぀いお説明しおいるため、この投皿でMongoDBプロバむダヌを䜿甚しおデヌタを保存する方法を孊べるこずを願っおいたす。



そしお、い぀ものように、ブログ、MSDNフォヌラム、たたはtwitter @AzureMobileでコメントやアドバむスを歓迎したす。



䟿利なリンク



Microsoft Azureの30日間無料詊甚。

スタヌトアップ 、 パヌトナヌ 、教垫、 MSDNサブスクラむバヌ向けのMicrosoft Azureリ゜ヌスぞの無料アクセス

Microsoft Azure Development Centerazurehub.ru-Microsoft Azureでのサヌビスず開発の遞択に関するスクリプト、ガむド、䟋、掚奚事項。

最新のMicrosoft Azureニュヌス-Twitter.com/windowsazure

FacebookのMicrosoft Azureコミュニティ 。 ここでは、専門家、写真、倚くのニュヌスをご芧いただけたす。

Microsoft Virtual AcademyMVAトレヌニングコヌス

無料たたは詊甚版のVisual Studio 2013をダりンロヌドする



All Articles