简体   繁体   English

使用Wininet上传文件时如何添加正确的Content-Type? (HTTP PUT)

[英]How to add correct Content-Type when uploading file with Wininet? (HTTP PUT)

I am uploading a file with Wininet to a Sharepoint server with HTTP PUT. 我正在使用Wininet将文件上传到使用HTTP PUT的Sharepoint服务器。 However, even when I specify a file name with .xlsx extension, I got on the Sharepoint server a file which says it's named .xlsx , but when downloading it, it gets a .zip extension. 但是,即使指定扩展名为.xlsx的文件名,我在Sharepoint服务器上也得到了一个名为.xlsx的文件,但下载时却获得了.zip扩展名。 Also, on Sharepoint, the file does not get the little Excel icon next to it, but a more generic icon. 另外,在Sharepoint上,该文件旁边没有显示Excel小图标,而是一个更通用的图标。 I have tried every combination of setting the Content-type ("mime-type") with HttpAddRequestHeaders and at HttpSendRequest I could come up with. 我尝试了将Content-type(“ mime-type”)与HttpAddRequestHeaders一起设置的所有组合,并且在HttpSendRequest上可以提出。

The code below uploads the file, but Sharepoint gets the content-type wrong: 下面的代码上传了文件,但是Sharepoint的内容类型错误:

static int upload_file_to_sharepoint(LPCSTR filename, LPCSTR server, LPCSTR location)
{
    HINTERNET hIntrn = InternetOpenA(
        "magic", 
         INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
         NULL,
         NULL,
         0
    );
    if (!hIntrn)
        return printf("No Internet connection: %li.\n", GetLastError());

    HINTERNET hConn = InternetConnectA(
        hIntrn, 
        server,
        INTERNET_DEFAULT_HTTPS_PORT,
        NULL,
        NULL,
        INTERNET_SERVICE_HTTP,
        0,
        NULL
    );

    if (!hConn)
        return printf("Connection to update server failed: %li.\n", GetLastError());

    DWORD dwOpenRequestFlags =
        INTERNET_FLAG_KEEP_CONNECTION |
        INTERNET_FLAG_NO_COOKIES |
        INTERNET_FLAG_NO_CACHE_WRITE |
        INTERNET_FLAG_NO_UI |
        INTERNET_FLAG_RELOAD;

    PCSTR rgpszAcceptTypes[] = {
        "text/*",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        NULL
    };

    HINTERNET hReq = HttpOpenRequestA(
        hConn,
        "PUT",
        location,
        "HTTP/1.1",
        NULL,
        rgpszAcceptTypes,
        dwOpenRequestFlags,
        NULL
    );


    HANDLE hFile = CreateFileA(
        filename,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (NULL == hFile) {
        ExitProcess(1);
    }

    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (NULL == hMap) {
        ExitProcess(1);
    }

    LPVOID lpvFile = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);

    DWORD dwFileSize = GetFileSize(hFile, NULL);

    CHAR mimetype[1024];
    sprintf(
        mimetype,
        "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    //"Content-Type: application/vnd.ms-excel\r\n"
    );

    if (!HttpAddRequestHeadersA(hReq, mimetype, -1, HTTP_ADDREQ_FLAG_REPLACE)) {
        printf("Failed adding mime header\n");
    }

    if (!HttpSendRequestA(
        hReq,
        NULL,// "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        0, //-1,
        lpvFile,
        dwFileSize)) {
        printf("HttpSendRequest failed: %li.\n", GetLastError());
    }

    UnmapViewOfFile(lpvFile);
    CloseHandle(hMap);
    CloseHandle(hFile);

    printf("Uploaded file to http://%s%s\n", server, location);

    return 0;
}

I captured the headers with Fiddler, got this: 我用Fiddler捕获了标题,得到了:

PUT http://x.com/CENSORED/a.xslx HTTP/1.1
Accept: text/*, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: attachment; filename="a.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
User-Agent: magic
Host: censored
Content-Length: 772303
Connection: Keep-Alive
Pragma: no-cache


HTTP/1.1 200 OK
Cache-Control: private,max-age=0
Content-Length: 0
Expires: Tue, 15 Sep 2015 08:43:16 GMT
Last-Modified: Wed, 30 Sep 2015 08:43:16 GMT
ETag: "{0DC262D0-83AE-489A-90CD-EB23B284A3B3},14"
Server: Microsoft-IIS/7.5
SPRequestGuid: 6aba173e-41db-4b14-b7df-7714c54db282
X-SharePointHealthScore: 0
ResourceTag: rt:0DC262D0-83AE-489A-90CD-EB23B284A3B3@00000000014
Public-Extension: http://schemas.microsoft.com/repl-2
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.7145
X-MS-InvokeApp: 1; RequireReadOnly
ServerName: Xcensored
Date: Wed, 30 Sep 2015 08:43:16 GMT

So, it helps if you upload the file as .xlsx instead of .xslx ... 因此,如果您将文件上传为.xlsx而不是.xslx ,则会有所帮助...

The code works now and looks something like this, no special headers necessary, which is consistent with other examples I have found on the web: 该代码现在可以正常工作,看起来像这样,不需要特殊的标头,这与我在网上找到的其他示例是一致的:

static int upload_file_to_sharepoint(LPCSTR filename, LPCSTR server, LPCSTR location)
{
    HINTERNET hIntrn = InternetOpenA(
        "magic", 
         INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
         NULL,
         NULL,
         0
    );
    if (!hIntrn)
        return printf("No Internet connection: %li.\n", GetLastError());

    HINTERNET hConn = InternetConnectA(
        hIntrn, 
        server,
        INTERNET_DEFAULT_HTTPS_PORT,
        NULL,
        NULL,
        INTERNET_SERVICE_HTTP,
        0,
        NULL
    );

    if (!hConn)
        return printf("Connection to update server failed: %li.\n", GetLastError());

    DWORD dwOpenRequestFlags =
        INTERNET_FLAG_KEEP_CONNECTION |
        INTERNET_FLAG_NO_COOKIES |
        INTERNET_FLAG_NO_CACHE_WRITE |
        INTERNET_FLAG_NO_UI |
        INTERNET_FLAG_RELOAD;

    HINTERNET hReq = HttpOpenRequestA(
        hConn,
        "PUT",
        location,
        "HTTP/1.1",
        NULL,
        NULL,
        dwOpenRequestFlags,
        NULL
    );


    HANDLE hFile = CreateFileA(
        filename,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (NULL == hFile) {
        ExitProcess(1);
    }

    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (NULL == hMap) {
        ExitProcess(1);
    }

    LPVOID lpvFile = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);

    DWORD dwFileSize = GetFileSize(hFile, NULL);    

    if (!HttpSendRequestA(
        hReq,
        NULL,
        0,
        lpvFile,
        dwFileSize)) {
        printf("HttpSendRequest failed: %li.\n", GetLastError());
    }

    UnmapViewOfFile(lpvFile);
    CloseHandle(hMap);
    CloseHandle(hFile);

    printf("Uploaded file to http://%s%s\n", server, location);

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM