2016-07-20 21 views
8

OData dayalı bir sayfaya hizmet vermeli ve aynı zamanda sonuçta her bir kaydı temsil eden kaç baytın kaydedildiği bir sayfaya sahip bir web sitem var.OData yanıtından ölçüm çıkışı

[EnableQuery] 
public IHttpActionResult GetRecords(ODataQueryOptions<Record> queryOptions) 
{ 
DataProvider<Record> provider = GetRecordProvider(); 
... 
return OK<IQueryable<Record>>(provider.Queryable); 
} 

Ben

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); 
     } 
    } 

ben mümkün olacağını düşündüm

config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create(new CustomODataSerializerProvider(), new DefaultODataDeserializerProvider())); 

tarafından OData biçimlendiriciye kanca çalıştı: Bu kodu kullanarak DB'den sonuçları almak WriteObjectInline çağrısı tarafından üretilen çıktının uzunluğunu bulmak, ancak nasıl yapılacağını anlayamıyorum. Ben MeasuringJsonFormatter tanımlanan tüm yöntemlere kesme noktaları ayarlayın ve:

Ben de işe

config.Formatters.Insert(0, new MeasuringJsonFormatter(new ODataPayloadKind[] { ODataPayloadKind.Entry, ODataPayloadKind.Feed})); 

ama burada kanca görünmüyor tarafından bağımlısı

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(); 
    } 

} 

kullanarak farklı bir çözüm çalıştı hiçbiri vurulmadı.

Herkes bana nerede bakılacağı yönünde bir yön verebilir mi?

Ben Visual Studio 2010 ile C# kullanıyorum, MS ASP.NET MVC 5.2.3, OData v4

+0

Bunun için bir çözüm buldunuz mu? –

+0

Bu fikri denediniz mi http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi? – DmitryBLR

cevap

4

MS ASP.NET Web API 2.2 emin değilim ama kendi sürümünü uygularsanız ODataWriter sonra girişin uzunluğunu kontrol edebilirsiniz. Şu örneğe bakın: özel ODataWriter öğesinin https://blogs.msdn.microsoft.com/odatateam/2015/01/05/tutorial-sample-odatalib-custom-payload-format/. CsvOutputContext size ben Flush önce this.stream.Length kontrol etmek deneyebilirsiniz düşünüyorum

public void Flush() 
{ 
    this.stream.Flush(); 
} 

var, ama bunu test etmedi.

DÜZENLEME

Eğer böyle özel ODataWriter içine WriteStart geçersiz kılmak gerekir serileştirici verilerinizi kaydeder yolu veri eklemek veya değiştirmek isterseniz:

public override void WriteStart(ODataFeed feed) 
{ 
} 

private void WriteEntry(ODataEntry entry) 
{ 
    foreach (var header in this.headers) 
    { 
     var property = entry.Properties.SingleOrDefault(p => p.Name == header);  
     if (property != null) 
     { 
      this.context.Writer.Write(property.Value); 
     }  
     this.context.Writer.Write(","); 
    }  
    this.context.Writer.WriteLine(); 
} 

this.context.Writer.Write İstediğiniz whatver veri eklemenize izin verir . Sadece sağladığım örnek bağlantıya bakın. Eğer serialize gerekecektir jpg dosyası gibi ikili veri kaydetmek için

EDIT2

. Şuna bak:

private void WriteEntry(ODataEntry entry) 
{ 
    string file = @"C:\test.jpg"; 
    byte[] data = File.ReadAllBytes(file); 
    using (MemoryStream fileStream = new MemoryStream(data)) 
    using (Image i = Image.FromStream(originalms)) 
    { 
     i.Save(this.context.Writer, System.Drawing.Imaging.ImageFormat.Jpeg); 
    } 
}