2016-07-20 9 views
8

से आउटपुट मापने के लिए मेरे पास एक पृष्ठ के साथ एमवीसी पर आधारित एक वेबसाइट है जो ओडाटा स्वरूपित परिणामों की सेवा करनी चाहिए, जबकि यह भी लॉग इन कर रहा है कि परिणाम में प्रत्येक रिकॉर्ड का प्रतिनिधित्व करने वाले कितने बाइट भेजे गए थे।ओडाटा प्रतिक्रिया

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

मैं

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

मैंने सोचा कि मैं करने में सक्षम होगा द्वारा OData फ़ॉर्मेटर को हुक करने की कोशिश की: मैं डीबी से परिणाम इस कोड का उपयोग मिलता है 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 में परिभाषित करने के लिए breakpoints सेट है, और कोई भी हिट नहीं हुआ था।

क्या कोई मुझे एक दिशा दे सकता है जहां देखना है?

मैं दृश्य स्टूडियो 2010 के साथ सी # का उपयोग कर रहा, एमएस ASP.NET MVC 5.2.3, OData v4

+0

क्या आपको इसका समाधान मिला है? –

+0

क्या आपने इस विचार की कोशिश की है http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi? – DmitryBLR

उत्तर

4

के लिए एमएस ASP.NET वेब एपीआई 2.2 मैं नहीं यकीन है, लेकिन आप के स्वयं के संस्करण को लागू करता है, तो ODataWriter तो आप प्रविष्टि की लंबाई की जांच कर सकते हैं। इस उदाहरण को देखें: कस्टम ODataWriter के https://blogs.msdn.microsoft.com/odatateam/2015/01/05/tutorial-sample-odatalib-custom-payload-format/। CsvOutputContext में आप

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

मिला मुझे लगता है कि आप Flush से पहले this.stream.Length जाँच करने के लिए कोशिश कर सकते हैं, लेकिन मैं इसे परीक्षण नहीं किया।

संपादित

आप डेटा जोड़ने या जिस तरह से serializer अपने डेटा की बचत होती है आप इस तरह अपने कस्टम ODataWriter अंदर WriteStart ओवरराइड करने के लिए की जरूरत है बदलना चाहते हैं:

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 आप जोड़ना whatver डेटा आप की तरह की सुविधा देता है । बस प्रदान किए गए उदाहरण लिंक को देखें।

EDIT2

आदेश जेपीजी फाइल की तरह बाइनरी डेटा आप इसे क्रमानुसार करने की आवश्यकता होगी बचाने के लिए। इसे देखें:

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); 
    } 
} 
संबंधित मुद्दे