У меня есть веб-сайт, основанный на MVC со страницей, которая должна отображать результаты в формате OData, а также регистрировать, сколько байтов было отправлено, представляя каждую запись в результате. получить результаты из БД, используя этот код:Измерение вывода из ответа OData
[EnableQuery]
public IHttpActionResult GetRecords(ODataQueryOptions<Record> queryOptions)
{
DataProvider<Record> provider = GetRecordProvider();
...
return OK<IQueryable<Record>>(provider.Queryable);
}
Я пытался подключить к форматере OData по
config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create(new CustomODataSerializerProvider(), new DefaultODataDeserializerProvider()));
где
public class CustomODataSerializerProvider : DefaultODataSerializerProvider
{
public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
{
if (edmType.Definition.TypeKind == EdmTypeKind.Entity)
return new CustomODataEntityTypeSerializer(this);
else
return base.GetEdmTypeSerializer(edmType);
}
}
public class CustomODataEntityTypeSerializer : ODataEntityTypeSerializer
{
public CustomODataEntityTypeSerializer(ODataSerializerProvider provider)
: base(provider)
{
}
public override ODataProperty CreateStructuralProperty(IEdmStructuralProperty structuralProperty, EntityInstanceContext entityInstanceContext)
{
var property = base.CreateStructuralProperty(structuralProperty, entityInstanceContext);
if(property.Value == null) return null;
else return property;
}
public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
{
base.WriteObject(graph, type, messageWriter, writeContext);
}
public override void WriteDeltaObjectInline(object graph, IEdmTypeReference expectedType, ODataDeltaWriter writer, ODataSerializerContext writeContext)
{
base.WriteDeltaObjectInline(graph, expectedType, writer, writeContext);
}
public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
{
int outputSize = 0;
base.WriteObjectInline(graph, expectedType, writer, writeContext);
writer.Flush();
Log(outputSize);
}
}
Я думал, что я мог бы узнать длину вывода, сгенерированного вызовом WriteObjectInline
, но не можете понять, как это сделать.
Я также попробовал другое решение, используя
public class MeasuringJsonFormatter : ODataMediaTypeFormatter
{
public MeasuringJsonFormatter(IEnumerable<Microsoft.Data.OData.ODataPayloadKind> payloadKinds)
: base(payloadKinds)
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override bool CanReadType(Type type)
{
return false;
}
private bool IsSupportedType(Type type)
{
return type==typeof(Record);
}
private bool IsSupportedCollection(Type type)
{
return
type.IsGenericType &&
IsSupportedType(type.GetGenericArguments()[0]) &&
typeof(IEnumerable<>).MakeGenericType(type.GetGenericArguments()[0]).IsAssignableFrom(type)
;
}
public override bool CanWriteType(Type type)
{
return IsSupportedType(type) || IsSupportedCollection(type);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
return base.WriteToStreamAsync(typeof(string), Format(type, value, content), writeStream, content, transportContext);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext, System.Threading.CancellationToken cancellationToken)
{
return base.WriteToStreamAsync(typeof(string), Format(type, value, content), writeStream, content, transportContext, cancellationToken);
}
private string Format(Type type, object value, System.Net.Http.HttpContent content)
{
if (IsSupportedType(type))
{
string result =JsonConvert.SerializeObject(value, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
Log(result.Length);
return result;
}
else if (IsSupportedCollection(type))
{
StringBuilder sb = new StringBuilder();
foreach (object item in (value as IEnumerable)) sb.Append(Format(type.GetGenericArguments()[0], item, content));
return sb.ToString();
}
else return "Unable to process type " + type.ToString();
}
}
зацепиться
config.Formatters.Insert(0, new MeasuringJsonFormatter(new ODataPayloadKind[] { ODataPayloadKind.Entry, ODataPayloadKind.Feed}));
но здесь крюк, кажется, не работает: я установить точки останова для всех методов, определенных в MeasuringJsonFormatter
и никого не было.
Может ли кто-нибудь дать мне направление, где искать?
Я использую C# с Visual Studio 2010, MS ASP.NET MVC 5.2.3, MS ASP.NET Web API 2.2 для OData v4
Вы нашли решение этого? –
Вы пробовали эту идею http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi? – DmitryBLR