9

我正在使用 Mongo、NoRM 和 MVC .Net 开始一个新项目。

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

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

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

您对此有任何建议/最佳实践吗?我是否需要每次都对 ID 进行编码/解码?

谢谢!

4

5 回答 5

16

使用这样的自定义模型绑定器...... (针对官方 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)));
    }
}
于 2010-12-04T07:09:04.480 回答
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()

于 2010-07-15T05:48:36.797 回答
0

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

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

因此,如果我有一个叫 Johnny Walker 的人,我会创建一个“johnny-walker”的蛞蝓。你只需要确保这些 url slug 保持唯一,并且你可以保持干净的 url 没有丑陋的对象 ID。

于 2010-06-29T18:34:06.023 回答
0

我不熟悉该ObjectId类型,但您可以编写一个自定义模型绑定器,负责将id路由约束转换为ObjectId.

于 2010-06-29T17:39:37.477 回答
0

对于 Web API,您可以在 WebApiConfig 中添加自定义参数绑定 ule:

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)
于 2017-11-04T04:34:33.600 回答