积极答复者
(C++/CX) 使用HTTP/1.1 POST上傳檔案至 C# Web Service

问题
-
C# Web Service Function is declared as:
public UploadFile(byte[] file, string FileName)
The test form says the request should take this form:
POST address_of_service HTTP/1.1Host: <host>Content-Type: application/x-www-form-urlencodedContent-Length: length file= string& file= string& FileName= string
How do I get my binary file data into that form? I've tried just converting the file data to a string and putting it in the body (
file=<string_data>
) but I get HTTP 500 errors back, complaining about cannot convert < string_data> to System.Byte. I've got HTTP POST working fine elsewhere in my application with plain string parameters.Also, out of curiosity, why is it showing the file parameter twice?
答案
-
Hi waterrock,
对于测试页面上的两个file必须是string的说法还是看不懂,以前没有遇到过这么写的API说明文档,既然是file怎么会固定成string格式,不过你可以尝试直接把file=byte[]这个直接上传看看可行否。
关于在C++/CX中使用web service这个问题,有几个解决办法:
1,使用C++ REST SDK协助: C++ REST SDK (Codename "Casablanca")
2,参考一下这个文档:Connecting to networks and web services
希望能帮到你吧。
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.- 已标记为答案 Jamles HezModerator 2014年4月25日 10:00
-
或者还有一个办法,你建立一个C#的项目,包含Web Service通信,然后再C++项目中引用。
具体可以参考:Creating Windows Runtime Components in C# and Visual Basic
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.- 已标记为答案 Jamles HezModerator 2014年4月25日 10:00
全部回复
-
Hi waterrock,
目前我不知道你C#代码中是具体怎么上传的,不过看样子你可以添加HttpClient的Header属性。你能提供更多的信息么?
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later. -
Hi James,
server端的部分是由另外的單位用c#開發,因此我只有url位址。
client端我是用c++/cx,c++不像c#有Add Service Reference可以使用。
所以我選擇用http post的方式,參考官網的範例HttpClient Sample
http://code.msdn.microsoft.com/windowsapps/HttpClient-sample-55700664
測試頁上的說明是這樣
POST address_of_service HTTP/1.1
Host: <host>
Content-Type: application/x-www-form-urlencoded
Content-Length: length
file= string& file= string& FileName= string
所以我把HttpClient Sample的Content-Type改為application/x-www-form-urlencoded
task<wstring> HttpRequest::PostAsync(Uri^ uri, const wstring& body, cancellation_token cancellationToken)
{
int length = 0;
ComPtr<IStream> postStream;
CreateMemoryStream(&postStream);
if (body.length() > 0)
{
// Get the required buffer size.
int size = WideCharToMultiByte(CP_UTF8, // UTF-8
0, // Conversion type
body.c_str(), // Unicode string to convert
static_cast<int>(body.length()), // Size
nullptr, // Output buffer
0, // Output buffer size
nullptr,
nullptr);
CheckHResult((size != 0) ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
std::unique_ptr<char[]> tempData(new char[size]);
length = WideCharToMultiByte(CP_UTF8, // UTF-8
0, // Conversion type
body.c_str(), // Unicode string to convert
static_cast<int>(body.length()), // Size
tempData.get(), // Output buffer
size, // Output buffer size
nullptr,
nullptr);
CheckHResult((length != 0) ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
CheckHResult(postStream->Write(tempData.get(), length, nullptr));
}
return DownloadAsync(L"POST",
uri->AbsoluteUri->Data(),
cancellationToken,
L"application/x-www-form-urlencoded",
postStream.Get(),
length);
}在c++/cx中,不知道如何把byte轉成string的型式以post傳遞出去?
Thanks
-
Hi waterrock,
关于怎么把byte[]转化成string应该不是难事,下面的是C#代码,不过改写成C++应该也不难,参考DataReader class:
DataReader dataReader = Windows.Storage.Streams.DataReader.FromBuffer(buffer); string text = dataReader.ReadString(buffer.Length);
不过同样还有一个问题在于你为什么会有两个file = xxx存在,毕竟你服务器只接受一个file,那第二个file所带的内容岂不是丢失了?
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later. -
使用DataReader 把byte[] 轉成string 出現的錯誤訊息:
============================================================================
First-chance exception at 0x767C4B32 in DentalPageApp.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x0370C2E4. HRESULT:0x80070459 在多位元組的目的字碼頁中,沒有這個 Unicode 字元可以對應到的字元。
WinRT information: 在多位元組的目的字碼頁中,沒有這個 Unicode 字元可以對應到的字元。
============================================================================
關於post時為什麼會出現兩個file=string 的變數存在,我也不是很清楚,我是看測試頁上的使用說明。
因為在c#中以Add Service Reference加進來的UploadFile Function 是只有一個byte[] file 變數。
還是有什麼其他方式,可以在跨平台的情況上傳檔案??
Thanks
-
可以预料到这个错误,因为你的byte[]可能并不是从string转化而来,如果说这个byte[]从image转化来的话,那根本没法转化成string,强制转化就会有这个错误产生。我建议你去联系一下编写server的人员,问一下string到底是怎么回事。
不过你第一个帖子的一句话说server端接收数据的API为这个,那么是可以接受byte[]的啊,为什么还要转化为string呢。
public UploadFile(byte[] file, string FileName)
至于其他方式来跨平台传文件,要么就是WCF,要么就是socket,没有其他方式了。
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later. -
Hi waterrock,
对于测试页面上的两个file必须是string的说法还是看不懂,以前没有遇到过这么写的API说明文档,既然是file怎么会固定成string格式,不过你可以尝试直接把file=byte[]这个直接上传看看可行否。
关于在C++/CX中使用web service这个问题,有几个解决办法:
1,使用C++ REST SDK协助: C++ REST SDK (Codename "Casablanca")
2,参考一下这个文档:Connecting to networks and web services
希望能帮到你吧。
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.- 已标记为答案 Jamles HezModerator 2014年4月25日 10:00
-
或者还有一个办法,你建立一个C#的项目,包含Web Service通信,然后再C++项目中引用。
具体可以参考:Creating Windows Runtime Components in C# and Visual Basic
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.- 已标记为答案 Jamles HezModerator 2014年4月25日 10:00