我正在用Mongo,NoRM和MVC .Net开始一个新项目。如何在MVC.net中从MongoDB传递ObjectId
在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。所以,当我有一个编辑链接我的网址是这样的:
网站/管理/编辑/ 23,111,160,3,240,200,191,56,25,0,0,0
它不全自动绑定到我的控制器一个ObjectId
你对此有何建议/最佳实践?我需要每次编码/解码ID吗?
谢谢!
我正在用Mongo,NoRM和MVC .Net开始一个新项目。如何在MVC.net中从MongoDB传递ObjectId
在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。所以,当我有一个编辑链接我的网址是这样的:
网站/管理/编辑/ 23,111,160,3,240,200,191,56,25,0,0,0
它不全自动绑定到我的控制器一个ObjectId
你对此有何建议/最佳实践?我需要每次编码/解码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);
}
}
和
protected void Application_Start()
{
......
ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdModelBinder());
}
差点忘了,从ObjectId.ToString()
我不熟悉ObjectId
类型,但可以编写custom model binder,它将负责将id
路由约束转换为ObjectId
的实例。
您是否知道可以使用[MongoIdentifier]属性使任何属性充当唯一键?
我一直在解决这个问题,通过让每个实体都代表一个“url slug”属性并用[MongoIdentifier]装饰该属性来借用WordPress技术。
所以,如果我有一个名叫约翰尼沃克的人,我会创造一个“johnny-walker”的slu slu。你只需要确保这些url slugs保持独特,你就可以保持干净的网址,而不会有丑陋的对象id。
是啊,我知道的是,因为它是只为管理我不需要有干净的网址。现在,我添加了一个IdValue属性,它将ObjectId值呈现为一个字符串,并且当我需要获取我刚刚做的数据时.Single(new ObjectId(id))不确定这是否是最好的方法,但它工作正常。 – VinnyG 2010-06-29 20:00:10
使网址使用这样的自定义模型粘合剂... (对官方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)));
}
}
这会在抛出参数时抛出异常。我认为使用TryParse并在无效时返回ObjectId.Empty是处理它的更好方法。 – phloopy 2012-10-23 15:16:47
对于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)
当在表单中传递值时,此解决方案不起作用。无论值如何传递,请参阅我的答案,以获得可行的解决方案。 (可能值得注意的是这是C#MongoDB驱动程序,因为它们的语法各不相同)。 – 2010-12-04 07:10:41
原始问题在ASP.NET MVC和标准代码中,允许控制器从url解析ObjectId。 – Sherlock 2010-12-13 19:51:19