Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc Web Api Pdf下载和路由_Asp.net Mvc_Asp.net Mvc 4_Asp.net Web Api_Asp.net Web Api2 - Fatal编程技术网

Asp.net mvc Web Api Pdf下载和路由

Asp.net mvc Web Api Pdf下载和路由,asp.net-mvc,asp.net-mvc-4,asp.net-web-api,asp.net-web-api2,Asp.net Mvc,Asp.net Mvc 4,Asp.net Web Api,Asp.net Web Api2,所以我试图精简web Api并在我的项目中实现 有两件事我不太确定 我正在尝试下载pdf。我的web api在App Server中,我正在web服务器中使用它 在我的web api中,我在控制器中有一个方法 public class FilesController : ApiController { [ActionName("GetFile")] public HttpResponseMessage GetFile(string FileName, string

所以我试图精简web Api并在我的项目中实现

有两件事我不太确定

  • 我正在尝试下载pdf。我的web api在App Server中,我正在web服务器中使用它
  • 在我的web api中,我在控制器中有一个方法

    public class FilesController : ApiController
    {        
        [ActionName("GetFile")]
        public HttpResponseMessage GetFile(string FileName, string CEQRNumber, string LatestMileStone)
        {
            var file = GetListofFilesByCEQRAndMilestone(FileName, CEQRNumber, LatestMileStone);
            var path = file.FilePath;
            var extension = file.FileExtention;
            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            var stream = new FileStream(path, FileMode.Open,FileAccess.ReadWrite);
            result.Content = new StreamContent(stream);
    
            if (extension == ".pdf")
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
    
            if (extension == ".xlsx" || extension == ".xls")
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    
            if (extension == ".zip")
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("aapplication/zip");
    
            return result;
        }
    }
    
    现在我不知道如何消费它。在我的web服务器主mvc应用程序中。我有一个行动方法

    public ActionResult GetFile(string fileName, string ceqrNum, string latestMS, string token)
    {
        string url = "https://xxx/api/Files/GetFile/" + fileName + "/" + ceqrNum + "/" + latestMS;
    
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/pdf"));
    
                Task<String> response = client.GetStringAsync(url);
    
                // NOT SURE HOW TO CONVERT RESPONSE TO PDF
    
            }
    }
    
    我注意到,如果我必须有不同的参数,我必须在配置中添加这些参数

    所以我补充说

    config.Routes.MapHttpRoute(
                name: "GetFileList",
                routeTemplate: "api/{controller}/{action}/{CEQRNumber}/{LatestMileStone}",
                defaults: new
                {
                    CEQRNumber = UrlParameter.Optional,
                    LatestMileStone = UrlParameter.Optional,
                }
            );
    
            config.Routes.MapHttpRoute(
                name: "GetFileForDownload",
                routeTemplate: "api/{controller}/{action}/{FileName}/{CEQRNumber}/{LatestMileStone}",
                defaults: new
                {
                    Controller = "Files",
                    FileName = UrlParameter.Optional,
                    CEQRNumber = UrlParameter.Optional,
                    LatestMileStone = UrlParameter.Optional
                }
            );
    
    现在,我可以有一个默认路由,无论参数和动作名称如何,也不管我必须编写新路由的每个不同动作和参数如何

    我将感谢你的回答。我试图理解WebAPI的概念,因为这是我第一次使用它

    谢谢你的评论-

  • 不要以读/写方式打开文件,读已经足够好了

  • 第二条路线很好。您不需要第一条路线,也可以直接发布到以下路线:

  • api/{controller}/{FileName}/{CEQRNumber}/{LatestMileStone}

    并从GetFiles中删除
    [ActionName]
    属性

    更简单的是,您可以使用以下路线
    api/{controller}
    并将参数作为查询字符串传递

    所以看起来是这样的

    config.Routes.MapHttpRoute(
        routeTemplate: "api/{controller}"
    );
    
    您的url将如下所示:

    http://xxx/api/Files?FileName=foo&CEQRNumber=bar,&LatestMileStone
    
    控制器代码:

    public class FilesController : ApiController
    {        
        public HttpResponseMessage GetFile(string FileName, string CEQRNumber, string LatestMileStone)
        {
            var file = GetListofFilesByCEQRAndMilestone(FileName, CEQRNumber, LatestMileStone);
            var path = file.FilePath;
            var extension = file.FileExtention;
            var result = new HttpResponseMessage(HttpStatusCode.OK);
            var stream = new FileStream(path, FileMode.Open,FileAccess.Read);
            result.Content = new StreamContent(stream);
    
            // do the header work
            return result;
        }
    }
    
    对于客户端代码,而不是ReadAsStringAsync,请使用

     using (Stream responseStream = await response.Content.ReadAsStreamAsync())
     {
         // Read response stream
         await ReadResponseStreamAsync(responseStream, fileName);
     }
    
    别忘了在客户端验证响应代码

    有关如何从流中保存文件的注释,请参见:

     private void ReadResponseStreamAsync(stream responseStream, string fileName)
     {
          using (var fileStream = File.Create("C:\\Path\\To\\" + fileName))
          {
                responseStream.CopyTo(fileStream);
          }
     }
    

    我想知道客户端代码是什么样子的。我已经有了api控制器方法,它可以完美地工作。你能详细说明一下客户将如何工作吗。很抱歉,如果我不清楚我想知道的第二个问题,我是否必须根据不同操作中的不同参数更改或添加config.Routes.MapHttpRoute中的值。基本上,我在上一个代码部分中编写的内容会为您提供一个响应流。获取该流并将其写入一个文件,或者任何想要将其写入的存储。最后我添加了一个小示例。谈到路由,我的观点是您不必添加额外的路由,而是使用查询参数。这是你想要避免的吗?提供每个方法路由参数的替代方法只是使用属性路由。看见这里还有一个链接,指向大量突出显示了属性路由的WebApi示例:我并没有试图避免使用查询参数。只是当我使用查询参数时,我总是会得到一个带有“?”和“&”的错误。我不记得有什么错误,但这就像查询字符串中的“?”和“&”被认为是一种威胁。这确实是另一个问题的主题:)要快速启动,请等待异步任务方法的结果(如果您自己使用的是异步方法)
    等待您的异步方法
    或者如果您使用的是同步方法您的异步方法()。结果。如果你不得不使用.Result,那么你的代码设置就会出现问题。以下是一个链接:
     private void ReadResponseStreamAsync(stream responseStream, string fileName)
     {
          using (var fileStream = File.Create("C:\\Path\\To\\" + fileName))
          {
                responseStream.CopyTo(fileStream);
          }
     }