2012-04-11 10 views
0

MongoDB csharp公式ライブラリを使用して値を返すモデルのObjectIdを取得できません。コントローラーに返信するフォームを送信すると、PageIDは常にモデルの{000000000000000000000000}に戻ります。レンダリングされたHTMLには有効なIDがあり、1つのフィールドがフォームの投稿から正しく返ってこないことがあります。MongoDB:投稿時にBsonIdをシリアル化していないMVC

HTMLはレンダリング:<input id="PageID" name="PageID" type="hidden" value="4f83b5ccd79f660b881887a3" />

これは私が持っているものです。

モデル:

public class PageModel 
    { 
     public PageModel() 
     { 
      CanEdit = false; 
      CancelRequest = false; 
     } 

     [BsonId] 
     public ObjectId PageID { get; set; } 

     [Display(Name = "Page URL")] 
     public string PageURL { get; set; } 

     [AllowHtml] 
     [Display(Name = "Content")] 
     public string Value { get; set; } 

     [Display(Name = "Last Modified")] 
     public DateTime LastModified { get; set; } 

     [BsonIgnore] 
     public bool CancelRequest { get; set; } 
     [BsonIgnore] 
     public bool CanEdit { get; set; } 

    } 

コントローラーポスト:

[HttpPost] 
     public ActionResult Edit(PageModel model) 
     { 
      // check to see if the user canceled 
      if (model.CancelRequest) 
      { 
       return Redirect(model.PageURL); 
      } 

      // check for a script tag to prevent 
      if (!model.Value.Contains("<script")) 
      { 
       // save to the database 
       model.LastModified = DateTime.Now; 
       collection.Save(model); 

       // return to the page 
       return Redirect(model.PageURL); 
      } 
      else 
      { 
       ModelState.AddModelError("Value", "Disclosures discovered a script in the html you submitted, please remove the script before saving."); 
      } 

      return View(model); 
     } 

ビュー:

@model LeulyHome.Models.PageModel 

@{ 
    ViewBag.Title = ""; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

@using (Html.BeginForm()) 
{ 
    <fieldset> 
     <legend>Edit Page</legend> 
     <div class="control-group"> 
      @Html.LabelFor(m => m.PageURL, new { @class = "control-label" }) 
      <div class="controls"> 
       @Html.TextBoxFor(m => m.PageURL, new { @class = "input-xlarge leu-required span9" }) 
       @Html.ValidationMessageFor(m => m.PageURL, null, new { @class = "help-block" }) 
      </div> 
     </div> 
     <div class="control-group"> 
      @Html.LabelFor(m => m.Value, new { @class = "control-label" }) 
      <div class="controls"> 
       @Html.TextAreaFor(m => m.Value) 
       @Html.ValidationMessageFor(m => m.Value, null, new { @class = "help-block" }) 
      </div> 
     </div> 
     <div class="control-group"> 
      @Html.LabelFor(m => m.LastModified, new { @class = "control-label" }) 
      <div class="controls"> 
       @Html.DisplayFor(m => m.LastModified) 
       @Html.HiddenFor(m => m.LastModified) 
      </div> 
     </div> 

     @Html.HiddenFor(m => m.PageID) 
     @Html.HiddenFor(m => m.CancelRequest) 

     <div class="form-actions"> 
      <button type="submit" class="btn btn-primary">Save Page</button> 
      <button type="button" class="btn btn-danger" id="cancelBtn">Cancel Changes</button> 
     </div> 
    </fieldset> 
} 

@section Footer { 
    <script type="text/javascript" src="@Url.Content("~/Content/ckeditor/ckeditor.js")"></script> 
    <script language="javascript" type="text/javascript"> 
     $(document).ready(function() { 
      // adjust the editor's toolbar 
      CKEDITOR.replace('Value', { 
       toolbar: [["Bold", "Italic", "Underline", "-", "NumberedList", "BulletedList", "-", "Link", "Unlink"], 
        ["JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock"], 
        ["Cut", "Copy", "Paste", "PasteText", "PasteFromWord", "-", "Print", "SpellChecker", "Scayt"], ["Source", "About"]] 
      }); 

      $("#cancelBtn").click(function() { 
       $("#CancelRequest").val("True"); 
       $("#updateBtn").click(); 
      }); 
     }); 
    </script> 
} 

答えて

2

あなたがのオブジェクトを期待しているPAGEIDの文字列値を送信しているように見えますObjectIdを入力します。

モデルバインディングでは、この文字列を取得してObjectIdに変換する方法はわかりません。 MongoDriverのObjectIdクラスを見れば、それはかなり毛深いことがわかります。

私たちはmongodbをかなり使いました。私たちのIDのために、私たちは単に多くの柔軟性を提供する文字列を使います。 ObjectIdクラスがドキュメントIDとして必要なユースケースはわかりませんが、必要はないかもしれません。

ここからは、2つのオプションがあるようです。

公共:役立ちます:)

+0

ありがとうございました。私はMVCでシーズンされていますが、MongoDBは初めてです。あなたの2番目のオプションは、実際には私に十分な情報を与えてくれました。私はモデルバインダーを作成してこれを世話してくれました。ここに例があります。 http://www.joe-stevens.com/2011/06/12/model-binding-mongodb-objectid-with-asp-net-mvc/ – uadrive

1

    が を文字列にドキュメントIDを変更するか、他の何か
  1. のObjectIdクラス用のカスタムモデルバインダーを書く

希望はバインディングを作成します。クラスObjectIdBinder:IModelBinder {

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
{ 
    var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
    return !string.IsNullOrWhiteSpace(result.AttemptedValue) ? ObjectId.Parse(result.AttemptedValue) : ObjectId.Empty; 
} 

}

ModelBinderConfig作成:

名前空間Nasa8x.CMS {publicクラスModelBinderConfig {公共静的ボイドレジスタ(ModelBinderDictionaryバインダー) {binder.Add(typeof演算(たObjectId)を、新しいObjectIdBinder());

 binder.Add(typeof(string[]), new StringArrayBinder()); 

     binder.Add(typeof(int[]), new IntArrayBinder()); 

    } 
} 

}グローバルに

登録します。CS:あなたはタイプのObjectIdであることが、あなたのC#クラスにPAGEIDプロパティが必要ですが、MongoDBの側にこのタイプを利用したくない場合は

protected void Application_Start() 
      { 

       ModelBinderConfig.Register(ModelBinders.Binders); 

       WebApiConfig.Register(GlobalConfiguration.Configuration); 
       FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
       RouteConfig.RegisterRoutes(RouteTable.Routes);  

      } 
0

、あなたはドライバーの世話をさせることができますあなたのクラスの変換 - 定義:

public class PageModel 
{ 

    [BsonId] 
    [BsonRepresentation(BsonType.ObjectId)] 
    public string PageID { get; set; } 

} 
関連する問題