Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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# 通过POST httprequest将文件传输到hololens(错误429)_C#_.net_Httprequest_Hololens - Fatal编程技术网

C# 通过POST httprequest将文件传输到hololens(错误429)

C# 通过POST httprequest将文件传输到hololens(错误429),c#,.net,httprequest,hololens,C#,.net,Httprequest,Hololens,我使用桌面应用程序通过httprequest与hololens眼镜进行通信(hololens通过USB连接),尤其是我想读写文件。为此,我使用以下代码: class BuildDeployPortal { // Consts public static readonly string API_FileQuery = @"http://{0}/api/filesystem/apps/file"; // Classes & Structs public st

我使用桌面应用程序通过httprequest与hololens眼镜进行通信(hololens通过USB连接),尤其是我想读写文件。为此,我使用以下代码:

class BuildDeployPortal
{
    // Consts
    public static readonly string API_FileQuery = @"http://{0}/api/filesystem/apps/file";

    // Classes & Structs
    public struct ConnectInfo
    {
        public ConnectInfo(string ip, string user, string password)
        {
            IP = ip;
            User = user;
            Password = password;
        }

        public string IP;
        public string User;
        public string Password;
    }

    public async static void GetFile(ConnectInfo connectInfo, string knownfolderid, string filename, string packagefullname, string path)
    {
        try
        {
            // Query
            string query = string.Format(API_FileQuery, connectInfo.IP);
            query += "?knownfolderid=" + Uri.EscapeUriString(knownfolderid);
            query += "&filename=" + Uri.EscapeUriString(filename);
            query += "&packagefullname=" + Uri.EscapeUriString(packagefullname);
            query += "&path=" + Uri.EscapeUriString(path);

            // Create http request
            var httpRequest = new HttpClient();

            httpRequest.DefaultRequestHeaders.Clear();
            httpRequest.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic",
                                                                                        EncodeTo64(connectInfo.User + ":" + connectInfo.Password));

            HttpResponseMessage resp = await httpRequest.GetAsync(query);

            byte[] responseMessage = await resp.Content.ReadAsByteArrayAsync();

        }
        catch (Exception ex)
        {
            //log some problems
        }

    }



    public async static void UploadFile(ConnectInfo connectInfo, string knownfolderid, string packagefullname, string path, string filePath)
    {
        try
        {
            // Query
            string query = string.Format(API_FileQuery, connectInfo.IP);
            query += "?knownfolderid=" + Uri.EscapeUriString(knownfolderid);
            query += "&packagefullname=" + Uri.EscapeUriString(packagefullname);
            query += "&path=" + Uri.EscapeUriString(path);

            //  Create http request
            var httpRequest = new HttpClient();

            httpRequest.DefaultRequestHeaders.Clear();
            httpRequest.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic",
                                                                                        EncodeTo64(connectInfo.User + ":" + connectInfo.Password));
            byte[] data = File.ReadAllBytes(filePath);
            ByteArrayContent byteContent = new ByteArrayContent(data);

            HttpResponseMessage resp = await httpRequest.PostAsync(query, byteContent);

            var responseMessage = await resp.Content.ReadAsStringAsync();

        }
        catch (Exception ex)
        {
            //log some problems
        }

    }


    // Helpers
    private static string EncodeTo64(string toEncode)
    {
        byte[] toEncodeAsBytes = Encoding.ASCII.GetBytes(toEncode);
        string returnValue = Convert.ToBase64String(toEncodeAsBytes);
        return returnValue;
    }
}
要运行它,我打电话给

BuildDeployPortal.ConnectInfo co = new BuildDeployPortal.ConnectInfo("127.0.0.1:10080", "user", "pass");

//get file
BuildDeployPortal.GetFile(co, "LocalAppData", "2017-01-25-09-04-21_TestFile.csv", "app_full_package_name", "\\LocalState");

//upload file
BuildDeployPortal.UploadFile(co, "LocalAppData", "app_full_package_name", "\\LocalState",
            "C:\\Users\\myuser\\Desktop\\info.json");
GetFile方法工作正常,并为我提供了所需的文件,但UploadFile方法为我提供了以下响应:StatusCode:429,ReasonPhase:“请求太多”。如果在执行期间只运行其中一个,则结果相同

我真的不明白为什么我会有这个错误,我只是发送了一个请求(或者我遗漏了什么)

有关信息,可以找到RESTAPI定义


谢谢

我没有真正回答我的问题(为什么会出现这个错误429),但我给出了一个上传文件的替代解决方案

我下载以获取WindowsDevicePortalWrapper库。 然后我调用以下代码来上传文件:

IDevicePortalConnection connection = new DefaultDevicePortalConnection("http://127.0.0.1:10080", "user", "password");
DevicePortal dp = new DevicePortal(connection);
//write file
await dp.UploadFileAsync("LocalAppData", "C:\\Users\\ng1dd32\\Desktop\\info.json", "\\LocalState", "Lexington_1.0.0.0_x86__ph1m9x8skttmg");
调试问题 问题是Chrome 62发送了一个空的
内容类型
标题,而Chrome 61则将
内容类型
标题作为
多部分/表单数据
正确发送

原因是微软自己的FileExplorer.js代码调用了
jQuery.ajax(…)
contentType:“
,因此浏览器只能解释一个空字符串

摘自FileExplorer.js

$.ajax({url:"/api/filesystem/apps/file?"+$.param(r),cache:!1,contentType:"",processData:!1,data:n,type:"post"}).done(...)
无法指定任何请求头,也无法指定请求正文,因此没有用于确定正确的头和正文集的规范

FWIW,Microsoft自己的始终发送内容类型标题:

string contentType = string.Format("multipart/form-data; boundary={0}", boundaryString);
解决方案 我已经创建了一个bookmarklet,它可以在设备门户的FileExplorer页面上正确上传文件

扩展版 可复制的小型bookmarklet版本(也适用于inspector/debugger控制台)
(我为Hololens开发了一年多,在我的每台电脑分别升级到Chrome 62时发现了这一点。)

我得到了同样的东西。我已经在HoloLens论坛上重复了这个代码/问题:-但也没有看到回复。我真的很希望这个问题能得到解决。哎呀,我看这也是你的帖子。我有一个比这个稍早一点的,没有回应。如果你得到答案,请把它贴在这里谢谢。抱歉,丹,我没有答案,只有一个选择…这是正确的-这已经在设备门户的更高版本中修复,但全息镜头尚未进行更新。为了避免这种情况,您可以使用尚未更新的IE,它将发送一个“正确”编码的请求。如果有帮助解决此问题的文档,请告诉我,我会在MSDN上编辑这些文档。@HirschSinghal感谢您的确认和内部信息。最好让REST API文档声明
POST
to
/API/filesystem/apps/file
需要
多部分/表单数据的
ContentType
头,并且需要这样发送有效负载。(也可能需要一个查询参数?)此外,对空
ContentType
头响应429个太多请求的API可以替换为更合适的状态代码,例如400个错误请求或412个前置条件失败。@HirschSinghal不幸,Edge将XHR调用解释为与Chrome和Firefox相同,并且不更正空字符串中的内容类型。我在我的解决方案中添加了一个bookmarklet,它可以在Chrome上工作,并且可以跨浏览器工作。编辑:如果设备门户支持JSONP就太好了,那么我可能已经能够使用其他解决方法了。FileExplorer.js中的所有对象实例和方法都是在闭包中创建的,所以我不能对其进行修补。而且,由于CSRF令牌位于cookie/头中,加上设备门户RESTAPI不支持CORS,CORS也被淘汰了。
(function(jQuery) {
var pathLinkData = jQuery(".pathLink:last-child").data(),
    path = pathLinkData.path,
    packagename = pathLinkData.packagename,
    knownfolderid = pathLinkData.knownfolderid,
    url = '/api/filesystem/apps/file?knownfolderid=' + knownfolderid + '&packagefullname=' + packagename + '&path=%5C%5C' + path,
    file_data = jQuery('#fileToUpload')[0].files[0],
    form_data = new FormData();

  form_data.append('file', file_data, file_data.name);

  jQuery.ajax({
    url: url,
    dataType: 'text',
    cache: false,
    contentType: false,
    processData: false,
    data: form_data,
    type: 'POST',
    error: function(xhr, textStatus, error) { console.error(error) },
    success: function(res){
      alert('uploaded');
      console.log(res);
    }
  });
})(jQuery);
javascript:(function(jQuery){var pathLinkData=jQuery('.pathLink:last-child').data(),path=pathLinkData.path,packagename=pathLinkData.packagename,knownfolderid=pathLinkData.knownfolderid,url='/api/filesystem/apps/file?knownfolderid='+knownfolderid+'&packagefullname='+packagename+'&path=%5C%5C'+path,file_data=jQuery('#fileToUpload')[0].files[0],form_data=new FormData();form_data.append('file',file_data,file_data.name);jQuery.ajax({url:url,dataType:'text',cache:false,contentType:false,processData:false,data:form_data,type:'POST',error:function(xhr,textStatus,error){console.error(error)},success:function(res){alert("uploaded");console.log(res);}});})(jQuery);