Asp.net mvc 如何在MVC.net中从MongoDB传递ObjectId
我正在用Mongo、NoRM和MVC.Net启动一个新项目 在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。因此,当我有一个编辑链接时,我的URL如下所示: 网站/Admin/Edit/23111160,3240200191,56,25,0,0,0 而且它不会作为ObjectId自动绑定到我的控制器 您对此有何建议/最佳做法?我是否每次都需要对ID进行编码/解码Asp.net mvc 如何在MVC.net中从MongoDB传递ObjectId,asp.net-mvc,mongodb,norm,Asp.net Mvc,Mongodb,Norm,我正在用Mongo、NoRM和MVC.Net启动一个新项目 在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。因此,当我有一个编辑链接时,我的URL如下所示: 网站/Admin/Edit/23111160,3240200191,56,25,0,0,0 而且它不会作为ObjectId自动绑定到我的控制器 您对此有何建议/最佳做法?我是否每次都需要对ID进行编码/解码 谢谢 我不熟悉ObjectId类型,但您可以编写一个将id路由约束转换为ObjectId
谢谢 我不熟悉
ObjectId
类型,但您可以编写一个将id
路由约束转换为ObjectId
实例的路由约束,您知道可以使用[MongoIdentifier]属性使任何属性充当唯一键吗
我一直在通过借用WordPress的技术来解决这个问题,让每个实体也由一个“url slug”属性表示,并用[MongoIdentifier]装饰该属性
所以,如果我有一个叫约翰尼·沃克的人,我会创造一段“约翰尼·沃克”。您只需确保这些url段塞保持唯一,就可以保持干净的url,而不会有难看的对象ID。我使用以下方法
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);
}
}
及
差点忘了,让来自
ObjectId.ToString()
的URL使用如下自定义模型绑定器。。。(与官方的C#MongoDB司机作对)
对于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)
是的,我知道,因为这只是为了管理,我不需要有干净的网址。现在,我添加了一个IdValue属性,该属性将ObjectId值呈现为字符串,当我需要获取数据时,我只需这样做。Single(new ObjectId(id))不确定这是否是最好的方法,但它工作正常……当值以表单形式传递时,此解决方案不起作用。请参阅我的答案,了解一个无论值如何传递都有效的解决方案。(可能还值得注意的是,这是针对哪个C#MongoDB驱动程序的,因为它们的语法不同)。最初的问题是在ASP.NET MVC和允许控制器从url解析ObjectId的标准代码的上下文中。这会在修改参数时引发异常。我认为使用TryParse并在ObjectId.Empty无效时返回它是一种更好的处理方法。@IanMercer如果ObjectId可为null,则不会
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)