Как передать ObjectId из MongoDB в MVC.net - PullRequest
9 голосов
/ 29 июня 2010

Я начинаю новый проект с Mongo, NoRM и MVC .Net.

До того, как я использовал FluentNHibernate, мои идентификаторы были целыми числами, теперь мои идентификаторы - ObjectId. Поэтому, когда у меня есть ссылка «Изменить», мой URL выглядит следующим образом:

WebSite / Admin / Edit / 23,111,160,3,240,200,191,56,25,0,0,0

И он не привязывается автоматически к моему контроллеру как ObjectId

Есть ли у вас какие-либо предложения / лучшие практики для работы с этим? Нужно ли мне каждый раз кодировать / декодировать идентификатор?

Спасибо!

Ответы [ 5 ]

15 голосов
/ 04 декабря 2010

Используйте привязку пользовательской модели, как это ... (работает с официальным драйвером C # MongoDB)

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

public class ObjectIdModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (result == null)
        {
            return ObjectId.Empty;
        }
        return ObjectId.Parse((string)result.ConvertTo(typeof(string)));
    }
}
14 голосов
/ 15 июля 2010

Использую следующее

public class ObjectIdModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        string value = controllerContext.RouteData.Values[bindingContext.ModelName] as string;
        if (String.IsNullOrEmpty(value)) {
            return ObjectId.Empty;
        }
        return new ObjectId(value);
    }
}

и

protected void Application_Start()
    {
        ......

        ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdModelBinder()); 
    }

почти забыл, сделать URL из ObjectId.ToString()

0 голосов
/ 04 ноября 2017

Для Web API вы можете добавить пользовательский параметр привязки параметров в WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //...
        config.ParameterBindingRules.Insert(0, GetCustomParameterBinding);
        //...
    }

    public static HttpParameterBinding GetCustomParameterBinding(HttpParameterDescriptor descriptor)
    {
        if (descriptor.ParameterType == typeof(ObjectId))
        {
            return new ObjectIdParameterBinding(descriptor);
        }
        // any other types, let the default parameter binding handle
        return null;
    }

    public class ObjectIdParameterBinding : HttpParameterBinding
    {
        public ObjectIdParameterBinding(HttpParameterDescriptor desc)
            : base(desc)
        {
        }

        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            try
            {
                SetValue(actionContext, new ObjectId(actionContext.ControllerContext.RouteData.Values[Descriptor.ParameterName] as string));
                return Task.CompletedTask;
            }
            catch (FormatException)
            {
                throw new BadRequestException("Invalid ObjectId format");
            }
        }
    }
}

и использовать его без каких-либо дополнительных атрибутов в контроллере:

 [Route("{id}")]
 public IHttpActionResult Get(ObjectId id)
0 голосов
/ 29 июня 2010

Знаете ли вы, что вы можете использовать атрибут [MongoIdentifier], чтобы любое свойство выступало в качестве уникального ключа?

Я решал эту проблему, заимствуя технику из WordPress, чтобы каждая сущность также была представлена.с помощью свойства "url slug" и украшения этого свойства с помощью [MongoIdentifier].

Так что, если бы у меня был человек по имени Джонни Уокер, я бы создал слаг "johnny-walker".Вам просто нужно убедиться, что эти URL-слизни остаются уникальными, и вы должны поддерживать чистоту URL-адресов без уродливых идентификаторов объектов.

0 голосов
/ 29 июня 2010

Я не знаком с типом ObjectId, но вы могли бы написать пользовательский связыватель модели , который позаботится о преобразовании ограничения маршрута id в экземпляр ObjectId.

...