Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何在MVC.net中从MongoDB传递ObjectId_Asp.net Mvc_Mongodb_Norm - Fatal编程技术网

Asp.net mvc 如何在MVC.net中从MongoDB传递ObjectId

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

我正在用Mongo、NoRM和MVC.Net启动一个新项目

在我使用FluentNHibernate之前,我的ID是整数,现在我的ID是ObjectId。因此,当我有一个编辑链接时,我的URL如下所示:

网站/Admin/Edit/23111160,3240200191,56,25,0,0,0

而且它不会作为ObjectId自动绑定到我的控制器

您对此有何建议/最佳做法?我是否每次都需要对ID进行编码/解码


谢谢

我不熟悉
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)