网页API ModelBinders - 如何将一个属性绑定你的对象的不同 [英] Web API ModelBinders - how to bind one property of your object differently

查看:158
本文介绍了网页API ModelBinders - 如何将一个属性绑定你的对象的不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下行为的签名

    [ValidateInput(false)]
    public HttpResponseMessage PostParam(Param param)

通过参数看起来像这样:

With Param looking something like this:

public class Param {
  public int Id { get; set;}
  public string Name { get; set; }
  public string Choices { get; set; }
}

这里的顺利 - 有什么过来的电线像这样

Here's the hitch - what comes over the wire is something like this

{
  Id: 2,
  Name: "blah",
  Choices: [
    {
      foo: "bar"
    },
    {
      blah: "blo"
      something: 123
    }
  ]
}

我不希望选择反序列化 - 我想它存储为一个字符串(是的,我理解的安全隐患)。可以理解的是,我得到一个错误,因为如果默认的粘结剂不知道这一点。

I don't want "Choices" to deserialize - I want it stored as a string (yes, I understand the security implications). Understandably, I get an error because since the default binder does not know this.

现在用Asp的mvc创建​​特定ModelBinder的将是相当简单的。我倒是

Now with Asp Mvc creating a specific ModelBinder would be fairly simple. I'd


  • 继承DefaultModelBinder

  • 用我自己
  • 重写属性反序列化
  • 设置在活页夹我的的Application_Start 使用 Binders.Add

  • inherit DefaultModelBinder
  • override the property deserialization with my own
  • set the binder in my Application_Start using Binders.Add

好像与网页API,这是一个不同的过程 - System.Web.DefaultModelBinder不会有什么重写,而且我不能用钩东西 Binders.Add 。我试着环顾四周,但找不到太多关于如何真正做我想做的。这是进一步复杂化,因为显然ModelBinders API改变了不少过测试版和RTM所以有很多过时的信息在那里。

Seems like with Web Api this is a different process - the System.Web.DefaultModelBinder doesn't have anything to override and that I can't hook things up using Binders.Add. I've tried looking around but couldn't find much on how to actually do what I want. This is further complicated since apparently the ModelBinders api changed quite a bit over Beta and RTM so there's a lot of outdated information out there.

推荐答案

在网页API,你必须区分三个概念 - ModelBinding 格式化程序 ParameterBinding 。这是相当混乱的人/移动使用MVC,在这里我们只谈 ModelBinding

In Web API you have to distinguish three concepts - ModelBinding, Formatters and ParameterBinding. That is quite confusing to people moving from/used to MVC, where we only talk about ModelBinding.

ModelBinding ,违背了MVC,只是拉出来的数据URI的责任。格式化处理读书身体, ParameterBinding HttpParameterBinding ),既包括前概念。

ModelBinding, contrary to MVC, is responsible only for pulling data out of URI. Formatters deal with reading the body, and ParameterBinding (HttpParameterBinding) encompasses both of the former concepts.

ParameterBinding 当你想彻底改变整个机制(即允许从身体约束两个对象,实现MVC式装订等)真的是唯一有用的 - 对于简单的任务修改粘合剂(URI具体数据)或格式化(身体数据)几乎绰绰有余总是更。

ParameterBinding is really only useful when you want to revolutionize the whole mechanism (i.e. allow two objects to be bound from body, implement MVC-style binding and so on) - for simpler tasks modifying binders (for URI specific data) or formatters (for body data) is almost always more than enough.

总之,到了点 - 你想达到可以很容易地用自定义做了什么 JSON.NET 转换器(JSON.NET背后是网络的默认序列化库API JSON格式引擎)。

Anyway, to the point - what you want to achieve can very easily be done with a custom JSON.NET converter (JSON.NET is the default serialization library behind Web API JSON formatting engine).

所有你需要做的是:

public class Param
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonConverter(typeof(CustomArrayConverter))]
    public string Choices { get; set; }
}

然后添加转换器:

And then add the converter:

internal class CustomArrayConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                    JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        return JsonConvert.SerializeObject(array);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, JArray.Parse(value as string));
    }
}

在这种情况下,我们告诉JSON.NET在转换器存储选择字符串(在读法),当你返回与选择了参数对象属性客户端(在写法),我们采取字符串和序列化到阵列使输出JSON看起来与输入相同的。

In this case we are telling JSON.NET in the converter to store Choices as string (in the read method), and when you return the Param object with the Choices property to the client (in the write method) we take the string and serialize to an array so that the output JSON looks identical to the input one.

您现在可以测试它是这样的:

You can test it now like this:

    public Param PostParam(Param param)
    {
        return param;
    }

和验证数据进来就像你希望和数据出来等同于原来的JSON

And verify that the data coming in is like you wished, and the data coming out is identical to the original JSON.

这篇关于网页API ModelBinders - 如何将一个属性绑定你的对象的不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆