0

我希望使用 MS.NET MVC 的 ValueProvider 工具封装我的 json api 的所有序列化逻辑。

但是,由于我的反序列化是类型导向的(即,它需要知道从反序列化返回的类),并且我无法找到合理的方法来获取我的 ValueProvider 应该返回的类型。

假设我们有一个控制器:

public class MyController : Controller
{
  // We want obj to be instantiated by MyValueProvider
  public ActionResult MyAction(MyComplexObject obj)
  {

  }
}

然后我希望能够写:

public class MyValueProvider : IValueProvider
{

  public bool ContainsPrefix(string prefix)
  {
   ...
  }

  public ValueProviderResult GetValue(string key)
  {
    switch (req.HttpMethod)
    {
      case "POST":
        {
          req.InputStream.Position = 0;
          T retObj = MyDeserialize<T>(req.InputStream);

          return new ValueProviderResult(retObj, key, CultureInfo.CurrentCulture);
        }
        break;
      default:
        return null;
    }
  }
}

(虽然我意识到如果没有在 MyValueProvider 中实际绑定 T 我将不得不使用反射来调用 MyDeserialize 与运行时提供的类型)

我几乎正在考虑使用由 GetValue 的“key”参数键入的一些变量命名方案来派生运行时类型以反序列化。

4

1 回答 1

0

经过半天的思考,然后阅读http://ishwor.cyberbudsonline.com/2012/07/fun-with-aspnet-mvc-3-custom-json-model-binder.html,我得出了结论我需要的实际上是一个 ModelBinder,因为 ModelType 在 BindingContext 中可用。

因此,问题中的 ValueProvider 变为:

public class MyModelBinder<T> : IModelBinder
{
  public object BindModel(
    ControllerContext controllerContext, 
    ModelBindingContext bindingContext)
  {
    JToken resTok;

    var key = bindingContext.ModelName;
    var req = controllerContext.HttpContext.Request;

    if (bindingContext.ModelType != typeof(T)) return null;

    switch (req.HttpMethod)
    {
      case "POST":
        req.InputStream.Position = 0;
        T retObj = MyDeserialize<T>(req.InputStream);
        return retObj;
        break;

      default:
        return null;
    }
  }
}
于 2013-09-30T15:13:47.037 回答