Пользовательский WebApi BufferedMediaTypeFormatter WriteToStream никогда не вызывается - PullRequest
0 голосов
/ 17 мая 2018

Я использую WebApi2 с angular на моем клиенте. Я пытаюсь реализовать экспорт в файл 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());

Что мне не хватает, пожалуйста?

...