ASP.NET MVCはじめました~MongoDBにデータを登録する
概要
前回はデータを一覧表示してみたので、次にMongoDBへデータの登録をしてみます。
登録画面はこんな感じになります(デフォルト)。
環境
- Visual Studio Community 2015
- ASP.NET MVC5
- MongoDB 3.2
データの登録
Insertメソッドにモデルオブジェクトを渡してあげるだけ。簡単ですね。
■UserRepository.cs
public async Task InsertAsync(User document)
{
var collection = GetCollection<User>(Collection);
await collection.InsertOneAsync(document);
}
このサンプルではMongoDBのオブジェクトIDを主キーとしているため、オブジェクトID以外が同値のデータは登録できてしまいます。これはあまり現実的ではないので、名前とメールアドレスの組み合わせで一意となるようにユニークインデックスを張っておきます(名前とメールアドレスの組み合わせも一般的ではないですが)。
シェルよりcreateIndexメソッドにunique:trueと指定することでユニークインデックスが作成できます。
> db.users.createIndex({"name":1,"email":1},{unique:true}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
getIndexesメソッドで作成されたインデックスを確認してみます。_idフィールドを主キーとしている他、名前とメールアドレスのユニークインデックスが確認できます。
この状態で名前とメールアドレスが既に登録されている値を新規で登録しようとすると「duplicate key error」が発生します。これで重複データの登録は防げました。
MVC
コードを一式載せておきます。
Model
名前とメールアドレスの組み合わせでユニークインデックスを張ったので、メールアドレスのフィールドを必須に変更しました。
■User.cs
using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.ComponentModel.DataAnnotations; namespace aspnet_mvc5_mongodb.Models { public class User { [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; } [BsonElement("name")] [Required] public string Name { get; set; } [BsonElement("age")] public int Age { get; set; } [BsonElement("email")] [Required] public string Email { get; set; } [BsonElement("address")] public string Address { get; set; } } }
View
■Create.cshtml
@model aspnet_mvc5_mongodb.Models.User @{ ViewBag.Title = "Create"; } <h2>Create</h2> @{ if (ViewBag.ErrorMsg != null) { <span class="errorMsg">@ViewBag.ErrorMsg</span> } } @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>User</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Age, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
Controller
■UsersController.cs
using aspnet_mvc5_mongodb.Models; using aspnet_mvc5_mongodb.Repositories; using aspnet_mvc5_mongodb.Repositories.Abstractions; using System; using System.Net; using System.Threading.Tasks; using System.Web.Mvc; namespace aspnet_mvc5_mongodb.Controllers { public class UsersController : Controller { private readonly IUserRepository _repository; public UsersController() : this(new UserRepository()) { } public UsersController(IUserRepository repository) { this._repository = repository; } [HttpGet] public ActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Create(User inputModel) { if (inputModel == null) { return HttpNotFound(); } if (ModelState.IsValid) { try { await _repository.InsertAsync(inputModel); return RedirectToAction("Index"); } catch (Exception) { ViewBag.ErrorMsg = "データ登録に失敗しました。"; return View(inputModel); } } return View(inputModel); } ... } }
リポジトリ
■MongoDB.cs
using MongoDB.Driver; using System.Configuration; namespace aspnet_mvc5_mongodb.Repositories { public class MongoDB { protected static IMongoClient _client; protected static IMongoDatabase _database; public MongoDB() { var connectionString = ConfigurationManager.AppSettings["MongoDBConnection"]; var database = ConfigurationManager.AppSettings["Database"]; _client = new MongoClient(connectionString); _database = _client.GetDatabase(database); } public static IMongoCollection<T> GetCollection<T>(string collection) { return _database.GetCollection<T>(collection); } } }
■IUserRepository.cs
using aspnet_mvc5_mongodb.Models; using System.Collections.Generic; using System.Threading.Tasks; namespace aspnet_mvc5_mongodb.Repositories.Abstractions { public interface IUserRepository { Task InsertAsync(User document); ... } }
■UserRepository.cs
using aspnet_mvc5_mongodb.Models; using aspnet_mvc5_mongodb.Repositories.Abstractions; using MongoDB.Driver; using System.Collections.Generic; using System.Threading.Tasks; namespace aspnet_mvc5_mongodb.Repositories { public class UserRepository : MongoDB, IUserRepository { private static readonly string Collection = "users"; public async Task InsertAsync(User document) { var collection = GetCollection<User>(Collection); await collection.InsertOneAsync(document); } ... } }
実行
/Users/Createにアクセス。
次回は画面からデータの編集です☆彡
参考
https://docs.mongodb.com/getting-started/csharp/insert/
https://docs.mongodb.com/manual/core/index-unique/
- 作者: Kyle Banker,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/12/14
- メディア: 大型本
- 購入: 5人 クリック: 55回
- この商品を含むブログ (8件) を見る