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 ;)
Related
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...
Is it possible to retrieve a list of entities as a parameter for an action in c# odata?
Tried the following but it casues the entire controller to not work:
[HttpPost]
[NhSessionManagement()]
[ODataRoute("BatchUpdate")]
public async Task<IHttpActionResult> BatchUpdate(List<Item> items, bool updateDefaultJSONFile)
{
return Ok();
}
This is the config:
{
var action = builder.EntityType<Item>().Collection.Action("BatchUpdate");
action.CollectionParameter<Item>("items");
action.Parameter<bool>("updateDefaultJSONFile");
}
This is how I then send the data:
$http.post(appConfig.serviceUrl + "api/items/Service.BatchUpdate", { items: itemsToUpdate, updateDefaultJSONFile: true}).success(function (data, status, headers, config) {
debug("Successfully saved");
}).error(function (data, status, headers, config) {
debug("Failed to save");
});
In fiddler:
POST http://192.168.20.108/api/items/Service.BatchUpdate HTTP/1.1
Host: 192.168.20.108
Connection: keep-alive
Content-Length: 83114
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: http://192.168.20.108
Authorization: Bearer ****
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://192.168.20.108/
Accept-Encoding: gzip, deflate
Accept-Language: sv-SE,sv;q=0.9,en-US;q=0.8,en;q=0.7
{"items":[{"Key":"helpful","Text":"test"}],"updateDefaultJSONFile":false}
Specify collection parameters as an array, not a list:
[HttpPost]
[NhSessionManagement()]
[ODataRoute("BatchUpdate")]
public async Task<IHttpActionResult> BatchUpdate(Item[] items, bool updateDefaultJSONFile)
{
return Ok();
}
Config is correct, good job.
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'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.
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.