2

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

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

到目前为止,我所做的是DelegatingHandler从请求的查询参数中获取要使用的 url 前缀,以便可以将其作为属性添加到某些请求/控制器上下文对象中;并使用 a为响应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);
    }
4

0 回答 0