首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebAPI从OnActionExecuted临时覆盖JsonFormatter

WebAPI从OnActionExecuted临时覆盖JsonFormatter
EN

Stack Overflow用户
提问于 2016-05-05 15:16:19
回答 2查看 724关注 0票数 2

我正在尝试创建一个属性,它将以不同的方式序列化从操作返回的数据

代码语言:javascript
复制
public override void OnActionExecuted(HttpActionExecutedContext filterContext)
{
    var content = (filterContext.Response.Content as ObjectContent);

    if (content == null)
    {
        return;
    }

    if (content.ObjectType.IsGenericType 
        && content.ObjectType.GetGenericTypeDefinition() == typeof (Page<>))
    {
        var pageObject = (content.Value as IPage);
        var jsonFormatterRule = new JsonFormatterRule();
        var pageJson = JsonConvert.SerializeObject(pageObject.ItemsArray, 
                                                jsonFormatterRule.GetPascalCasedSettings());

       //How do I set the content that \/ doesn't compile?
       //filterContext.Response.Content = pageJson;
   }
}

这是JsonFormatterRules,以防有人想见他们。

代码语言:javascript
复制
public JsonSerializerSettings GetDefaultSettings()
{
    var settings = new JsonSerializerSettings()
    {
        Formatting = Formatting.Indented,
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
    };

    settings.Converters.AddRange(defaultConfiguredConverters);
    return settings;
}

public JsonSerializerSettings GetPascalCasedSettings()
{
    var settings = this.GetDefaultSettings();
    settings.ContractResolver = new DefaultContractResolver();

    return settings;
}

如何设置执行的On的内容?我不能全局地将默认序列化程序更改为DefaultContract,因为它可能会导致线程问题。

此外,我不希望创建一个新的响应,并复制从旧的标题,似乎超过杀死。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-05 15:49:06

这样做的一种方法是定义自定义格式化程序。

首先,定义属性:

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Class)]
public sealed class SpecialSerializeAttribute : Attribute
{
}

现在创建一个将找到属性的格式化程序:

代码语言:javascript
复制
public class SpecialSerializeFormatter : MediaTypeFormatter
{
    public SpecialSerializeFormatter()
    {
        //You can add any other supported types here.
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
    }

    public override bool CanReadType(Type type)
    {
        //you can just return false if you don't want to read any differently than your default way
        //if you return true here, you should override the ReadFromStreamAsync method to do custom deserialize
        return type.IsDefined(typeof(SpecialSerializeAttribute), true));
    }

    public override bool CanWriteType(Type type)
    {
        return type.IsDefined(typeof(SpecialSerializeAttribute), true));
    }

    public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
        TransportContext transportContext)
    {

        //value will be your object that you want to serialize

        //add any custom serialize settings here
        var json = JsonConvert.SerializeObject(value);

        //Use the right encoding for your application here
        var byteArray = Encoding.UTF8.GetBytes(json);
        await writeStream.WriteAsync(byteArray, 0, byteArray.Length);
    }
}

在您的WebApiConfig.cs中注册格式化程序

您还可以直接为每种类型构建一个格式化程序,然后不必执行该属性。只需更改CanRead和CanWrite方法即可。我发现基于这些直接类型提供了更好的结果,因为它不是这样的通用格式化程序,您可能需要根据类型应用自定义逻辑,但是上面的答案应该可以满足您的需要。

票数 1
EN

Stack Overflow用户

发布于 2016-05-05 16:55:41

如果有人想知道,响应内容是一个HTTPContent,它继承自ByteArrayContent。因此,如果已经序列化了JSON,则只需将其放入字节数组中即可。

代码语言:javascript
复制
filterContext.ActionContext.Response.Content = new ByteArrayContent(Encoding.ASCII.GetBytes(pageJson));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37054236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档