如何从序列化过程中访问请求信息

时间:2013-10-01 07:45:43

标签: c# asp.net-mvc json serialization asp.net-web-api

我正在使用Visual Studio 2012目标.Net 4+开发(自托管)WebApi应用程序,并着眼于尽快迁移到VS2013以利用MVC 5和WebApi 2.0。

我需要在所有传出的Uri前面添加一个字符串,该字符串作为传入请求的查询参数发送。挑战是在控制器,模型或视图/视图模型中没有任何特定代码的情况下执行此操作。如果可能的话,我还想避免使用需要使用反射/递归来处理传出响应的所有属性的动作过滤器,尽管使用结果动作过滤器来制作url前缀可用于序列化程序。

我到目前为止所提供的是DelegatingHandler来获取请求的查询参数中使用的url前缀,因此可以将其作为属性添加到某个请求/控制器上下文对象中;并使用JsonConverter为响应中的所有Uri类型属性添加所需的前缀。

我剩下的就是将请求参数中指定的Url前缀转换为转换器。传递给JsonConvertor的序列化程序确实具有Context属性,但我无法看到它是否以及如何与请求上下文相关。

我可以想出一些方法来解决这个问题,但是对于MVC / WebApi如何在管道周围传递请求(上下文)信息,仍然会遇到“缺乏知识”的障碍。

委派处理程序:

class UrlPrefixHandler : DelegatingHandler 
{
    private string GetUrlPrefixValue(HttpRequestMessage request)
    {
        var queryStrings = request.GetQueryNameValuePairs();
        if (queryStrings == null)
            return null;

        var match = queryStrings.FirstOrDefault(kv => string.Compare(kv.Key, "url_prefix", true) == 0);
        if (string.IsNullOrEmpty(match.Value))
            return null;

        return match.Value;
    }

    async protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        string urlPrefix = GetUrlPrefixValue(request);

        // TODO : How do I get this to the serializer on a per request basis?
        //        and do this without placing requirements on controllers/models/views?

        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

        return response;
    }
}

Json转换器:

class UriPrefixConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Uri).IsAssignableFrom(objectType);
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JObject result = new JObject();

        //serializer.

        Uri u = (Uri)value as Uri;

        // TODO : Getting the prefix from the request's context somehow
        Uri prefixed = new Uri("/uriPrefix" + u.OriginalString, UriKind.Relative);

        writer.WriteValue(prefixed.OriginalString);
    }

0 个答案:

没有答案