1

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

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>
}
4

3 に答える 3

2

タイプ ObjectId のオブジェクトを期待している PageID の文字列値を送信しているようです。

モデル バインディングは、この文字列を取得して ObjectId に変換する方法を知りません。MongoDriver の ObjectId クラスを見ると、非常に複雑であることがわかります。

私たちは mongodb をかなり使用しており、ID には単純に文字列を使用して柔軟性を高めています。ドキュメント Id として ObjectId クラスが必要なユースケースはわかりませんが、必要ない場合があります。

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

  1. ドキュメント ID を文字列などに変更します
  2. ObjectId クラスのカスタム モデル バインダーを作成する

それが役立つことを願っています:)

于 2012-04-11T05:53:32.067 に答える
1

バインディングの作成:

public class 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 class ModelBinderConfig { public static void Register(ModelBinderDictionary バインダー) { バインダー.Add(typeof(ObjectId), new ObjectIdBinder());

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

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

    }
}

}

Global.cs に登録します。

 protected void Application_Start()
            {  

                ModelBinderConfig.Register(ModelBinders.Binders);

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

            }
于 2013-09-09T09:05:20.573 に答える
1

C# クラスの PageID プロパティを Type ObjectId にする必要はないが、MongoDB 側でこの Type を利用したい場合は、ドライバーにクラス定義の変換を任せることができます。

public class PageModel
{

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

}
于 2016-05-11T11:32:00.970 に答える