How to pass ObjectId from MongoDB in MVC.net

后端 未结 5 459
野的像风
野的像风 2020-12-06 11:55

I\'m starting a new project with Mongo, NoRM and MVC .Net.

Before I was using FluentNHibernate so my IDs were integer, now my IDs are ObjectId. So when I have an Edi

相关标签:
5条回答
  • 2020-12-06 12:27

    Did you know you can use the [MongoIdentifier] attribute to make any property act as the unique key?

    I've been solving this issue by borrowing a technique from WordPress by having every entity also be represented by a "url slug" property and decorating that property with [MongoIdentifier].

    So if I had a person named Johnny Walker I'd create a slug of "johnny-walker". You just have to make sure these url slugs stay unique and you get to keep clean urls without ugly object ids.

    0 讨论(0)
  • 2020-12-06 12:35

    I am not familiar with the ObjectId type but you could write a custom model binder that will take care of converting the id route constraint to an instance of ObjectId.

    0 讨论(0)
  • 2020-12-06 12:37

    I Use following

    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);
        }
    }
    

    and

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

    almost forgot, make URLs from ObjectId.ToString()

    0 讨论(0)
  • 2020-12-06 12:44

    For Web API you can add Custom parameter binding ule in 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");
                }
            }
        }
    }
    

    And use it Without any additional attributes in controller:

     [Route("{id}")]
     public IHttpActionResult Get(ObjectId id)
    
    0 讨论(0)
  • 2020-12-06 12:48

    Use a custom model binder like this ... (working against the offical C# MongoDB driver)

    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)));
        }
    }
    
    0 讨论(0)
提交回复
热议问题