我在客户端使用带有角度的WebApi2。 我正在尝试在我的网站中实现导出到excel文件。 我实现了自定义BufferedMediaTypeFormatter。但不幸的是它不起作用。 WriteToStream函数永远不会被调用,尽管CanWriteType函数被调用两次并且两次都返回true。 这是我的代码:
public class FileMediaFormatter : BufferedMediaTypeFormatter
{
public const string SupportedMediaType = "text/html";
public FileMediaFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue(SupportedMediaType));
}
public override bool CanReadType(Type type)
{
return false;
}
public override bool CanWriteType(Type type)
{
if (ExportableResolver.Instance.Value.CanConvert(type))
return true;
if (!type.IsGenericType)
return false;
var arguments = type.GetGenericArguments();
if (arguments.Length != 1)
return false;
var ienumType = typeof(IEnumerable<>).MakeGenericType(arguments[0]);
if (!ienumType.IsAssignableFrom(type))
return false;
return arguments[0].IsClass;
}
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
IEnumerable<object> enumValue;
Type genericType = type;
if (ExportableResolver.Instance.Value.CanConvert(value.GetType()))
{
enumValue = ExportableResolver.Instance.Value.Convert(value);
genericType = enumValue.GetType();
}
else
{
enumValue = (value as IEnumerable<object>);
if (enumValue.Count() > 0)
{
genericType = typeof(List<>).MakeGenericType(enumValue.First().GetType());
}
else
{
// source of baseentity is no important because its just makes an empty file
genericType = typeof(List<>).MakeGenericType(new FileArchive.Domain.Entities.FileProperties().GetType());
}
var a = genericType.Name;
}
if (enumValue == null)
{
base.WriteToStream(type, value, writeStream, content);
return;
}
var list = enumValue as object[] ?? enumValue.ToArray();
var fTypeObj = HttpUtility.ParseQueryString(HttpContext.Current.Request.RawUrl).Get("fType");
if (fTypeObj != null)
{
string fType = fTypeObj.ToString();
var dataTable = DependencyResolver.Current.GetService<IExportXslService>().ConvertToDataTable(list.ToList(), genericType.GetGenericArguments()[0]);
DependencyResolver.Current.GetService<IExportXslService>().WriteDataTableToStream(dataTable, string.Format("{0}", genericType.GetGenericArguments()[0].Name), writeStream, string.Empty);
}
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
if (CanWriteType(type))
{
string typeName = ExportableResolver.Instance.Value.CanConvert(type)
? type.Name
: type.GetGenericArguments()[0].Name;
//if object (its for the complex type tbls) then give the assembly name
typeName = typeName == "Object" ? System.Reflection.Assembly.GetExecutingAssembly().GetName().Name : typeName;
//string tempFileName = GetHebrewFileName(typeName);
//if (!string.IsNullOrEmpty(tempFileName))
// typeName = tempFileName;
headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = string.Format("{0}_{1:yyyyMMddHHmmss}.xlsx", typeName, DateTime.Now) };
var fTypeObj = HttpUtility.ParseQueryString(HttpContext.Current.Request.RawUrl).Get("fType");
if (fTypeObj != null)
{
string fType = fTypeObj.ToString();
if (fType == "excel")
{
headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = string.Format("{0}_{1:yyyyMMddHHmmss}.xlsx", typeName, DateTime.Now) };
}
else if (fType == "text")
{
headers.ContentType = new MediaTypeHeaderValue("text/plain");
headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = string.Format("{0}_{1:yyyyMMddHHmmss}.txt", typeName, DateTime.Now) };
}
return;
}
}
base.SetDefaultContentHeaders(type, headers, mediaType);
}
}
在WebApiConifg注册函数中我添加了:
config.Formatters.Insert(0,new FileMediaFormatter());
我错过了什么?
答案 0 :(得分:0)
万一有人遇到这个问题,我会遇到这个问题,而我的问题是,尽管我的格式化程序能够对CanWriteType(myCustomType)做出“真”响应,但在最后一场比赛结束时却无法应对。
最后的“让它完成”调用基于“ ObjectContent”,这是一个错误响应,导致回退到标准Json格式化程序:因此从未调用过我的WriteStream(...)。
解决方案是确保格式化程序可以处理ObjectContent。