ero su Google quando devo affrontare tale questione nel mio compito .. Ho implementazione pulita da questa thread
primo luogo è necessario verificare EDM ModelBuilder in modo corretto per espandere oggetti
voi è necessario registrare il modello edm per blog e releations di chiave esterna.then solo esso riuscirà
Esempio
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Blog>("blog");
builder.EntitySet<Profile>("profile");//ForeignKey releations of blog
builder.EntitySet<user>("user");//ForeignKey releations of profile
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
Allora avete bisogno di sviluppare questo formattatore di codice sorgente ..example noi here
applogies per il mio inglese ..
Prima di tutto abbiamo bisogno di creare una classe che sarà derivata dalla classe astratta MediaTypeFormatter. Qui è la classe con i suoi costruttori:
public class CSVMediaTypeFormatter : MediaTypeFormatter {
public CSVMediaTypeFormatter() {
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
}
public CSVMediaTypeFormatter(
MediaTypeMapping mediaTypeMapping) : this() {
MediaTypeMappings.Add(mediaTypeMapping);
}
public CSVMediaTypeFormatter(
IEnumerable<MediaTypeMapping> mediaTypeMappings) : this() {
foreach (var mediaTypeMapping in mediaTypeMappings) {
MediaTypeMappings.Add(mediaTypeMapping);
}
}
}
Sopra, non importa quale il costruttore si utilizza, abbiamo sempre aggiungere del testo/csv tipo di supporto da sostenere per questo formattatore. Inoltre, consente l'iniezione di MediaTypeMappings personalizzati.
Ora, è necessario eseguire l'override di due metodi: MediaTypeFormatter.CanWriteType e MediaTypeFormatter.OnWriteToStreamAsync.
Prima di tutto, ecco l'implementazione del metodo CanWriteType. Ciò che questo metodo deve fare è determinare se il tipo di oggetto è supportato con questo formattatore o meno per scriverlo.
protected override bool CanWriteType(Type type) {
if (type == null)
throw new ArgumentNullException("type");
return isTypeOfIEnumerable(type);
}
private bool isTypeOfIEnumerable(Type type) {
foreach (Type interfaceType in type.GetInterfaces()) {
if (interfaceType == typeof(IEnumerable))
return true;
}
return false;
}
Ciò che fa qui è controllare se l'oggetto ha implementato l'interfaccia IEnumerable. Se è così, allora è bello e può formattare l'oggetto. In caso contrario, restituirà false e framework ignorerà questo formattatore per quella particolare richiesta.
Infine, ecco l'effettiva implementazione. Abbiamo bisogno di fare un certo lavoro con la riflessione qui, al fine di ottenere i nomi ei valori delle proprietà fuori dal parametro di valore che è un tipo di oggetto:
protected override Task OnWriteToStreamAsync(
Type type,
object value,
Stream stream,
HttpContentHeaders contentHeaders,
FormatterContext formatterContext,
TransportContext transportContext) {
writeStream(type, value, stream, contentHeaders);
var tcs = new TaskCompletionSource<int>();
tcs.SetResult(0);
return tcs.Task;
}
private void writeStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders) {
//NOTE: We have check the type inside CanWriteType method
//If request comes this far, the type is IEnumerable. We are safe.
Type itemType = type.GetGenericArguments()[0];
StringWriter _stringWriter = new StringWriter();
_stringWriter.WriteLine(
string.Join<string>(
",", itemType.GetProperties().Select(x => x.Name)
)
);
foreach (var obj in (IEnumerable<object>)value) {
var vals = obj.GetType().GetProperties().Select(
pi => new {
Value = pi.GetValue(obj, null)
}
);
string _valueLine = string.Empty;
foreach (var val in vals) {
if (val.Value != null) {
var _val = val.Value.ToString();
//Check if the value contans a comma and place it in quotes if so
if (_val.Contains(","))
_val = string.Concat("\"", _val, "\"");
//Replace any \r or \n special characters from a new line with a space
if (_val.Contains("\r"))
_val = _val.Replace("\r", " ");
if (_val.Contains("\n"))
_val = _val.Replace("\n", " ");
_valueLine = string.Concat(_valueLine, _val, ",");
} else {
_valueLine = string.Concat(string.Empty, ",");
}
}
_stringWriter.WriteLine(_valueLine.TrimEnd(','));
}
var streamWriter = new StreamWriter(stream);
streamWriter.Write(_stringWriter.ToString());
}
Siamo parzialmente finito. Ora, dobbiamo fare uso di questo. Ho registrato questo formattatore nella pipeline con il seguente codice all'interno metodo Global.asax Application_Start:
GlobalConfiguration.Configuration.Formatters.Add(
new CSVMediaTypeFormatter(
new QueryStringMapping("format", "csv", "text/csv")
)
);
Sulla mia applicazione di esempio, quando si passa a/api/auto format = csv, si otterrà un file CSV? ma senza un'estensione. Vai avanti e aggiungi l'estensione csv. Quindi, aprilo con Excel e dovresti vedere qualcosa di simile al seguente:
Mille benedizioni su di voi signore. – gorillapower