【问题标题】:File download issue with api controllerapi控制器的文件下载问题
【发布时间】:2015-10-31 11:43:46
【问题描述】:
public class DefaultController : Controller
{
    // GET: Default
    public ActionResult Index()
    {
        return Download();
    }

    public FileResult Download()
    {
        string xmlString = "my test xml data";
        string fileName = "test" + ".xml";
        return File(Encoding.UTF8.GetBytes(xmlString), "application/xml", fileName);
    }
}

我在 asp.net mvc 应用程序中有上面的代码来下载文件。它工作正常,因为我的控制器被继承到控制器。但是当我将此代码移动到 Webapi 控制器时,它会在返回 File 时引发错误。经过分析我发现我在webapi中的控制器继承了ApiController(system.web.http.api控制器)。我发现 ApiController 中没有 File 类。是否有任何选项可以在 webapi 控制器中实现下载文件功能?

我在 webapi 控制器中尝试了以下替代代码,但一旦我调用它就看不到下载文件。

public HttpResponseMessage DownloadConstructedXmlFile()
        {
            var result = new HttpResponseMessage(HttpStatusCode.OK);
            string xmlContent = "My test xml data";
            //var serializer = new XmlSerializer(typeof(xmlContent));

            var builder = new StringBuilder();
            using (var writer = new StringWriter(builder))
            {
                // serializer.Serialize(writer, xmlContent);
                result.Content = new StringContent(xmlContent, Encoding.UTF8, "application/xml");
                result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = string.Format("test.xml")
                };
               // return result;
            }

            return new HttpResponseMessage();
        }

PS:我正在尝试使用 angularjs 代码通过 angular 服务调用此 api。这是在单击下载按钮时调用的。 api控制器代码或建议中的任何示例角度代码或帮助都会有所帮助。

【问题讨论】:

标签: c# asp.net-mvc angularjs asp.net-web-api


【解决方案1】:

这是一个更简单的例子:

   using System.Net;
   using System.Net.Http;
   using System.Net.Http.Headers;
   using System.Text;
   using System.Web.Http;

   namespace WebApplication1.Controllers
   {
    public class ValuesController : ApiController
    {
        // GET: api/Values
        public HttpResponseMessage Get()
        {
            var xmlString = "<xml><name>Some XML</name></xml>";
            var result = Request.CreateResponse(HttpStatusCode.OK);
            result.Content = new StringContent(xmlString, Encoding.UTF8, "application/xml");
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = "test.xml"
            };

            return result;
        }
    }
   }

【讨论】:

  • 其实我没有 text.xml。我正在从 db 获取数据并动态生成 xml 文件。我正在尝试下载该 xml 文件。
  • 感谢您的编辑,我有完整的 xml 作为字符串,我正在尝试下载该 xml 文件。我没有 xml 文件。
  • 对不起,我试图换到另一台电脑来编辑这个,他们需要一个草稿功能
  • 我又做了一次更新,你应该可以在字符串变量中获取xml并立即返回它。
  • 您使用的是 Web API 1 还是 2?我从一个新项目中对此进行了测试,它与 Web API 2 一起正常工作
【解决方案2】:

它认为这样的事情可以解决问题!

public HttpResponseMessage Get(string fileName)
{
    FileStream fileStream = FileProvider.Open(fileName);
    var response = new HttpResponseMessage();
    response.Content = new StreamContent(fileStream);
    response.Content.Headers.ContentDisposition 
                      = new ContentDispositionHeaderValue("attachment");
    response.Content.Headers.ContentDisposition.FileName = fileName;
    response.Content.Headers.ContentType
                     = new MediaTypeHeaderValue("application/octet-stream");
    response.Content.Headers.ContentLength 
                     = FileProvider.GetLength(fileName);
    return response;
}

【讨论】:

  • FileProvider 是 ASP.NET Core
【解决方案3】:

考虑到您正在返回 XML,您可以让控制器返回 XDocument

public XDocument returnXMLFile()
{
   var xDoc = XDocument.Load("test.xml");
   return xDoc;
}

然后您需要修改GlobalConfiguration.Configuration.Formatters 返回 XML,或配置您的客户端以将 accept header 设置为 application/xml

配置服务器以通过另一种类型(如 JSON)返回 XML 的一种方法是以下代码:

var xml = new System.Net.Http.Formatting.XmlMediaTypeFormatter();
xml.MediaTypeMappings.Add(new QueryStringMapping("format", "xml", "application/xml"));
GlobalConfiguration.Configuration.Formatters.Add(xml);

然后您可以通过超链接将文件下载为 xml

<a href="[pathToController]/returnxmlfile?format=xml" >Download XML</a>

要自定义,请查看这些有关使用 Angular js 下载文件的问题。

【讨论】:

  • 我正在尝试从 db 获取数据,构建 xml,然后通过 angular js 单击按钮将 xml 作为文件下载到本地系统。
  • @Chandana 控制器方法的返回类型可以是任何类型,框架会为你构建xml。
  • 非常感谢您的帮助和时间麦克。 Jonahan 的回答符合我的要求,但您的回答对许多与我类似情况感到震惊的人也很有用。
猜你喜欢
  • 2012-12-25
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
相关资源
最近更新 更多