ModelState.IsValid содержит ошибки при использовании MongoDB

Я пытаюсь создать базовую базу данных фильмов с использованием ASP.NET MVC 4 и MongoDB. Моя проблема в методе POST Update моего MovieController.

[HttpPost]
    public ActionResult Update(Movie movie)
    {
        if (ModelState.IsValid)
        {

            _movies.Edit(movie);

            return RedirectToAction("Index");
        }

        return View();
    }

ModelState содержит ошибку для поля Id фильма (которое является объектом ObjectId) и выдает следующее исключение:

 {System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'MongoDB.Bson.ObjectId' failed because no type converter can convert between these types

Это вид обновления:

@model MVCMovie.Models.Movie

@{
    ViewBag.Title = "Update";
}

<h2>Update</h2>

@using (Html.BeginForm())
{
    @Html.HiddenFor(m => m.Id);
    @Html.EditorForModel()

    <p>
        <input type="submit" value="Update" />
    </p>
}

И класс Кино в Моделях:

namespace MVCMovie.Models
{
    public class Movie
    {
        [BsonId]
        public ObjectId Id { get; set; }

        public string Title { get; set; }

        public DateTime ReleaseDate { get; set; }

        public string Genre { get; set; }

        public decimal Price { get; set; }

        [ScaffoldColumn(false)]
        public DateTime TimeAdded { get; set; }
    }
}

РЕДАКТИРОВАТЬ: Решение Я добавил [ScaffoldColumn(false)] к идентификатору, чтобы браузер не пытался его визуализировать. Однако мне все еще нужно было реализовать решение, предоставленное Михаем, чтобы передать правильный идентификатор.

Я предполагаю, что проблема вызывается в представлении, потому что он пытается отправить строку вместо объекта ObjectId. Но я не могу понять, как это исправить, есть идеи?

3 ответа

Решение

Проблема в том, что MVC не знает, как преобразовать ваш Id в тип ObjectId. Он видит это только как строку.

Вам придется использовать пользовательское связующее для вашего метода. Посмотрите по этой ссылке http://www.dotnetcurry.com/ShowArticle.aspx?ID=584

Посмотри на это

public class MovieModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var modelBinder = new DefaultModelBinder();
        var movie = modelBinder.BindModel(controllerContext, bindingContext) as Movie;
        var id = controllerContext.HttpContext.Request.Form["Id"];
        if (movie != null)
        {
            movie.Id = new ObjectId(id);
            return movie ;
        }

        return null;
    }
}

И измените свой метод обновления как

public ActionResult Update([ModelBinder(typeof(MovieModelBinder))] Movie movie)

Для тех, кто ищет этот ответ, из этого поста, и он отлично работает: http://www.joe-stevens.com/2011/06/12/model-binding-mongodb-objectid-with-asp-net-mvc/

Создайте подшивку модели:

public class ObjectIdBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        return new ObjectId(result.AttemptedValue);
    }
}

Затем зарегистрируйтесь в запуске приложения:

protected void Application_Start()
{
    ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdBinder());
}

Кажется, вам нужно написать собственный конвертер типов.
Проверьте это обсуждение: ObjectId Type Converter

Другие вопросы по тегам