當我面對我的任務,問題,我GOOGLE了..我有乾淨實現從這個thread
首先你需要驗證EDM模型構建器以適當的方式爲擴大 對象
你必須註冊edm模型博客和外鍵的releas.then只有它會成功
例
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());
然後,你需要開發這個格式..example源代碼,我們here
applogies,我的英語 ..
首先,我們需要創建一個將從MediaTypeFormatter抽象類派生的類。下面是它的構造函數的類:
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);
}
}
}
以上,無論你用哪個構造,我們隨時添加這種格式可以支持文本/ CSV媒體類型。我們還允許注入自定義MediaTypeMappings。
現在,我們需要重寫兩個方法:MediaTypeFormatter.CanWriteType和MediaTypeFormatter.OnWriteToStreamAsync。
首先,這裏是CanWriteType方法的實現。該方法需要做的是確定該格式化程序是否支持該對象的類型,以便編寫它。
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;
}
這裏做的是檢查對象是否實現了IEnumerable接口。如果是這樣,那麼它很酷,可以格式化對象。如果不是,它將返回false,並且框架將忽略該特定請求的格式化程序。
最後,這裏是實際的實現。我們需要做的反射這裏的一些工作,以獲得屬性名稱和值出這是一類對象的值參數:
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());
}
我們完成了一部分。現在,我們需要利用這一點。我註冊了這個格式與Global.asax中的Application_Start方法中下面的代碼管道:
GlobalConfiguration.Configuration.Formatters.Add(
new CSVMediaTypeFormatter(
new QueryStringMapping("format", "csv", "text/csv")
)
);
在我的示例應用程序,當你瀏覽到/ API /汽車格式= CSV,它可以把你一個CSV文件?但沒有擴展。繼續並添加csv擴展。然後,用Excel打開它,你應該看到類似如下的東西:
一千個祝福你的先生。 – gorillapower 2017-02-21 10:33:39