如何在MVC.net中从MongoDB传递ObjectId

时间:2010-06-29 17:36:46

标签: asp.net-mvc mongodb norm

我正在与Mongo,NoRM和MVC .Net开始一个新项目。

在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。因此,当我有一个编辑链接时,我的URL看起来像这样:

网站/管理员/编辑/ 23,111,160,3,240,200,191,56,25,0,0,0

并且它不会自动绑定到我的控制器作为ObjectId

您有什么建议/最佳做法可以解决这个问题吗?我是否每次都需要对ID进行编码/解码?

谢谢!

5 个答案:

答案 0 :(得分:15)

使用像这样的自定义模型绑定器... (针对官方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)));
    }
}

答案 1 :(得分:14)

我使用以下

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

差点忘了,从ObjectId.ToString()

创建网址

答案 2 :(得分:0)

我不熟悉ObjectId类型,但您可以编写custom model binder来处理将id路由约束转换为ObjectId的实例。< / p>

答案 3 :(得分:0)

您是否知道可以使用[MongoIdentifier]属性将任何属性作为唯一键?

我一直在通过从WordPress借用一种技术来解决这个问题,让每个实体也用“url slug”属性来表示并用[MongoIdentifier]来装饰该属性。

所以,如果我有一个名叫Johnny Walker的人,我会创造一个“johnny-walker”。你只需要确保这些url slugs保持独特,你就可以保持干净的URL没有丑陋的对象ID。

答案 4 :(得分:0)

对于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)