בקשת POST בC# יוצרת שגיאה
-
@עידו אם אתה יודע בטח תוכל להסביר מה ההבדל בין הבקשת 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
-
פוסט זה נמחק! -
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו אתה יכול בקוד להשתמש בסיפריות מוכנות של 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}"); } }
בשרת שלי אין net (סייבר פאנל מבוסס לינוקס)
-
-
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו זה משהו שאתה מטמיע בקוד אצלך, ודרך הקוד נתוני ה-request מוכנסים לתוך קובץ log.
אתה כותב ב-asp.net?
אני לא כותב בASP ולדעתי השרת לא יודע להריץ ASP
תודה
-
@עידו באיזו שפה אתה כותב?
אם זה אתה משתמש באחסון VPS, אז תוכל ללכת לתיקית ה-apache או ngnix ושם יש לוגים של כל הבקשות שנכנסות לשרת.
באחסון שיתופי (shared), אתה יכול להנפיק את קובץ ה-LOG דרך הקוד של השפה שבה אתה כותב, מן הסתם ה-entry point של האפליקציה שלך מקבלת את ה-request שמכיל מידע על הבקשה וה-headers שלה. -
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו באיזו שפה אתה כותב?
אם זה אתה משתמש באחסון VPS, אז תוכל ללכת לתיקית ה-apache או ngnix ושם יש לוגים של כל הבקשות שנכנסות לשרת.
באחסון שיתופי (shared), אתה יכול להנפיק את קובץ ה-LOG דרך הקוד של השפה שבה אתה כותב, מן הסתם ה-entry point של האפליקציה שלך מקבלת את ה-request שמכיל מידע על הבקשה וה-headers שלה.אני כותב בעיקר C# ואם צריך משתמש בchatgpt לphp או לשאר השפות - כמו שאמרתי, אני לא מתכנת.
בדקתי את הלוגים של השרת ומשום מה הבקשות ששלחתי לא מופיעות שם לא ברור לי למה...