我正在与Mongo,NoRM和MVC .Net开始一个新项目。
在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。因此,当我有一个编辑链接时,我的URL看起来像这样:
网站/管理员/编辑/ 23,111,160,3,240,200,191,56,25,0,0,0
并且它不会自动绑定到我的控制器作为ObjectId
您有什么建议/最佳做法可以解决这个问题吗?我是否每次都需要对ID进行编码/解码?
谢谢!
答案 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)