我正在使用 Mongo、NoRM 和 MVC .Net 开始一个新项目。
在我使用 FluentNHibernate 之前,我的 ID 是整数,现在我的 ID 是 ObjectId。所以当我有一个编辑链接时,我的 URL 看起来像这样:
网站/管理员/编辑/23,111,160,3,240,200,191,56,25,0,0,0
而且它不会作为 ObjectId 自动绑定到我的控制器
您对此有任何建议/最佳实践吗?我是否需要每次都对 ID 进行编码/解码?
谢谢!
我正在使用 Mongo、NoRM 和 MVC .Net 开始一个新项目。
在我使用 FluentNHibernate 之前,我的 ID 是整数,现在我的 ID 是 ObjectId。所以当我有一个编辑链接时,我的 URL 看起来像这样:
网站/管理员/编辑/23,111,160,3,240,200,191,56,25,0,0,0
而且它不会作为 ObjectId 自动绑定到我的控制器
您对此有任何建议/最佳实践吗?我是否需要每次都对 ID 进行编码/解码?
谢谢!
使用这样的自定义模型绑定器...... (针对官方 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)));
}
}
我使用以下
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()
您是否知道可以使用 [MongoIdentifier] 属性使任何属性充当唯一键?
我一直在通过从 WordPress 借用一种技术来解决这个问题,方法是让每个实体也由一个“url slug”属性表示,并用 [MongoIdentifier] 装饰该属性。
因此,如果我有一个叫 Johnny Walker 的人,我会创建一个“johnny-walker”的蛞蝓。你只需要确保这些 url slug 保持唯一,并且你可以保持干净的 url 没有丑陋的对象 ID。
我不熟悉该ObjectId
类型,但您可以编写一个自定义模型绑定器,负责将id
路由约束转换为ObjectId
.
对于 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)