问题
I'm starting a new project with Mongo, NoRM and MVC .Net.
Before I was using FluentNHibernate so my IDs were integer, now my IDs are ObjectId. So when I have an Edit link my URL looks like this :
WebSite/Admin/Edit/23,111,160,3,240,200,191,56,25,0,0,0
And it does not bind automaticly to my controller as an ObjectId
Do you have any suggestions/best practices to work with this? Do I need to encode/decode the ID everytime?
Thanks!
回答1:
I Use following
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);
}
}
and
protected void Application_Start()
{
......
ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdModelBinder());
}
almost forgot, make URLs from ObjectId.ToString()
回答2:
Use a custom model binder like this ... (working against the offical C# MongoDB driver)
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)));
}
}
回答3:
I am not familiar with the ObjectId
type but you could write a custom model binder that will take care of converting the id
route constraint to an instance of ObjectId
.
回答4:
Did you know you can use the [MongoIdentifier] attribute to make any property act as the unique key?
I've been solving this issue by borrowing a technique from WordPress by having every entity also be represented by a "url slug" property and decorating that property with [MongoIdentifier].
So if I had a person named Johnny Walker I'd create a slug of "johnny-walker". You just have to make sure these url slugs stay unique and you get to keep clean urls without ugly object ids.
回答5:
For Web API you can add Custom parameter binding ule in 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");
}
}
}
}
And use it Without any additional attributes in controller:
[Route("{id}")]
public IHttpActionResult Get(ObjectId id)
来源:https://stackoverflow.com/questions/3143254/how-to-pass-objectid-from-mongodb-in-mvc-net