将文件从Win32 C ++程序上传到OneDrive(SkyDrive)

时间:2014-04-29 15:07:52

标签: c++ rest winapi file-upload onedrive

我正在使用Visual Studio 2013(在Windows 8.1 Pro上)基于Cordova Windows 7编写用于将文件上载到OneDrive的程序。

虽然通过POST方法传输文件可以做,但是错误" request_method_invalid:HTTP方法' POST'不允许使用此资源。"回报。

根据official document,编写的可以使用POST方法上传。如果这是对的,那么这段代码哪里出错了?

* picojson是一个开源JSON解析器。

wstring filePath = L"C:\\..\\test.jpg";
wstring dest = L"https://apis.live.net/v5.0/me/skydrive/files/test.jpg";


file = CreateFile(filePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto out;
}
file_size.LowPart = GetFileSize(file, &file_size.HighPart);

inet = InternetOpen(L"Cordova", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!inet) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto out;
}

// 1- Headers
buf = new BYTE[CHUNK_SIZE];
ws = L"Content-Type: multipart/form-data; boundary=" + BOUNDARY;
if (!HttpAddRequestHeaders(req, ws.c_str(), ws.size(), HTTP_ADDREQ_FLAG_ADD)) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto end_req;
}
for (picojson::object::iterator i = headers.begin(); i != headers.end(); i++){
    if (i->second.is<wstring>() == false) continue;
    ws = i->first + L": " + i->second.get<wstring>(); // Authorization: Bearer (access_token)
    if (!HttpAddRequestHeaders(req, ws.c_str(), ws.size(), HTTP_ADDREQ_FLAG_ADD)) {
        SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
        goto out;
    }
}

// 2- Contents
// 2.1 Contents headers
ws = L"";
for (picojson::object::iterator i = params.begin(); i != params.end(); i++){
    if (i->second.is<wstring>() == false) continue;
    ws += L"--" + BOUNDARY + L"\r\n";
        + L"Content-Disposition: form-data; name=\"" + i->first + L"\";\r\n\r\n"
        + i->second.get<wstring>() + L"\r\n";
}
ws += L"--" + BOUNDARY + L"\r\n"
    + L"Content-Disposition: form-data; name=\"" + fileKey + L"\"; filename=\"" + fileName + L"\"\r\n"
    + L"Content-Type: " + mimeType + L"\r\n\r\n";


int utf8_len = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, NULL, 0, NULL, NULL);
utf8_text = new char[utf8_len + 10];
if (!WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), utf8_text, utf8_len + 10, NULL, NULL)) {
    SendErrorMessage(data, CONNECTION_ERR, filePath, dest);
    goto end_req;
}

2 个答案:

答案 0 :(得分:2)

也就是说,使用PUT进行文件上传实际上要容易得多。在这种情况下,您在上面指定的路径是正确的(即文件名属于路径),您可以按原样将文件内容写入响应主体。

答案 1 :(得分:1)

如果要通过POST进行上传,则目标位置应该是多部分正文中具有文件名的父文件夹。来自example

POST https://apis.live.net/v5.0/me/skydrive/files?access_token=ACCESS_TOKEN

Content-Type: multipart/form-data; boundary=A300x

--A300x
Content-Disposition: form-data; name="file"; filename="HelloWorld.txt"
Content-Type: application/octet-stream

Hello, World!
--A300x--