Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.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
C# 试图通过C编写文件下载的Web服务器端实现,其中消息体是文件内容_C#_Asp.net_Asp.net Web Api_Asp.net Web Api2 - Fatal编程技术网

C# 试图通过C编写文件下载的Web服务器端实现,其中消息体是文件内容

C# 试图通过C编写文件下载的Web服务器端实现,其中消息体是文件内容,c#,asp.net,asp.net-web-api,asp.net-web-api2,C#,Asp.net,Asp.net Web Api,Asp.net Web Api2,我的问题/挑战非常类似于几个不同的堆栈溢出帖子,但我已经详细阅读了它们,并且仍然在努力让最基本的应用程序正常工作。具体地说,我相信并且都非常接近我想要实现的目标 为了给您提供上下文,我正在尝试编写/存根一个简单的固件OTA(无线)服务器。我最初的目标似乎很简单,但我花了很多时间,几乎没有任何进展。我想提供一个可以从浏览器(以及最终在IoT设备上运行的一些固件)点击的URL,该URL将接收一些参数(通过URL参数或通过标题)。如果固件更新可用,则调用应返回一个文件作为响应主体;如果当前没有可用的更

我的问题/挑战非常类似于几个不同的堆栈溢出帖子,但我已经详细阅读了它们,并且仍然在努力让最基本的应用程序正常工作。具体地说,我相信并且都非常接近我想要实现的目标

为了给您提供上下文,我正在尝试编写/存根一个简单的固件OTA(无线)服务器。我最初的目标似乎很简单,但我花了很多时间,几乎没有任何进展。我想提供一个可以从浏览器(以及最终在IoT设备上运行的一些固件)点击的URL,该URL将接收一些参数(通过URL参数或通过标题)。如果固件更新可用,则调用应返回一个文件作为响应主体;如果当前没有可用的更新,则调用应返回一个合适的HTTP响应代码(或仅返回一个空消息主体)

我在VisualStudio的网站应用程序方面不是很有经验,但在C#方面却很舒服,而且它似乎是一个很好的环境,可以让它快速运行。我对其他实现持开放态度,但我认为编写控制器是最简单的方法。我了解到,这个Web API似乎主要用于.Net到.Net的通信,所以如果有更好的平台,我很高兴被指向更好的方向。以下是我总结的内容(充分利用了上面的链接,因此没有我的功劳!):

}

当我输入URL
http://localhost:2265/api/ota
,我在屏幕上看到以下原始输出:

{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},"content":{"headers":[{"key":"Content-Disposition","value":["attachment; filename=hello-world.bin"]},{"key":"Content-Type","value":["application/octet-stream"]},{"key":"Content-Length","value":["407904"]}]},"statusCode":200,"reasonPhrase":"OK","headers":[],"requestMessage":null,"isSuccessStatusCode":true}
在Fiddler2中捕获的整个响应如下所示:

HTTP/1.1200正常

传输编码:分块

内容类型:application/json;字符集=utf-8

服务器:红隼

X-SourceFiles:=?UTF-8?B?YzpcdXNlcnNcZG91Z2NcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxNVxQcm9qZWN0c1xPdmVyVGhl QWLYQXBXHNYY1XPDMVYVGHLQWLYQXBPXGFWAVxVDGE=?=

X-Powered-By:ASP.NET

日期:2017年2月28日星期二16:43:01 GMT

192

{version:
{“major”:1,“minor”:1,“build”:-1,“revision”:-1,“minorRevision”:-1},“content”:{“headers”:[{“key”:“content Disposition”,“value”:[“attachment;filename=hello world.bin”]},{“content Type”,“value”:[“application/octet stream”]},{“key”:“content Length”,“value”:[“407904”}],“statusCode”:200,“reasonPhrase”:“OK”,“headers”:[],“requestMessage”:null,“isSuccessStatusCode”:true}

0

(如果格式有点难看,很抱歉,我想我还需要一些使用MD进行HTTP响应的教程!)

再一次,我的目标是编写C#代码,返回一个HTTP响应,其中头表示文件是附件,消息体只是文件本身

再次感谢您可能提供的任何帮助/见解


谢谢-道格。

这是我向浏览器发送文件的标准方法。该方法包含两个参数,一个是文件内容,另一个是客户端将接收的默认文件名。请欣赏

    /// <summary>
    /// Sends the fileData to the browser and prompts the visitor to save it with the 
    /// name specified in fileName.
    /// </summary>
    /// <param name="defaultFilename">File name to use when browser prompts visitor (spaces will be replaced with dashes)</param>
    /// <param name="data">Data to be sent to visitor's browser</param>
    /// <param name="errorMsg"></param>
    // Mod 08/04/09 Ron C - Reworked code to work right in modern browsers.
    public static bool DownloadToBrowser(string data, string defaultFilename, out string errorMsg){
        errorMsg = "";
        System.Web.HttpResponse response = HttpContext.Current.Response;

        try {
            defaultFilename = defaultFilename.Replace(' ', '-');        //firefox will cut the name off at the space if there is one, so get rid of 'em
            response.Clear();
            response.ContentType = "application/octet-stream";
            response.AddHeader("Content-Disposition", "attachment; filename=" + defaultFilename);
            //8/5/09 Adding a "Content-Length" header was cutting off part of my file.  Apparently
            //       it would need to factor in the length of the headers as well as the conent.
            //       since I have no easy way to figure out the length of the headers, initially I was gonna
            //       eliminate "Content-Length" header.  Doing so works great in IE 7 and FireFox 3, but not 
            //       in Safari 3 or 4(which doesn't download the file without the "Content-Length" header.  So I
            //       resorted to a cludge of using the header tag and setting it to content length + 1000 for headers.
            //       I'd love to have a better solution, but his one works and I've already wasted 6+ hours to get to this
            //       solution.  Cross broswer downloading of a file shouldn't have to be so hard.  -Ron
            int len = data.Length + 1000;
            response.AddHeader("Content-Length", len.ToString()); //file size for progress dialog
            response.Write(data);
            response.Flush();
            response.Close();       //Close() needed to prevent html from page being streamed back after the file data we sent.

            //Don't use response.End() cause it throws a thread abort exception that can't be caught! Actually you can
            //catch it but then it rethrows after the catch block! (What bozo thought that up?).  I found lots of threads on this.


        } catch (Exception ex) {
            errorMsg = "Unable to download file to browser.";
            //Add code here to log the error in your environment
            return false;
        }
        return true;
    }
//
///将文件数据发送到浏览器,并提示访问者使用
///文件名中指定的名称。
/// 
///浏览器提示访问者时使用的文件名(空格将替换为破折号)
///要发送到访问者浏览器的数据
/// 
//Mod 08/04/09 Ron C-重新编写的代码在现代浏览器中正常工作。
public static bool DownloadToBrowser(字符串数据、字符串defaultFilename、输出字符串errorMsg){
errorMsg=“”;
System.Web.HttpResponse response=HttpContext.Current.response;
试一试{
defaultFilename=defaultFilename.Replace(“”,“-”);//如果有名字,firefox会在空格处删掉它,所以把它们去掉
response.Clear();
response.ContentType=“应用程序/八位字节流”;
response.AddHeader(“内容处置”、“附件;文件名=“+defaultFilename”);
//2009年8月5日添加“内容长度”标题会切断我的部分文件
//它需要考虑头的长度和内容。
//因为我没有简单的方法来计算头球的长度,最初我想
//消除“内容长度”标题。这样做在IE 7和FireFox 3中效果很好,但不是很好
//在Safari3或4中(如果没有“Content Length”头文件,则不会下载文件)
//求助于使用header标记并将其设置为content-length+1000作为标题。
//我很想有一个更好的解决方案,但他的解决方案很有效,我已经浪费了6个多小时来解决这个问题
//解决方案。跨兄弟下载文件不应该这么难。-罗恩
int len=数据长度+1000;
response.AddHeader(“Content Length”,len.ToString());//进度对话框的文件大小
响应。写入(数据);
response.Flush();
response.Close();//需要Close()来防止html页面在我们发送的文件数据之后被流回。
//不要使用response.End(),因为它会抛出一个无法捕获的线程中止异常!实际上您可以
//接住它,但它在接住挡块后会重新旋转!(博佐怎么想的?)。我在这上面发现了很多线。
}捕获(例外情况除外){
errorMsg=“无法将文件下载到浏览器。”;
//在此处添加代码以在您的环境中记录错误
返回false;
}
返回true;
}

Ron先生-感谢您的回复。我感谢您的帮助!您是否建议我将其与我执行的Web Api调用结合使用
    /// <summary>
    /// Sends the fileData to the browser and prompts the visitor to save it with the 
    /// name specified in fileName.
    /// </summary>
    /// <param name="defaultFilename">File name to use when browser prompts visitor (spaces will be replaced with dashes)</param>
    /// <param name="data">Data to be sent to visitor's browser</param>
    /// <param name="errorMsg"></param>
    // Mod 08/04/09 Ron C - Reworked code to work right in modern browsers.
    public static bool DownloadToBrowser(string data, string defaultFilename, out string errorMsg){
        errorMsg = "";
        System.Web.HttpResponse response = HttpContext.Current.Response;

        try {
            defaultFilename = defaultFilename.Replace(' ', '-');        //firefox will cut the name off at the space if there is one, so get rid of 'em
            response.Clear();
            response.ContentType = "application/octet-stream";
            response.AddHeader("Content-Disposition", "attachment; filename=" + defaultFilename);
            //8/5/09 Adding a "Content-Length" header was cutting off part of my file.  Apparently
            //       it would need to factor in the length of the headers as well as the conent.
            //       since I have no easy way to figure out the length of the headers, initially I was gonna
            //       eliminate "Content-Length" header.  Doing so works great in IE 7 and FireFox 3, but not 
            //       in Safari 3 or 4(which doesn't download the file without the "Content-Length" header.  So I
            //       resorted to a cludge of using the header tag and setting it to content length + 1000 for headers.
            //       I'd love to have a better solution, but his one works and I've already wasted 6+ hours to get to this
            //       solution.  Cross broswer downloading of a file shouldn't have to be so hard.  -Ron
            int len = data.Length + 1000;
            response.AddHeader("Content-Length", len.ToString()); //file size for progress dialog
            response.Write(data);
            response.Flush();
            response.Close();       //Close() needed to prevent html from page being streamed back after the file data we sent.

            //Don't use response.End() cause it throws a thread abort exception that can't be caught! Actually you can
            //catch it but then it rethrows after the catch block! (What bozo thought that up?).  I found lots of threads on this.


        } catch (Exception ex) {
            errorMsg = "Unable to download file to browser.";
            //Add code here to log the error in your environment
            return false;
        }
        return true;
    }