api控制器的文件下载问题

时间:2015-08-07 22:51:32

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

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应用程序中有上面的代码来下载文件。它工作正常,因为我的控制器继承到Controller。但是当我将此代码移动到Webapi控制器时,它会在返回文件时抛出错误。经过分析,我发现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代码通过角度服务调用此api。这是在下载按钮单击时调用的。 api控制器代码或建议中的任何示例角度代码或帮助都会有所帮助。

3 个答案:

答案 0 :(得分:11)

这是一个更简单的例子:

   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;
        }
    }
   }

答案 1 :(得分:3)

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

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;
}

答案 2 :(得分:2)

考虑到您正在返回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下载文件的这些问题。