בקשת POST בC# יוצרת שגיאה
-
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
והם לא מוכנים לקבל אותו כשהוא נשלח ע"י ספריה מסוימת (שבה משתמשים היום) בשפה מסוימת, אולי אני טועה אבל לפי הבנתי יש להם בשרת בעיה עם איך שC# מממשים את הפרוטוקול הזה.
במילים אחרות, אם אני - מתכנת C# (אני לא, למעשה אני רחוק מזה, אבל זה לא הנקודה) - רוצה לכתוב קוד שיתקשר עם השרת שלהם, והולך לפי התיעוד הרשמי שלהם, אני בבעיה, מה שאין כן אם אני מתכנת בPHP או שפות אחרות, שאז הכל חלק.
על זה בדיוק אני אומר שאין כזה דבר (כלומר הכל יכול להיות תיאורטית, הכוונה שיש לזה סבירות אפסית), ובוא ננסה להבין איפה שורש הבעיה. כי היא ב100% לא במימוש של C#
אתה מכיר את mitmproxy? יש לו ממשק וובי שמאפשר לראות את התוכן בפועל של בקשות -
@צדיק-תמים כתב בבקשת POST בC# יוצרת שגיאה:
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
והם לא מוכנים לקבל אותו כשהוא נשלח ע"י ספריה מסוימת (שבה משתמשים היום) בשפה מסוימת, אולי אני טועה אבל לפי הבנתי יש להם בשרת בעיה עם איך שC# מממשים את הפרוטוקול הזה.
במילים אחרות, אם אני - מתכנת C# (אני לא, למעשה אני רחוק מזה, אבל זה לא הנקודה) - רוצה לכתוב קוד שיתקשר עם השרת שלהם, והולך לפי התיעוד הרשמי שלהם, אני בבעיה, מה שאין כן אם אני מתכנת בPHP או שפות אחרות, שאז הכל חלק.
על זה בדיוק אני אומר שאין כזה דבר (כלומר הכל יכול להיות תיאורטית, הכוונה שיש לזה סבירות אפסית), ובוא ננסה להבין איפה שורש הבעיה. כי היא ב100% לא במימוש של C#
נכון, היא במימוש של ימות המשיח, כי שם זה לא עובד... באתרים אחרים כן...
-
@צדיק-תמים כתב בבקשת POST בC# יוצרת שגיאה:
אתה מכיר את mitmproxy? יש לו ממשק וובי שמאפשר לראות את התוכן בפועל של בקשות
לא מכיר, אבל גם jsonplaceholder נותן אפשרות
-
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
@צדיק-תמים כתב בבקשת POST בC# יוצרת שגיאה:
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
והם לא מוכנים לקבל אותו כשהוא נשלח ע"י ספריה מסוימת (שבה משתמשים היום) בשפה מסוימת, אולי אני טועה אבל לפי הבנתי יש להם בשרת בעיה עם איך שC# מממשים את הפרוטוקול הזה.
במילים אחרות, אם אני - מתכנת C# (אני לא, למעשה אני רחוק מזה, אבל זה לא הנקודה) - רוצה לכתוב קוד שיתקשר עם השרת שלהם, והולך לפי התיעוד הרשמי שלהם, אני בבעיה, מה שאין כן אם אני מתכנת בPHP או שפות אחרות, שאז הכל חלק.
על זה בדיוק אני אומר שאין כזה דבר (כלומר הכל יכול להיות תיאורטית, הכוונה שיש לזה סבירות אפסית), ובוא ננסה להבין איפה שורש הבעיה. כי היא ב100% לא במימוש של C#
נכון, היא במימוש של ימות המשיח, כי שם זה לא עובד... באתרים אחרים כן...
אתה יודע מה זה פרוטוקול? ובפרט מה זה פרוטוקול HTTP?
אם תלמד את זה תבין למה לא יכול להיות שיש בעיה בימות והיא צצה רק כששולחים HTTP POST בC# ולא כששולחים HTTP POST בשפות אחרות. בשום שלב לא טענתי שאין בעיה בימות אלא שאין שום קשר ל C#
אגב לגבי mitmpproxy, יש גם את proxyman עם ממשק יותר ידידותי ונסיון חינם -
@צדיק-תמים אני יודע איך הבקשה נראית בפועל, אני כבר אחרי כל זה...
-
@עידו אם אתה יודע בטח תוכל להסביר מה ההבדל בין הבקשת POST JSON שאתה שולח ב C# ולא עובדת לבקשת POST JSON שאחרים שולחים וכן עובדת
זה מה שאני מבקש מההתחלה
ואם תאמר שאין הבדל - אז שוב, אין קשר לC# -
@צדיק-תמים
אני יודע 3 דברים:- שאותה בקשת ג'סון עובדת באתר אחד, ואצל ימות המשיח לא עובדת.
- כשאחרים שלחו ג'סון בC# זה לא עבד להם.
- כששולחים בשפות אחרות זה כן עובד.
מה רץ מאחורי הקלעים ואיזה עוד אינפורמציה מועברת בדרך, אני לא יודע.
מה שבטוח ימות המשיח מסרבים להתייחס לתוכן הג'סון.
-
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
כששולחים בשפות אחרות זה כן עובד.
מי אמר? בדקת?
מדגיש, אותה צורה בדיוק - HTTP POST, מסוג JSON, ושכל הפרמטרים בגוף הבקשה -
@צדיק-תמים אני בדקתי, ומה ש@עידו אומר זה אמת.
יש בעיה בסיריאליזציה ב-C#, אגב, בדקתי את זה ב-postman וזה עובד (עם בקשת POST), ובדקתי את זה גם ב-PHP וזה גם עובד (גם עם בקשת POST).אם יש לך השגות על מה שנאמר כאן, אני מזמין אותך לנסות בעצמך את הנ"ל.
-
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
אני בדקתי, ומה ש@עידו אומר זה אמת.
יש בעיה בסיריאליזציה ב-C#איך נראה האובייקט עם הסריאליזציה הפגומה ואיך הוא היה אמור להיראות?
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
בדקתי את זה ב-postman וזה עובד (עם בקשת POST)
POST JSON? ככה?
אתה יכול לעשות בסרגל הצד של פוסטמן ייצוא לCURL ולהעתיק לכאן? -
POSTMAN: curl --location --request POST 'https://www.call2all.co.il/ym/api/UploadTextFile' \ --header 'Content-Type: application/json' \ --data-raw '{ "token": "<username>:<password>", "what": "ivr2:14/text_file.ini", "contents": "Some text message" }' c#: curl -X POST -d '{"token":"<username>:<password>","what":"ivr2:14/text_file.ini","contents":"Some test message"}' https://www.call2all.co.il/ym/api/UploadTextFile
תגוובה ב-POSTMAN:
{ "responseStatus": "OK", "message": "ok", "yemotAPIVersion": 6 }
תגובה ב-C#:
Response: {"yemotAPIVersion":6,"responseStatus":"EXCEPTION","message":"IllegalStateException(session token is required)"
אז ככה, ב-C# ברגע שאתה משייך flag של -d ל-curl, זה אוטומטית יוצר בקשה עם:
Content-Type: application/x-www-form-urlencoded
וזה לא נשלח עם:
Content-Type: application/json
ה-body שנשלח לשרת של ימות הוא בפורמט json בעוד שה-content-type בפורמט של:
x-url-encoded.לאחר מכן, ניסיתי לכפות על ה-httpClient לשים header של Content-Type: application/json, אך הוא מתעלם מזה....
ומכאן נובעת השגיאה, הבעיה היא לא בימות המשיח, אלא באופן בניית ה-CURL ב-C#, שה-body שנשלח לא תואם ל-content-type ב-header.
-
@צדיק-תמים במידה ואתה חפץ לבדוק זאת בעצמך, זה הקוד:
static async Task UploadTextFileWithPost2() { var url = "https://www.call2all.co.il/ym/api/UploadTextFile"; try { var client = new HttpClient(); var obj = new { token = $"{Username}:{Password}", what = "ivr2:14/text_file.ini", contents = "Some test message" }; var json = JsonConvert.SerializeObject(obj); var content = new StringContent(json, Encoding.UTF8, "application/json"); var responseJ2 = await client.PostAsync(url, content); // בדיקת מצב התגובה if (responseJ2.IsSuccessStatusCode) { // קריאת התוכן של התגובה var responseContent2 = await responseJ2.Content.ReadAsStringAsync(); Console.WriteLine($"Response: {responseContent2}"); } else { Console.WriteLine($"Error: {responseJ2.StatusCode}"); return; } } catch (Exception ex) { Console.WriteLine($"Exception: {ex.Message}"); } await Task.Delay(1000); Console.WriteLine("Async work done!"); }
-
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
POSTMAN: curl --location --request POST 'https://www.call2all.co.il/ym/api/UploadTextFile' \ --header 'Content-Type: application/json' \ --data-raw '{ "token": "<username>:<password>", "what": "ivr2:14/text_file.ini", "contents": "Some text message" }' c#: curl -X POST -d '{"token":"<username>:<password>","what":"ivr2:14/text_file.ini","contents":"Some test message"}' https://www.call2all.co.il/ym/api/UploadTextFile
תגוובה ב-POSTMAN:
{ "responseStatus": "OK", "message": "ok", "yemotAPIVersion": 6 }
תגובה ב-C#:
Response: {"yemotAPIVersion":6,"responseStatus":"EXCEPTION","message":"IllegalStateException(session token is required)"
אז ככה, ב-C# ברגע שאתה משייך flag של -d ל-curl, זה אוטומטית יוצר בקשה עם:
Content-Type: application/x-www-form-urlencoded
וזה לא נשלח עם:
Content-Type: application/json
ה-body שנשלח לשרת של ימות הוא בפורמט json בעוד שה-content-type בפורמט של:
x-url-encoded.לאחר מכן, ניסיתי לכפות על ה-httpClient לשים header של Content-Type: application/json, אך הוא מתעלם מזה....
ומכאן נובעת השגיאה, הבעיה היא לא בימות המשיח, אלא באופן בניית ה-CURL ב-C#, שה-body שנשלח לא תואם ל-content-type ב-header.
לא ממש הבנתי על איזה flag או d דיברת, אבל זה מעניין, למה אתרים אחרים כן מקבלים את זה?
ולכאורה בקוד פשוט שלחת JSON אז למה בכל זאת הוא לא שולח את זה כסוג JSON?
-
-
@soris1989 אבל בקוד רגיל בC# לא מוסיפים את זה, אני לא הוספתי בכל אופן...
-
@עידו הרצתי עכשיו דרך ה-bash סידרה של שליחת בקשות CURL של POST, ואכן שבשביל שזה יעבוד, צריך להוריד את ה-flag של -d, ובמקום זה לשים flags של:
\--header "Content-Type: application/json" \--data-raw '{"token":"<username>:<password>","what":"ivr2:14/text_file.ini","contents":"Some test message"}'
לגבי זה שזה עובד במקרים אחרים, אני לא יודע מה לומר לך. מה שכן, בשביל שזה יעבוד בפורמט JSON אתה תצטרך ככל הנראה לבנות CURL באופן ידני, כי ה-httpClient.PostAsync לא בונה נכון את ה-CURL.
בכל אופן, הצעתי לך אתמול פתרון שכן עובד, תשתמש בו.
-
@soris1989 יש לי שרת, איך אני יכול לראות בו בדיוק מה מגיע אליו? כולל ההדר?
-
@עידו אתה יכול בקוד להשתמש בסיפריות מוכנות של Logging לתוך קובץ.
הקוד הבא מאפשר את קבלת המחרוזת של ה-curl:
static async Task UploadTextFileWithPost2() { var url = "https://www.call2all.co.il/ym/api/UploadTextFile"; try { var client = new HttpClient(); var obj = new { token = $"{Username}:{Password}", what = "ivr2:14/text_file.ini", contents = "Some test message" }; var json = JsonConvert.SerializeObject(obj); var content = new StringContent(json, Encoding.UTF8, "application/json"); // Generate cURL command string curlCommand = GenerateCurlCommand("POST", url, client, content); Console.WriteLine("Generated cURL:"); Console.WriteLine(curlCommand); var responseJ2 = await client.PostAsync(url, content); // בדיקת מצב התגובה if (responseJ2.IsSuccessStatusCode) { // קריאת התוכן של התגובה var responseContent2 = await responseJ2.Content.ReadAsStringAsync(); Console.WriteLine($"Response: {responseContent2}"); } else { Console.WriteLine($"Error: {responseJ2.StatusCode}"); return; } } catch (Exception ex) { Console.WriteLine($"Exception: {ex.Message}"); } await Task.Delay(1000); Console.WriteLine("Async work done!"); } static string GenerateCurlCommand(string method, string url, HttpClient client, HttpContent content) { StringBuilder sb = new StringBuilder(); sb.Append($"curl -X {method} "); // Add headers foreach (var header in client.DefaultRequestHeaders) { sb.Append($"-H \"{header.Key}: {string.Join("; ", header.Value)}\" "); } // Add content body if (content != null) { string body = content.ReadAsStringAsync().Result; sb.Append($"-d '{body}' "); } // Add URL sb.Append(url); return sb.ToString(); }
המתודה GenerateCurlCommand, פולטת לך string עם ה- curl, את ה-string הזה תדפיס בתוך קובץ log או משהו בסגנון. וזה לגבי בקשות שאתה מריץ מהקוד שלך.
לגבי בדיקת בקשות שנכנסות למערכת שלך, במידה ואתה כותב ב asp.net core, אז תיצור middleware באופן הבא:
using Microsoft.AspNetCore.Http; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class RequestLoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<RequestLoggingMiddleware> _logger; public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext httpContext) { // Log request method, URL, and headers _logger.LogInformation("Request Method: {Method}, Request URL: {Url}", httpContext.Request.Method, httpContext.Request.Path); // Log all headers foreach (var header in httpContext.Request.Headers) { _logger.LogInformation("Header: {Header}: {Value}", header.Key, header.Value); } // Call the next middleware in the pipeline await _next(httpContext); } }
בקוד של asp.net (לא CORE), תשים ב-global.asax:
using System; using System.Web; public class Global : HttpApplication { protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext context = HttpContext.Current; // Log request method and URL var method = context.Request.HttpMethod; var url = context.Request.Url.ToString(); // Log all headers foreach (var header in context.Request.Headers.AllKeys) { var headerValue = context.Request.Headers[header]; System.Diagnostics.Debug.WriteLine($"Header: {header}: {headerValue}"); } // Log method and URL System.Diagnostics.Debug.WriteLine($"Request Method: {method}, Request URL: {url}"); } }
-
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
אז ככה, ב-C# ברגע שאתה משייך flag של -d ל-curl
מה הכוונה לשייך flag ל-curl בC#?
ממה שראיתי אתה שולח את הבקשה עם HttpClient של C# ולא curl
-
פוסט זה נמחק!