I'm using YUI 3 as an uploader control. I've created a WebAPI method that accepts POST transactions from YUI. When the HTML5 uploader is used, all works wonderfully. However, when I force it to Flash for testing, I'm encountering an error in my WebAPI method.
WebAPI
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
await Request.Content.ReadAsMultipartAsync(provider);
int reviewId;
if (!Int32.TryParse(provider.FormData["ReviewId"], out reviewId))
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, new Exception("Invalid Review ID"));
foreach (MultipartFileData file in provider.FileData)
ProcessFile(reviewId, file);
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
}
I'm getting the following error when calling
await Request.Content.ReadAsMultipartAsync(provider):
Unexpected end of MIME multipart stream. MIME multipart message is not complete.
Again, the exact same WebAPI function works when the HTML5 uploader is sending the file so there must be some difference I'm not accounting for. For sake of completeness, here is the HTTP request:
POST http://localhost:11185/api/file HTTP/1.1
Host: localhost:11185
Connection: keep-alive
Content-Length: 7174
Origin: http://localhost:11185
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Content-Type: multipart/form-data; boundary=----------ae0ae0Ij5cH2GI3KM7Ef1Ef1ei4gL6
Accept: */*
Referer: http://localhost:11185/review/449913
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
------------ae0ae0Ij5cH2GI3KM7Ef1Ef1ei4gL6
Content-Disposition: form-data; name="Filename"
576619_334492516619692_690003897_n.jpg
------------ae0ae0Ij5cH2GI3KM7Ef1Ef1ei4gL6
Content-Disposition: form-data; name="ReviewID"
449913
------------ae0ae0Ij5cH2GI3KM7Ef1Ef1ei4gL6
Content-Disposition: form-data; name="Filedata"; filename="576619_334492516619692_690003897_n.jpg"
Content-Type: application/octet-stream
�����JFIF���������*���ICC_PROFILE���lcms��mntrRGB XYZ �����)�9acspAPPL����������������������������������-lcms�����������������������������������������������
desc�������^cprt��\���
wtpt��h���bkpt��|���rXYZ������gXYZ������bXYZ������rTRC������#gTRC������#bTRC������#desc�������c2����������������������������������������������������������������������������������text����FB��XYZ ��������������-XYZ ��������3���XYZ ������o���8����XYZ ������b��������XYZ ������$��������curv������������c�k
�?Q4!�)�2;�FQw]�kpz���|�i�}���0�����C�
%# , #&')*)-0-(0%()(���C
(((((((((((((((((((((((((((((((((((((((((((((((((((��������"�����������������������������������������������������������
�W��w��6����4d�b����h-�暖#�Z9#I
��\���]V��J�\}C��e)�vjC,�m2܈�c��e� $w)������9͑����K!%�LT��]G*N�s
��8�x"����!L�r�3��7*�����SR1���Ch���n�V+�g��Ņc
ֵ^YW�f*���D��H��G����D���Q
��d�Jrkfɩ,��א,�
c��"ķ<�c
��u1XX��6*d.Y�ê��j�)��9]i:Nz�7��ˢ�)H��®���&���U�/�ǭ4��d〬O��9`��ǽ-y(b�j�9�ll�b�Մt]��H��9��K]X���$X�W���H].tw1���4���D�dW����>�҃�s������-8�;�g7l.�����<�m���%=�,���(�D��V$94���*��������!"12 $3A#05�������^VEx�`uK�s��,Sc#�p��c٩[��<I��fxq��+nfe.:t���{v��(��o��SP�E�t,s̫p���'���6[�nLkn�R�m�A!�}�K!�����˺砚�knhm"^SY�t��+�xr��k���L�~1�ڡܭy�P���O���M�_�&��o����;Ν�ط���������#��E��v7�qUP8�c(XL�]���8Y��]��'��Nt��P���u"���j�8�8�S �rB��Q�s��,�->����w�XB�HJ��=YO{m1��"[ZKj/;�dD���ʛZ��W���6�,eΩ:�A��5�e`54"�dAZW'Ջ���_�6���+%xI�P��T7�.�k�G���=PRV��m�P㌪�����Wu#Q>�o���g�*��01�lc���]�g�0��Η���F�~8�ǽMWPt���O a�qߎע7�55�i�q�a����z9>�*�ɼG#��T~���pK���1���۔�l�3���G��T�k�u{���:��0�|��)ѹ��m����3j��5cdٍb���L�y8��e;�
�
�<gb;q�zy��Y׳����1ɌӤ�㓞��s#�=�[ɑ#�����5��
���dy;vŧ�d.5*�������t�f�_Y�ɦ�59*��O�N#�'�s}�������;����9�rЖ�V3U)/�ӌ��Σ`Z����şٛ�tD�.�:�� H��[�k5�
juW���W���`��������r���H�88�����Ex~�g�Y�{���g�Y�{��d��!�U���6_�Y��������������� !102���?��E�uG���=<�n����x���H�M1C�G�[f���:x�kL�p���rC1����"�����������! 1"Aq���?ەzZr�=9Q�d�)���ݲ-Q�1jŬ���>�V�MZ>
��%E��rJC�w�۪U+/��/K'��?L�?dz��e��m?[�.�v��1�%�umv�W����WT�����?���3��������!1A 2a"0Qq#3BR���r��#b������?��J�e6��D�:�X3�$�(�ݦ>�����,�gr��5�5c���^�������˘,���s���%ӚP�;�,��Z�%�# "8��ӥ��Ip)0?q^�hF�IFvW�fa�N�K�W������);(P�MhA_D��4���KM����\vO�o�ThW]۟�f��`��))��[L&i+�٘F�j���L�
�'�DW�O��3�nc�]���,�H�Z�t/l
-x�����dڍ�㢰���A+�w.�K�,h�uK�х��Ӕw�]�����ҵZ��>����.w�d��t�i���,��Ût�������^�xS2��S�.9B��Y:��:��/�ԥ��C�J��d��H]\�*6xg���S`o觎e˴C�P�>e?U
\OU0�P�����o5#����VwªRw��PlB�:YtVS�-Nα���j�ca�v�~�U����``�6R#
�.#���Vi�VZ��*84_t��}��\����GW�Y�vy�+)*�gr쬘��i��|��3Q�ػ�}U�T[��&7�=O���U8SA4m��� 3��vR��2��T.:�?���'�������!1AQaq������ ��������?!�'�� � ��?�HI��2]�x�ɈCK�[,Q��B�:��
�]���p��H!h���k\�y�$N'q��$/�"�B/z}����/Ȭ~�YHn�F�,3���7�E���#�4kcV�oB0�![t�kZ�L��jX|�0'nQc]�O��d��ouK8\��ov��ĵ���+'DMY���6���bL�
��N�'EСM���6�-�A,����d��
�x��%��A1R���ZX>�j�Ѐ$
��k��Xܛg�{')�x]�H��טm�D�i�#dlr3M�y7(�4FD�#�bI.���UV]�*(�_��)�<"ET�T
�ȽQ$m$� �n��5b�3$�,��
�J� �#r$�h�<>脢"�t3����M��Tp���-�AZ�i�r0��r��/�F*G%d�?���y
��"qP����ERHĜ���s%9e�-���r!�ن��bFwoDf�4k(����\��F?R(Z
�[Au�I��At�:d�^�ﭕ*�QX�rgP6m���m�"V)���:����dю%)P�l�O2Y$LT^<V���(#$D������ōi���j�#�v>U}X�
2CZ���\�u��C�������s�n�z�)��(�����
�ztoa�Dr��5�܉��Yz�ʏ�pw�+�-$ˤ����~�h��!2$��6z���F��H��Q��ֈ�s[���
Mo��;M�'�bu�w*jʲ�i�
p~�hV�6-�#��h��e2�c��?��"E�D0�e��)�R�aح�]�GP���NH�1W4$�M:rD����������mCn=H��pLZ?,sl8��l���Bl/��D��%���GO
r^-k^��V7n (�ܾτ�+�NR� ��������_��\�ԟcؾkY�U�i��2�N+�:D�E�r���y\��٪>�0:�,�����`d��A v��k�
aͦ���J��#��N��
�J�ӫ)�:iZC�6BD�B(�1}� L���,�*��$
�l9��n��}�;�ޏX��.ħ��v"\䌴>�w��Y�������8��D���[�����f�Q�փ-b^�� ��S%�4�24!�'��E���(�'��hR#��ЩC"x쵩�,v;�����������!1AQa���?����%��;ᯓ��b�d�{��3��k�o!~��v_���e���_dv�eZ��-Y���~X������g�0�e�L�-
�,���O���X|_o�۩l�6`ɴx��X[��%?.ZX:]E��������������!1AQa����?�X�I}���/Sm��m�$�//����JxZ�
�Λn��#�u� �#�n�
&]��~�~'��#���0
;��<NG�����u&�.�^e�&����khK�sul���ߨ��ê?��u���~����_�'�=���?8����&�������!1AQaq��������������?)��α�W{���\-j*��`"yWA��VV+X�6�&P
!kY���l|Ī�5�f0��%�-�DY1�-C� ���)%(��
}��J�LH�8��M�����Ș�YJ�t*��-|CU,�ŏ�y�K�|��C2�-bcZ�T"Ջ�j���cR����<��l^���i��s���w�P�e��m�E������
1�w�zbY�2�3�_E�Ə�;�2�]Uj���
��YX�'nԿ
�]�k{����_� i�fH0P"�/ș�3(����;����l�N�uX� �9�:R�6�fӚ��/�����o�V�K��3m����v>��QP��6���DQe�����������u1X�s#ԯ������7�exW�ry�1P�u,���1�����r��NER8湇�ʸ�t,�>�G�F����AՔ�2�/�v!p��
�K���Z��/l
�\�!�>Y��\���,��� �m;/��b�w�m&����e�����J���~�eWR��!�O�T�E��ܾ~*�D���k����6�#�r���SD�НCB��tx�������q�#aw�$�q������w�������N�P�/�#����O�ʽ���`�f�Z�c��mҥ����X��-��ܲԙ;!��q�Ef�l:��*���Q�+W�q��=J�J��
Ų�]Tй-F$
#�7��0�tX�n
\
��-89F�a�F�~b\�q� �h���Ն�ß�ڳ*���߮�;��,�'lq���Qj��F�ۛ�2.n��-<���-�)���<�n�c��L���| ���G�r��4�������܉��L#7���%��c�6yX��q�lz�P�`V�Ы8{�c�Y�]J$`�+���U���*Ŋ����u�nMF*�vc�qg�B�(]��0��ڈڙ|\�;>������0gA��
�ӓ��_�Ԅ�V�}\I�#8�t:^���J<��{��
� m������IXn'���.*�/D*��S�6�ڕ�6WT�g�KQ���[!w�?�~#Q���e �"�'+��uW�*cP��u�/7���R���T+S�LTZuq���u0�h��:j�Q��Ө�jݮ(f�
�J��ZoR�A���!��t�AaH�BWF�
ۇ�L!��i�`P���
���gL}�^o�,���p?��)U��".&r��
�#R�\���ʫ����Q�K�
����cb�OL��(}����>"��"R�!T#:��Π!Wmc�4���C��4���g��,�$V��C/�h9��Z%��%+x^w�E�ñj��7&������?�K�� Yl���6e��(j-����R��%0e�l�5��$q
���G����3q|���n� b�V�T<_�#������2�טƐ2�F6�6���Ĵ�U��������75jy>�)��
H9��$�A�������)�?0_�ª)<Jc���
��>L�D�g�t�n��w��+!e>H P��-`��(7��&6� �ĠU�����>2� �_��r�"�d�1e��B�`o�n�_-��[�M�s6�52�Cm��xc����z�Al=�zA;�&���D�^o������.�GȨ�b�Y��n�庈��`WXz���Xb�'#�� �2*�yQo1��>U)��&ᦥ�����m͑s[�x��HuY�<�G�j?P,0�����/�]qp\�q]#��Kh��ID7����pIEԠU{�s���#���^�N�0�xo=L]6(���W0�j�0�/.�s3TL�F��V�����X���4Qx1|�:.��[x~f~���v~�\���1��̯��M#�d{��eܞ<�UV�'���
��3�5,h������
------------ae0ae0Ij5cH2GI3KM7Ef1Ef1ei4gL6
Content-Disposition: form-data; name="Upload"
Submit Query
------------ae0ae0Ij5cH2GI3KM7Ef1Ef1ei4gL6--
Upgrading the ASP.NET WebAPI NuGet package to the latest version solved the problem.
Related
i have a Server Application using dotnet core Controllers. There I have this Controller:
[HttpPost]
[RequestSizeLimit(100_000)]
public async Task<IActionResult> xxx([FromForm] string name, [FromForm] string description, [FromForm] bool isprivate, [FromForm] IFormFile icon)
{
...
}
When i send the request from my Frontend in the Browser, it works fine, generating this request:
Frame 103: 2148 bytes on wire (17184 bits), 2148 bytes captured (17184 bits) on interface \Device\NPF_Loopback, id 2
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 51141, Dst Port: 8001, Seq: 4701, Ack: 1792, Len: 2064
Hypertext Transfer Protocol
POST /api/xxx/xxxHTTP/1.1\r\n
Host: localhost:8001\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0\r\n
Accept: application/json, text/plain, */*\r\n
Accept-Language: de,en-US;q=0.7,en;q=0.3\r\n
Accept-Encoding: gzip, deflate\r\n
Content-Type: multipart/form-data; boundary=---------------------------20261806215495369501698203786\r\n
Content-Length: 1127\r\n
Origin: http://localhost:8001\r\n
DNT: 1\r\n
Connection: keep-alive\r\n
Referer: http://localhost:8001/xxx\r\n
[truncated]Cookie: .AspNetCore.Cookies=CfDJ8M_ELI8knopFkQ6zEqeCkgwDf43UGRqyyzwLWbKrkSuSRcmzqAPIcsi94bVzQFVWJB0NOGVRZVgzm4n7sf-0ox3SPK1ChgaqQuPRTogxdWzbJZPo1DCCi1TMI04RH4tmMj8rgv8EwDko5s1S2BNw0Owj8qL_-loCOz2VYU7wG3lVl5TIVavb46_nV6_Zr6MVdz
\r\n
[Full request URI: http://localhost:8001/api/xxx/xxx]
[HTTP request 6/6]
[Prev request in frame: 97]
[Response in frame: 107]
File Data: 1127 bytes
MIME Multipart Media Encapsulation, Type: multipart/form-data, Boundary: "---------------------------20261806215495369501698203786"
[Type: multipart/form-data]
First boundary: -----------------------------20261806215495369501698203786\r\n
Encapsulated multipart part:
Boundary: \r\n-----------------------------20261806215495369501698203786\r\n
Encapsulated multipart part:
Boundary: \r\n-----------------------------20261806215495369501698203786\r\n
Encapsulated multipart part:
Boundary: \r\n-----------------------------20261806215495369501698203786\r\n
Encapsulated multipart part: (image/png)
Last boundary: \r\n-----------------------------20261806215495369501698203786--\r\n
Now i also have a Client written in C# using the HTTPClient, and i can't get the fileupload working.
This is my code there right now:
public async Task<string?> Addxxx(string name, string description, bool isPrivate, byte[] ImageData, CancellationToken token)
{
var url = $"{Scheme}://{Address}:{Port}/api/xxx/xxx";
var Content = new MultipartFormDataContent();
var ImageContent = new ByteArrayContent(ImageData);
ImageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
Content.Add(ImageContent);
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new MultipartFormDataContent()
{
{
new FormUrlEncodedContent(new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("name" , name),
new KeyValuePair<string, string>("description" , description),
new KeyValuePair<string, string>("isprivate" , isPrivate.ToString()),
})
},
{Content }
}
};
request.Headers.Add("Accept", "multipart/form-data");
request.Headers.Add("User-Agent", UserAgent);
request.Headers.Add("Cookie", Cookies);
var response = await HttpClient.SendAsync(request, token);
if (!response.IsSuccessStatusCode)
return null;
...
}
However, this always gets a bad request.
This is the request generated:
Frame 16: 1523 bytes on wire (12184 bits), 1523 bytes captured (12184 bits) on interface \Device\NPF_Loopback, id 2
Null/Loopback
Internet Protocol Version 4, Src: 192.168.2.101, Dst: 192.168.2.101
Transmission Control Protocol, Src Port: 51121, Dst Port: 8001, Seq: 1394, Ack: 1020, Len: 1439
Hypertext Transfer Protocol
POST /api/xxx/xxxHTTP/1.1\r\n
Host: 192.168.2.101:8001\r\n
Accept: multipart/form-data\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36\r\n
[truncated]Cookie: .AspNetCore.Cookies=CfDJ8M_ELI8knopFkQ6zEqeCkgx2TK33iweuVbSNkdR_HNs5nC6EEy6zFxnuwpIovyH9WenSzaVCDgW3VWk0BJJ7cDnfdnQ5W_o98sJvaVtiVmPk3JB8e5bySGdcoRN6NwIl27mqLMl89Kt5hnsrq5Jps9Q3kJ1XSk5kpMciycb9AijtG9N_tqqqhRbV9EvbQc0CUU
Request-Id: |10c9eb89-46f0038fdc2e3b2d.\r\n
Content-Type: multipart/form-data; boundary="4265ae7c-56da-4811-b646-fc1123794472"\r\n
Content-Length: 576\r\n
\r\n
[Full request URI: http://192.168.2.101:8001/api/xxx/xxx]
[HTTP request 3/3]
[Prev request in frame: 10]
[Response in frame: 20]
File Data: 576 bytes
MIME Multipart Media Encapsulation, Type: multipart/form-data, Boundary: "4265ae7c-56da-4811-b646-fc1123794472"
[Type: multipart/form-data]
First boundary: --4265ae7c-56da-4811-b646-fc1123794472\r\n
Encapsulated multipart part: (application/x-www-form-urlencoded)
Boundary: \r\n--4265ae7c-56da-4811-b646-fc1123794472\r\n
Encapsulated multipart part: (multipart/form-data)
Last boundary: \r\n--4265ae7c-56da-4811-b646-fc1123794472--\r\n
I tried a lot and am a bit lost in how to Send the request from the Client...
Can someone point me in the right direction on how to send the image together with the other POST data?
I am currently working on a console app to import data into Joplin for Windows 10, using C# and Flurl.
Joplin's API description can be found here.
I am trying to create a new resource in Joplin for a file on my system, so it can be attached to a Joplin note.
With CURL I can create the resource using command:
curl -F "data=#c:\\temp\\Test.pptx" -F "props={\"title\":\"my resource title\"}" http://localhost:41184/resources?token=MyToken
(note: it only works with "data=#c:\temp\Test.pptx", NOT with "data=c:\temp\Test.pptx")
When I try this with Flurl in c# I get a 400 response from Joplin, in the log I find:
Error: Resource cannot be created without a file
at Api.action_resources (C:\Program Files\Joplin\resources\app.asar\lib\services\rest\Api.js:351:37)
at Api.route (C:\Program Files\Joplin\resources\app.asar\lib\services\rest\Api.js:140:42)
at execRequest (C:\Program Files\Joplin\resources\app.asar\lib\ClipperServer.js:157:39)
at C:\Program Files\Joplin\resources\app.asar\lib\ClipperServer.js:185:8
at C:\Program Files\Joplin\resources\app.asar\node_modules\multiparty\index.js:136:9
at C:\Program Files\Joplin\resources\app.asar\node_modules\multiparty\index.js:115:9
at processTicksAndRejections (internal/process/task_queues.js:75:11)"
I have tried this so far:
try
{
var url = BaseUrl
.WithHeader("User_Agent", browserUserAgent)
.AppendPathSegment("resources")
.SetQueryParam("token", Token);
using (var fs = new FileStream("c:\\temp\\Test.pptx", FileMode.Open, FileAccess.Read))
{
var resource = url.PostMultipartAsync(mp => mp
.AddJson("props", new { title = "test title" })
.AddFile("data", fs, "Test.pptx", "application/octet-stream")
)
.ReceiveJson<JoplinResource>()
.Result;
}
}
and:
try
{
var url = BaseUrl
.WithHeader("User_Agent", browserUserAgent)
.AppendPathSegment("resources")
.SetQueryParam("token", Token);
var resource = url.PostMultipartAsync(mp => mp
.AddJson("props", new { title = "test title" })
.AddFile("data", "c:\\temp\\Test.pptx")
)
.ReceiveJson<JoplinResource>()
.Result;
}
I hooked up fiddler to see what is the difference between my application and CURL.
Curl:
POST http://127.0.0.1:41184/resources?token=MyToken HTTP/1.1
Host: 127.0.0.1:41184
User-Agent: curl/7.70.0
Accept: */*
Connection: Keep-Alive
Content-Length: 33648
Content-Type: multipart/form-data; boundary=------------------------91ab181cbb0247ba
--------------------------91ab181cbb0247ba
Content-Disposition: form-data; name="props"
{"title":"my resource title"}
--------------------------91ab181cbb0247ba
Content-Disposition: form-data; name="data"; filename="Test.pptx"
Content-Type: application/octet-stream
...
My Console app:
POST http://localhost:41184/resources?token=MyToken HTTP/1.1
User_Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
Content-Type: multipart/form-data; boundary="f603841b-5c32-4e77-985a-69c2ffb6eed0"
Host: localhost:41184
Content-Length: 33612
Expect: 100-continue
Accept-Encoding: gzip, deflate
--f603841b-5c32-4e77-985a-69c2ffb6eed0
Content-Disposition: form-data; name=props
{"title":"My Resource"}
--f603841b-5c32-4e77-985a-69c2ffb6eed0
Content-Disposition: form-data; name=data; filename=Test.pptx; filename*=utf-8''Test.pptx
...
NOTE the differences:
props and data are in quotes when using CURL, not with FLURL
FLURL sends a second file name: filename*=utf-8''Test.pptx
How do I get this to work properly?
The issue was in the missing quotes for the "data" and "props":
try
{
var url = BaseUrl
.WithHeader("User_Agent", browserUserAgent)
.AppendPathSegment("resources")
.SetQueryParam("token", Token);
var resource = url.PostMultipartAsync(mp => mp
.AddJson("\"props\"", new { title = "My Resource" })
.AddFile("\"data\"", "c:\\temp\\Test.pptx")
)
.ReceiveJson<JoplinResource>()
.Result;
}
Raw request header is now:
POST http://localhost:41184/resources?token=MyToken HTTP/1.1
User_Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
Content-Type: multipart/form-data; boundary="c6b2377a-1240-4ae3-872f-fa24b643d3e0"
Host: localhost:41184
Content-Length: 33616
Expect: 100-continue
Accept-Encoding: gzip, deflate
--c6b2377a-1240-4ae3-872f-fa24b643d3e0
Content-Disposition: form-data; name="props"
{"title":"My Resource"}
--c6b2377a-1240-4ae3-872f-fa24b643d3e0
Content-Disposition: form-data; name="data"; filename=Test.pptx; filename*=utf-8''Test.pptx
...
And the Joplin REST service creates a new resource...
I'm new to WebRequests and I tried this:
string json = #"{""Gebruikersnaam"":""user"",""Wachtwoord"":""pass"",""IngelogdBlijven"":true}";
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://pontessg.magister.net/api/sessies");
httpWebRequest.ContentType = "application/json";
httpWebRequest.ContentLength = json.Length;
Console.WriteLine(json.Length);
Console.WriteLine(json);
Console.Read();
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
}
My code is keep returning me ERROR (400) and I don't really know why I think I forgot something, but I don't know what
(The Headers)
Request URL:https://pontessg.magister.net/api/sessies
Request Method:POST
Status Code:200 OK
Remote Address:[...]
Response Headers
view parsed
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 76
Content-Type: application/json; charset=utf-8
Expires: -1
Date: Sat, 25 Feb 2017 21:45:33 GMT
X-Frame-Options: DENY
Strict-Transport-Security: max-age=[...]
Request Headers
view parsed
POST /api/sessies HTTP/1.1
Host: pontessg.magister.net
Connection: keep-alive
Content-Length: 88
Accept: application/json, text/plain, */*
X-API-Client-ID: 12D8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Origin: https://pontessg.magister.net
Content-Type: application/json;charset=UTF-8
DNT: 1
Referer: https://pontessg.magister.net/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: SESSION_ID=[...]; M6UserName=user; username=pass; Magister.UserName=user; [...]
Request Payload
{"Gebruikersnaam":"user","Wachtwoord":"pass","IngelogdBlijven":true}
When I try the JS code below in the console of my browser, it returns 200 OK
$.ajax({
url: "https://pontessg.magister.net/api/sessies",
type: "POST",
data: "{\"Gebruikersnaam\":\"user\",\"Wachtwoord\":\"pass\",\"IngelogdBlijven\":true}",
contentType: "application/json;charset=utf-8",
success: action_Succeeded,
error: action_Failed
});
function action_Succeeded(r) {
console.log("succes");
}
function action_Failed(r1, r2, r3) {
alert("fail");
}
If someone could help me with this, I would like that
I have a Flight PHP REST server set up.
At 1 end point it expects POST data and based on one of the POST data it retrieves some data from the database and returns it as JSON.
When I use the Postman REST extension in Chrome I see the correct result. But when I do the call using my C# application the returned json is null because the $_POST seems empty.
This is my Flight index.php:
Flight::route('POST /getText', function(){
// Create a new report class:
$reportText = new ReportText;
$theText = $reportText->ParsePost($_POST);
if ($theText == null)
{
echo null;
}
else
{
echo json_encode($theText);
}
});
This is my ParsePost:
public function ParsePost($PostDictionary)
{
$textArray = null;
foreach ($PostDictionary as $key => $value)
{
if (!empty($value))
{
list($tmp, $id) = explode("_", $key);
$text = $this->geFooWithText($id);
$textArray[$key] = "bar";
}
}
return $textArray;
}
This is my C# part:
private static async Task RunAsyncPost(string requestUri)
{
using (var client = new HttpClient())
{
// Send HTTP requests
client.BaseAddress = new Uri("myUrl");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
// HTTP POST
var response = await client.PostAsJsonAsync(requestUri, new { question_8 = "foo", question_9 = "bar" });
response.EnsureSuccessStatusCode(); // Throw if not a success code.
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
if (string.IsNullOrEmpty(json))
{
throw new ArgumentNullException("json", #"Response from the server is null");
}
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
foreach (var kvp in dictionary)
{
Debug.WriteLine("Key: {0}, Value: {1}", kvp.Key, kvp.Value);
}
}
}
catch (HttpRequestException e)
{
// Handle exception.
Debug.WriteLine(e.ToString());
throw;
}
}
}
This is the response from Postman:
{
"question_8": "foo",
"question_9": "bar"
}
It seems I'm missing something in my call using C#.
[Update]
In this post (Unable to do a HTTP POST to a REST service passing json through C#) the same problem seems to appear.
Using Fiddler was suggested.
Using Postman and x-www-form-urlencoded:
POST http://myHost/api/getText HTTP/1.1
Host: myHost
Connection: keep-alive
Content-Length: 29
Cache-Control: no-cache
Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Accept-Encoding: gzip,deflate
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
question_8=foo&question_9=bar
Using Postman and form-data:
POST http://myHost/api/getText HTTP/1.1
Host: myHost
Connection: keep-alive
Content-Length: 244
Cache-Control: no-cache
Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvb4wmaP4KooT6TFu
Accept: */*
Accept-Encoding: gzip,deflate
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
------WebKitFormBoundaryvb4wmaP4KooT6TFu
Content-Disposition: form-data; name="question_8"
foo
------WebKitFormBoundaryvb4wmaP4KooT6TFu
Content-Disposition: form-data; name="question_9"
bar
------WebKitFormBoundaryvb4wmaP4KooT6TFu--
Using my C#-application:
POST http://myHost/api/getText/ HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: myHost
Content-Length: 50
Expect: 100-continue
Connection: Keep-Alive
{"question_8":"foo","question_9":"bar"}
The C# application is sending it clearly in a different way.
I've found the problem.
Because I use client.PostAsJsonAsync() the POST data is send as json, as you can see in Fiddler.
PHP doesn't expects the POST data to be in json format.
To read that data I need to use $data = file_get_contents('php://input'); in my PHP file.
Now I have my keys and values and can I continue. It looks like PHP needs a $_JSON variable ;)
I'm using HttpWebRequest component and trying to POST data to server.
When I use browser I can trace that it sends this request
POST https://plus.google.com/_/socialgraph/mutate/modifymemberships/?_reqid=1950158&rt=j HTTP/1.1
Host: plus.google.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
X-Same-Domain: 1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
Referer: https://plus.google.com/_/apps-static/_/js/home/b,s/rt=h/ver=OeD97kiQfn8.en./sv=1/am=!iPoVWvyH1UcKPT9bc1pNSZLcSj8oHAelto24gJorhwk/d=1/
Content-Length: 216
Cookie: PREF=ID=c42cff62752fc3e8:U=dae37ffa177e0689:FF=0:TB=2:LD=en:CR=2:TM=1244434765:LM=1311323210:DV=0SJoub_nzRUL:GM=1:S=EuE8opfqNl8PGGHI; NID=54=enDovqVn7CSHrPtZ2ZSPAt4PrE0ZZE-rWJawva2NiUWC1TzreG-sVdiSnRp7kolqcvMCGCIKt7agHKT6Hi2JZkV5qYmY_fUkxFjk6PUc7TrdNRAT7_9mRnvwOxeBOcng; rememberme=false; __utma=1.340991765.1324442547.1324723420.1324806933.8; __utmz=1.1324723420.7.7.utmcsr=google.com|utmccn=(referral)|utmcmd=referral|utmcct=/accounts/Logout2; OTZ=1044056_4_4_133320_8_385320; S=analytics-realtime-frontend=h23QCGj_I9O7FLG9cqDjkA:awfe=SnIt_U1wxuihQ1myCwuiZA:awfe-efe=lCXLSEuiUzX3HyaRuXVuRg:adwords-optimization=yCZeLrx1FD0uGQFYb07LTQ:adwords-common-ui=WfNukVX7rVpTuVtMlZ6IbA; S_awfe=tyb6VRVQyBHkv8nbfMNWRg; GMAIL_RTT=571; __utmc=1; HSID=AtaMO-oLk9-OMZkiv; SSID=AGt3gDSdd3Q98pA81; APISID=7xRgosYs7uOXzd0Y/AI4OXaHRTViR8oE8s; SAPISID=0HNI_ffNupNL-UfT/Ao6YbG5vkEashPdOM; ULS=EgYKBBICZW4Yy-Xb9wQ; SID=DQAAALMAAADk5OelxcPoQKO8FrSoOfOGoTHX4HeVfeJJQhtd19k07mJMUhJkiehF1FTzb7jNt34c80UGpyXEJT5FML373p6RR_5EQ3etVYjUXmgqHsdO7G-XuP_k_m798MDvd4AWkDX2vKVtqc5zA_olxB9UkJBLU_g2IM2vZ3Scp-eThZj8C3uZuzdN_DCpQeVjrU6a1kiIdQRsz9rUtxzoC0E22Ux4ba0QneaWBT73Ns14wh7fqZtYB-DRB2zcWkXXoNnV67U; FBS_VI_1324806859_0=ot_00Qg-hkQV7uhIEb0dTMT0_DD6aAI
Pragma: no-cache
Cache-Control: no-cache
a=%5B%5B%5B%225947b6d78a8231f3%22%5D%5D%5D&m=%5B%5B%5B%5Bnull%2Cnull%2C%22113690702042497323038%22%5D%2C%22Stephanie%20Parker%22%2C%5B%5D%5D%5D%5D&r=%5B%5B%5D%5D&at=AObGSAg06IXl5iYSceecKRc64xHVAB_GDw%3A1324806859000&
And when I use HttpWebRequester is sends following data which results in Code 400 rather then Code 200
POST https://plus.google.com/_/socialgraph/mutate/modifymemberships/?_reqid=1950158&rt=j HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
Accept-Language: en-gb,en;q=0.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
X-Same-Domain: 1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
Referer: https://plus.google.com/_/apps-static/_/js/home/b,s/rt=h/ver=OeD97kiQfn8.en./sv=1/am=!iPoVWvyH1UcKPT9bc1pNSZLcSj8oHAelto24gJorhwk/d=1/
Pragma: no-cache
Cache-Control: no-cache
Host: plus.google.com
Cookie: ULS=EgYKBBICZW4Yp_7k9wQ; SID=DQAAALYAAAAZuUVe6hDQbW__dA1Itrcz8thm2Ncxk5YFMfpeiKyr6Pps1Pu0ajmReczMDHKGnDpk3yrx7WFy-5QMOf0Fu4WiPVdUWcU_cLNfD7FhKtqmSmOgFiffTkyj8dg0bsTeahhrKR7j75rjU_eXqGnQI2qcJHOyk1cLEkWNaWyLRGeYDrsfAh6uzx4AI-1GtKbwwrE7UHsn_sUFG1DuwI_Ct_g9C2llFVVyQruvFnlmRE1xDE_ORwvnBYCrGQYjyt1blg8; HSID=AbkExs5EzrPodpoKx; SSID=A2y_-xD7iOhW9Y2HF; APISID=73YQ7BugDgjmMSdd/AgFF1ClZc0z-fpPGM; SAPISID=mT6qzvCACzlvDrg-/AN1ajSgZCB0R9xOmX
Content-Length: 216
Connection: Keep-Alive
a=%5b%5b%5b%225947b6d78a8231f3%22%5d%5d%5d&m=%5b%5b%5b%5bnull%2cnull%2c%22113690702042497323038%22%5d%2c%22Stephanie%20Parker%22%2c%5b%5d%5d%5d%5d&r=%5b%5b%5d%5d&at=AObGSAg06IXl5iYSceecKRc64xHVAB_GDw%3a1324806859000&
So any idea why this to similar requests have 2 different server response?
BTW I did check cookies and they are fine. I'm just puzzled on why my request would not work.
UPDATE Request Code added
webRequest_ = (HttpWebRequest)HttpWebRequest.Create(Params.URL);
webRequest_.Method = "POST";
//webRequest_.Proxy = new WebProxy("http://plus.google.com", false);
webRequest_.UserAgent = Params.UserAgent;
webRequest_.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
webRequest_.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
webRequest_.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
webRequest_.KeepAlive = true;
webRequest_.Headers.Add("X-Same-Domain", "1");
webRequest_.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
webRequest_.Referer = "https://plus.google.com/_/apps-static/_/js/home/b,s/rt=h/ver=OeD97kiQfn8.en./sv=1/am=!iPoVWvyH1UcKPT9bc1pNSZLcSj8oHAelto24gJorhwk/d=1/";
webRequest_.CookieContainer = Params.Cookie;
webRequest_.Headers.Add("Pragma", "no-cache");
webRequest_.Headers.Add("Cache-Control", "no-cache");
var sp = webRequest_.ServicePoint;
var prop = sp.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
prop.SetValue(sp, (byte)0, null);
var parameters = new StringBuilder();
foreach (var key in Params.Params)
{
parameters.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(key.ToString()),
HttpUtility.UrlEncode(Params.Params[key.ToString()]).Replace("+","%20"));
}
using (var writer = new StreamWriter(webRequest_.GetRequestStream()))
{
writer.Write(parameters.ToString());
}
After extensive testing I have figured out that problem is not in a header but rather in the data that gets posted, particularly in "at" parameter which is stands for session Id. After successfully generation session id it did work like a charm.