我正在使用针对 .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);
}