.net 创建需要类型信息的MVC3 ValueProviderFactory?

.net 创建需要类型信息的MVC3 ValueProviderFactory?,.net,asp.net-mvc,asp.net-mvc-3,protobuf-net,.net,Asp.net Mvc,Asp.net Mvc 3,Protobuf Net,我正在尝试为ASP MVC3编写一个Protobuf ValueProviderFactory。我设法解决了这个问题,但现在我遇到了一个更紧迫的问题。 这里是当前序列化在JsonValueProviderFactory.cs JavaScriptSerializer serializer = new JavaScriptSerializer(); object jsonData = serializer.DeserializeObject(bodyText); retur

我正在尝试为ASP MVC3编写一个Protobuf ValueProviderFactory。我设法解决了这个问题,但现在我遇到了一个更紧迫的问题。 这里是当前序列化在
JsonValueProviderFactory.cs

    JavaScriptSerializer serializer = new JavaScriptSerializer();
    object jsonData = serializer.DeserializeObject(bodyText);
    return jsonData;
那么反序列化是在没有任何类型信息的情况下完成的?
反序列化对象
返回什么类型的对象?动态?它如何知道数据的类型?我希望在这里插入protobuf网络,但它显然需要一个类型来发挥它的魔力

我还没有看过所有的MVC3源代码,但我猜到类型的映射发生在最后阶段,并且没有办法知道ValueProviderFactorys中的类型


我必须放弃并在动作中进行转换吗?

这里有几个问题

有关
JavaScriptSerializer
的工作原理,请阅读。该类尝试为基本类型(int、bool、date等)推断类型,并为更复杂的情况返回
Dictionary
。此外,如果JSON blob包含一个名为“\uuuu type”的特殊属性,那么反序列化程序将尝试创建该类型的对象

现在来看看这在MVC中是如何工作的。将值从请求映射到控制器中使用的对象实例的过程称为模型绑定。这分为两个组件:ModelBinder和ValueProviders。模型绑定器知道目标类型(例如产品),尝试创建其实例,然后使用请求中的值填充其属性。它通过询问ValueProviders来实现。例如,要在产品实例上设置Name属性,它会向值提供者请求“Name”的值。值提供者按顺序被查询并返回匹配项(来自查询字符串、post数据、JSON请求体等)


网络上有很多关于这方面的资源,但简言之,价值提供者不应该真正关心类型。

这里是一个使用ModelBinder的解决方案的快速尝试,正如marcind所建议的。这是未经测试的,但这只是一个开始。在本例中,
FromProtobuf
是一种简单的
byte[]
对象扩展方法

public class ProtobufModelBinder<T> : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/x-protobuf", StringComparison.OrdinalIgnoreCase))
            return null;

        using (MemoryStream ms = new MemoryStream())
        {
            controllerContext.HttpContext.Request.InputStream.CopyTo(ms);
            return ms.ToArray().FromProtobuf<T>();
        }
    }
}
公共类ProtobufModelBinder:IModelBinder
{
公共对象绑定模型(ControllerContext ControllerContext,ModelBindingContext bindingContext)
{
if(!controllerContext.HttpContext.Request.ContentType.StartWith(“应用程序/x-protobuf”,StringComparison.OrdinalIgnoreCase))
返回null;
使用(MemoryStream ms=new MemoryStream())
{
controllerContext.HttpContext.Request.InputStream.CopyTo(ms);
从protobuf()返回ms.ToArray();
}
}
}
可按如下方式进行设置:

ModelBinders.Binders.Add(typeof(MyClass), new ProtobufModelBinder<MyClass>());
ModelBinders.Binders.Add(typeof(MyClass),newprotobufmodelbinder());

Re-type-请注意,它需要一个
type
实例,但不必使用通用API。这意味着,如果您可以从
ParameterInfo
之类的信息推断
类型
,那么这应该是可能的。