我正在用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