python to c# (about server request) - c#

I need to translate this python code into C#:
messages = { "to" :"PhoneNumber" }
body = {
"type" : "SMS",
"contentType" : "COMM",
"from" : "PhoneNumber2",
"subject" :"subject",
"content" : "Hell world",
"messages" : [messages]
}
body2 = json.dumps(body)
headers = {
'Content-Type': 'application/json; charset=utf-8',
'X-ncp-apigw-timestamp': timestamp,
'x-ncp-iam-access-key': access_key,
'x-ncp-apigw-signature-v2': make_signature(uri, access_key)
}
res = requests.post(apiUrl, headers=headers, data=body2)
res.request
res.status_code
res.raise_for_status()
print(res.json())
So I've tried :
public class themessage
{
public string to;
}
public class body
{
public string type;
public string contentType;
public string from;
public string subject;
public string content;
public themessage messages;
}
var obj = new body
{
type = "SMS",
contentType = "COMM",
from = "PN",
subject = "subject",
content = "Hell World",
messages = new themessage
{
to = "PN"
}
};
var client = new RestClient(apiUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json; charset=utf-8");
request.AddHeader("X-ncp-apigw-timestamp", timestamp);
request.AddHeader("x-ncp-iam-access-key", accessKey);
request.AddHeader("x-ncp-apigw-signature-v2", test);
request.AddJsonBody(obj); // **this is where I'm concerning part**
IRestResponse response = client.Execute(request);
But, as you expected, failed to post with error message of "Not requested format" something.
Did I something wrong when making JsonBody? or posting process?
Thanks for all answers in advance!

Following my last comment on the IRestRequest interface, your class hierarchy should look similar to
public class themessage
{
public string to;
}
public class body
{
public string type;
public string contentType;
public string from;
public string subject;
public string content;
public themessage[] messages; // <- Array here
}
and the object you create with it will be something like
var obj = new body
{
type = "SMS",
contentType = "COMM",
from = "PN",
subject = "subject",
content = "Hell World",
messages = new themessage[] { new themessage{to = "PN"} }
};
The code for the RestClient and RestRquest stays as it is.

Related

Response Bargain Finder Max Compress c#

good morning, I have a solution in .net where I call the webservices of saber bargain finder max. Now I want to download the compressed information but the response object returns null. I read that you have to call the interface IClientMessageInspector BeforeSendRequest and AfterReceiveReply but I do not know how to proceed. someone will have an example or solution about it? Thank you
The response for the service cannot handle the compressed response, so yes, you have to put middleware in order to process the decompression before you let it continue.
First of all, you need to import the BFM WSDL as a service instead of as a web services, so:
Right click on "Service References" and click on "Add Service Reference..."
Paste the WSDL URL under "Address:" and click on "Go"
Recommendation: Download the WSDL and the associated schemas so you can modify them, since .NET has some issues handling some things, which you can manually modify. Sabre has some covered here.
Name the service whatever you like, in this example I'll call it BargainFinderMaxRQ_4_1_0_Srvc, under "Namespace:" and click on "OK"
Then, I created 2 classes, one that will be the one calling BFM ("BFM_v410Service"), and another one for the middleware ("BFMInspector").
Let's start with the BFMInspector:
// The inspector class has to implement both IClientMessageInspector and IEndpointBehavior interfaces
public class BFMInspector : IClientMessageInspector, IEndpointBehavior
{
// This is the method to action after receiving a response from Sabre
public void AfterReceiveReply(ref Message reply, object correlationState)
{
try
{
// Get compressed response from reply and load that into a byte array.
XmlDictionaryReader bodyReader = reply.GetReaderAtBodyContents();
bodyReader.ReadStartElement("CompressedResponse");
byte[] bodyByteArray = bodyReader.ReadContentAsBase64();
// Create some helper variables
StringBuilder uncompressed = new StringBuilder();
String xmlString = "";
XmlDocument xmlPayload = new XmlDocument();
// Load the byte array into memory
using (MemoryStream memoryStream = new MemoryStream(bodyByteArray))
{
// Unzip the Stream
using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
byte[] buffer = new byte[1024];
int readBytes;
// Unzips character by character
while ((readBytes = gZipStream.Read(buffer, 0, buffer.Length)) != 0)
{
for (int i = 0; i < readBytes; i++)
// Append all characters to build the response
uncompressed.Append((char)buffer[i]);
}
}
xmlString = uncompressed.ToString();
xmlString = xmlString.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>", "");
}
// Convert the string into an XML
xmlPayload.LoadXml(xmlString);
// Create a new Message, which is what will substitute what was returned by Sabre
Message tempMessage = Message.CreateMessage(reply.Version, null, xmlPayload.ChildNodes[0]);
tempMessage.Headers.CopyHeadersFrom(reply.Headers);
tempMessage.Properties.CopyProperties(reply.Properties);
MessageBuffer bufferOfFault = tempMessage.CreateBufferedCopy(Int32.MaxValue);
// Replace the reply with the new Message
reply = bufferOfFault.CreateMessage();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Nothing is done here, so we simply return null
return null;
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// Nothing done
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
// Add "this" as an endpoint to be inspected
clientRuntime.MessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// Nothing done
}
public void Validate(ServiceEndpoint endpoint)
{
// Nothing done
}
}
Now, the BFM_v410Service:
// BFM calling class
public class BFM_v410Service
{
// The constructor and CreateRequest simeply create a complete request
private BargainFinderMaxRQRequest service;
private OTA_AirLowFareSearchRQ request;
public OTA_AirLowFareSearchRS response;
private string endpoint;
public BFM_v410Service(string token, string pcc, string convId, string endpoint)
{
CreateRequest(pcc, true);
this.endpoint = endpoint;
service = new BargainFinderMaxRQRequest()
{
MessageHeader = new BargainFinderMaxRQ_3_4_0_Srvc.MessageHeader()
{
From = new From()
{
PartyId = new PartyId[]
{
new PartyId()
{
Value = pcc
}
}
},
To = new To()
{
PartyId = new PartyId[]
{
new PartyId()
{
Value = endpoint
}
}
},
ConversationId = convId,
CPAId = pcc,
Service = new Service()
{
Value = "BargainFinderMaxRQ"
},
Action = "BargainFinderMaxRQ",
MessageData = new MessageData()
{
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssK")
}
},
OTA_AirLowFareSearchRQ = request,
Security = new Security()
{
BinarySecurityToken = token
}
};
}
private void CreateRequest(string pcc, bool compressed)
{
request = new OTA_AirLowFareSearchRQ()
{
Version = "3.4.0",
POS = new SourceType[]
{
new SourceType()
{
PseudoCityCode = pcc,
RequestorID = new UniqueID_Type()
{
ID = "1",
Type = "1",
CompanyName = new CompanyNameType()
{
Code = "TN",
Value = "TN"
}
}
}
},
OriginDestinationInformation = new OTA_AirLowFareSearchRQOriginDestinationInformation[]
{
new OTA_AirLowFareSearchRQOriginDestinationInformation()
{
RPH = "1",
Item = "2018-09-21T11:00:00",
ItemElementName = ItemChoiceType.DepartureDateTime,
OriginLocation = new OriginDestinationInformationTypeOriginLocation()
{
LocationCode = "MVD"
},
DestinationLocation = new OriginDestinationInformationTypeDestinationLocation()
{
LocationCode = "KRK"
}
},
new OTA_AirLowFareSearchRQOriginDestinationInformation()
{
RPH = "2",
Item = "2018-09-28T11:00:00",
ItemElementName = ItemChoiceType.DepartureDateTime,
OriginLocation = new OriginDestinationInformationTypeOriginLocation()
{
LocationCode = "KRK"
},
DestinationLocation = new OriginDestinationInformationTypeDestinationLocation()
{
LocationCode = "MVD"
}
}
},
TravelerInfoSummary = new TravelerInfoSummaryType()
{
AirTravelerAvail = new TravelerInformationType[]
{
new TravelerInformationType()
{
PassengerTypeQuantity = new PassengerTypeQuantityType[]
{
new PassengerTypeQuantityType()
{
Code = "ADT",
Quantity = "1"
}
}
}
}
},
TPA_Extensions = new OTA_AirLowFareSearchRQTPA_Extensions()
{
IntelliSellTransaction = new TransactionType()
{
RequestType = new TransactionTypeRequestType()
{
Name = "50ITINS"
},
CompressResponse = new TransactionTypeCompressResponse()
{
Value = compressed
}
}
}
};
}
public void Execute()
{
try
{
// Instanciate the Inspector
BFMInspector inspector = new BFMInspector();
// Select the URL you'll be sending the request. I've passed this as a parameter in the constructor
EndpointAddress url = new EndpointAddress(new Uri(endpoint));
// Create a binding, with a couple of characteristics, because of the size of the response
Binding binding = new BasicHttpsBinding()
{
MaxReceivedMessageSize = Int32.MaxValue,
MaxBufferSize = Int32.MaxValue
};
// Create the executable the BargainFinderMaxPortTypeClient variable, which will allow me to call the service
BargainFinderMaxPortTypeClient execute = new BargainFinderMaxPortTypeClient(binding, url);
// Add the middleware. Here's where ApplyClientBehavior is called behind the scene and adds itself
execute.Endpoint.EndpointBehaviors.Add(inspector);
// Call BFM and successfully get the response as an OTA_AirLowFareSearchRS object
response = execute.BargainFinderMaxRQ(ref service.MessageHeader, ref service.Security, request);
Console.WriteLine(response);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Then, simply call this from a console application:
static void Main(string[] args)
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
string token = #"Shared/IDL:IceSess\/SessMgr:1\.0.IDL/Common/!ICESMS\/RESA!ICESMSLB\/RES.LB!-3146624380791354996!413892!0!1!E2E-1";
string pcc = "XXXX";
string convId = "HERE GOES YOUR CONVERSATION ID";
string endpoint = "https://webservices.havail.sabre.com";
BFM_v410Service bfm340 = new BFM_v410Service(token, pcc, convId, endpoint);
bfm410.Execute();
}
Hope this helps!

RestSharp Array Request

Send array post RestSharp?
Dictionary, List<> is not compatibile ?
public class Test
{
public string key { get; set; }
public string viewType { get; set; }
public string module { get; set; }
public string method { get; set; }
public Dictionary<string, string> parameters { get; set; }
}
My class init.
Test t = new Test();
t.key = "xxxxxxxxxxxxxxxxxx";
t.viewType = "json";
t.module = "test";
t.method = "test";
t.parameters = new Dictionary<string,string>();
t.parameters.Add("p1", "data1");
Send data request
IRestResponse response = restClient.Execute<Test>(restRequest);
Send is debbuger:
[JSON]
-request
module: "test"
method: "test"
parameters:"System.Collections.Generic.Dictionary`2[System.String,System.String]"
Who RestSharp create ? ? Send Array options object ?
$postData = array(
'key' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'viewType' => 'json',
'module' => 'test',
'method' => 'test',
[options] => stdClass Object
(
[name] => 'ADIDAS'
)
);
I found this in the documentation:
To add all properties for an object as parameters, use AddObject(). To
add a file for upload, use AddFile() (request will be sent as
multipart encoded form). To include a request body (like XML or JSON),
use AddBody();
So because you are using restRequest.AddObject(), RestSharp uses the value of t.parameters.ToString() instead of serializing to JSON.
Fix: use restRequest.AddBody(t) instead. You also have to specify the content type.
request.RequestFormat = DataFormat.Json;
request.AddBody(t);
RestClient restClient = new RestClient("https:");
RestRequest restRequest = new RestRequest(Method.POST);
Test t = new Test();
t.key = ac.Password;
t.viewType = "json";
t.module = "hello";
t.method = "hello";
t.parameters = new Dictionary<string,string>();
t.parameters.Add("wddwdw", "ddd");
restRequest.AddObject(t);
IRestResponse response = restClient.Execute<Test>(restRequest);

Validating Recaptcha 2 (No CAPTCHA reCAPTCHA) in ASP.NET's server side

The new Recaptcha 2 looks promising, but i didn't find a way to validate it in ASP.NET's server side,
if(Page.IsValid) in This answer, is valid for the old Recaptcha, but not the new one,
How to validate the new reCAPTCHA in server side?
After reading many resources, I ended up with writing this class to handle the validation of the new ReCaptcha :
As mentioned Here : When a reCAPTCHA is solved by end user, a new field (g-recaptcha-response) will be populated in HTML.
We need to read this value and pass it to the class below to validate it:
In C#:
In the code behind of your page :
string EncodedResponse = Request.Form["g-Recaptcha-Response"];
bool IsCaptchaValid = (ReCaptchaClass.Validate(EncodedResponse) == "true" ? true : false);
if (IsCaptchaValid) {
//Valid Request
}
The Class:
using Newtonsoft.Json;
public class ReCaptchaClass
{
public static string Validate(string EncodedResponse)
{
var client = new System.Net.WebClient();
string PrivateKey = "6LcH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory";
var GoogleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse));
var captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<ReCaptchaClass>(GoogleReply);
return captchaResponse.Success.ToLower();
}
[JsonProperty("success")]
public string Success
{
get { return m_Success; }
set { m_Success = value; }
}
private string m_Success;
[JsonProperty("error-codes")]
public List<string> ErrorCodes
{
get { return m_ErrorCodes; }
set { m_ErrorCodes = value; }
}
private List<string> m_ErrorCodes;
}
In VB.NET:
In the code behind of your page :
Dim EncodedResponse As String = Request.Form("g-Recaptcha-Response")
Dim IsCaptchaValid As Boolean = IIf(ReCaptchaClass.Validate(EncodedResponse) = "True", True, False)
If IsCaptchaValid Then
'Valid Request
End If
The Class:
Imports Newtonsoft.Json
Public Class ReCaptchaClass
Public Shared Function Validate(ByVal EncodedResponse As String) As String
Dim client = New System.Net.WebClient()
Dim PrivateKey As String = "6dsfH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory"
Dim GoogleReply = client.DownloadString(String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse))
Dim captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(Of ReCaptchaClass)(GoogleReply)
Return captchaResponse.Success
End Function
<JsonProperty("success")> _
Public Property Success() As String
Get
Return m_Success
End Get
Set(value As String)
m_Success = value
End Set
End Property
Private m_Success As String
<JsonProperty("error-codes")> _
Public Property ErrorCodes() As List(Of String)
Get
Return m_ErrorCodes
End Get
Set(value As List(Of String))
m_ErrorCodes = value
End Set
End Property
Private m_ErrorCodes As List(Of String)
End Class
Here's a version that uses the JavaScriptSerializer. Thanks Ala for the basis for this code.
WebConfig App Setting -
I've added the secret key to the Web.Config in my case to allow transforms between environments. It can also be easily encrypted here if required.
<add key="Google.ReCaptcha.Secret" value="123456789012345678901234567890" />
The ReCaptcha Class - A simple class to post the response parameter along with your secret to Google and validate it. The response is deserialized using the .Net JavaScriptSerializer class and from that true or false returned.
using System.Collections.Generic;
using System.Configuration;
public class ReCaptcha
{
public bool Success { get; set; }
public List<string> ErrorCodes { get; set; }
public static bool Validate(string encodedResponse)
{
if (string.IsNullOrEmpty(encodedResponse)) return false;
var client = new System.Net.WebClient();
var secret = ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"];
if (string.IsNullOrEmpty(secret)) return false;
var googleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, encodedResponse));
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var reCaptcha = serializer.Deserialize<ReCaptcha>(googleReply);
return reCaptcha.Success;
}
}
Validate The Response - Check the validity of the g-Recaptcha-Response form parameter in your Controller (or code behind for a web form) and take appropriate action.
var encodedResponse = Request.Form["g-Recaptcha-Response"];
var isCaptchaValid = ReCaptcha.Validate(encodedResponse);
if (!isCaptchaValid)
{
// E.g. Return to view or set an error message to visible
}
Most of these answers seem more complex than needed. They also dont specify the IP which will help prevent a interception attack (https://security.stackexchange.com/questions/81865/is-there-any-reason-to-include-the-remote-ip-when-using-recaptcha). Here's what I settled on
public bool CheckCaptcha(string captchaResponse, string ipAddress)
{
using (var client = new WebClient())
{
var response = client.DownloadString($"https://www.google.com/recaptcha/api/siteverify?secret={ ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"] }&response={ captchaResponse }&remoteIp={ ipAddress }");
return (bool)JObject.Parse(response)["success"];
}
}
You can use "IsValidCaptcha()" method to validate your google recaptcha on server side. Replace your secret key with "YourRecaptchaSecretkey" in the following method.
Public bool IsValidCaptcha()
{
string resp = Request["g-recaptcha-response"];
var req = (HttpWebRequest)WebRequest.Create
(https://www.google.com/recaptcha/api/siteverify?secret=+ YourRecaptchaSecretkey + "&response=" + resp);
using (WebResponse wResponse = req.GetResponse())
{
using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
{
string jsonResponse = readStream.ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
// Deserialize Json
CaptchaResult data = js.Deserialize<CaptchaResult>(jsonResponse);
if (Convert.ToBoolean(data.success))
{
return true;
}
}
}
return false;
}
Also create following class as well.
public class CaptchaResult
{
public string success { get; set; }
}
According to the doc you just post your secret key and user's answer to API and read returned "success" property
SHORT ANSWER:
var webClient = new WebClient();
string verification = webClient.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, userResponse));
if (JObject.Parse(verification)["success"].Value<bool>())
{
// SUCCESS!!!
FULL EXAMPLE:
Suppose, you implement this page in IamNotARobotLogin.cshtml.
<head>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="Login" method="POST">
<div class="g-recaptcha" data-sitekey="your_site_key"></div><br/>
<input type="submit" value="Log In">
</form>
</body>
And suppose you wish the controller saved, let's say, "I_AM_NOT_ROBOT" flag in the session if the verification succeeded:
public ActionResult IamNotARobotLogin()
{
return View();
}
[HttpPost]
public ActionResult Login()
{
const string secretKey = "6LcH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory";
string userResponse = Request.Form["g-Recaptcha-Response"];
var webClient = new System.Net.WebClient();
string verification = webClient.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, userResponse));
var verificationJson = Newtonsoft.Json.Linq.JObject.Parse(verification);
if (verificationJson["success"].Value<bool>())
{
Session["I_AM_NOT_A_ROBOT"] = "true";
return RedirectToAction("Index", "Demo");
}
// try again:
return RedirectToAction("IamNotARobotLogin");
}
Here's my fork of Ala's solution in order to:
send paramter in POST
to sanitize the form input
include the requester IP address
store the secret in Web.Config:
In the controller:
bool isCaptchaValid = await ReCaptchaClass.Validate(this.Request);
if (!isCaptchaValid)
{
ModelState.AddModelError("", "Invalid captcha");
return View(model);
}
The utility class:
public class ReCaptchaClass
{
private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static string SecretKey = System.Configuration.ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"];
[JsonProperty("success")]
public bool Success { get; set; }
[JsonProperty("error-codes")]
public List<string> ErrorCodes { get; set; }
public static async Task<bool> Validate(HttpRequestBase Request)
{
string encodedResponse = Request.Form["g-Recaptcha-Response"];
string remoteIp = Request.UserHostAddress;
using (var client = new HttpClient())
{
var values = new Dictionary<string, string>
{
{"secret", SecretKey},
{"remoteIp", remoteIp},
{"response", encodedResponse}
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://www.google.com/recaptcha/api/siteverify", content);
var responseString = await response.Content.ReadAsStringAsync();
var captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<ReCaptchaClass>(responseString);
if ((captchaResponse.ErrorCodes?.Count ?? 0) != 0)
{
log.Warn("ReCaptcha errors: " + string.Join("\n", captchaResponse.ErrorCodes));
}
return captchaResponse.Success;
}
}
}
This article give clear step by step explication on how to implement a ReCaptcha validation attribute on your model.
First, create the Recaptcha validation attribute.
namespace Sample.Validation
{
public class GoogleReCaptchaValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
Lazy<ValidationResult> errorResult = new Lazy<ValidationResult>(() => new ValidationResult("Google reCAPTCHA validation failed", new String[] { validationContext.MemberName }));
if (value == null || String.IsNullOrWhiteSpace( value.ToString()))
{
return errorResult.Value;
}
IConfiguration configuration = (IConfiguration)validationContext.GetService(typeof(IConfiguration));
String reCaptchResponse = value.ToString();
String reCaptchaSecret = configuration.GetValue<String>("GoogleReCaptcha:SecretKey");
HttpClient httpClient = new HttpClient();
var httpResponse = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={reCaptchaSecret}&response={reCaptchResponse}").Result;
if (httpResponse.StatusCode != HttpStatusCode.OK)
{
return errorResult.Value;
}
String jsonResponse = httpResponse.Content.ReadAsStringAsync().Result;
dynamic jsonData = JObject.Parse(jsonResponse);
if (jsonData.success != true.ToString().ToLower())
{
return errorResult.Value;
}
return ValidationResult.Success;
}
}
}
Then add the validation attribute on your model.
namespace Sample.Models
{
public class XModel
{
// ...
[Required]
[GoogleReCaptchaValidation]
public String GoogleReCaptchaResponse { get; set; }
}
}
Finally, you have just to call the ModelState.IsValid method
namespace Sample.Api.Controllers
{
[ApiController]
public class XController : ControllerBase
{
[HttpPost]
public IActionResult Post(XModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// ...
}
}
}
Et voilĂ  ! :)
Another example is posted here:
RecaptchaV2.NET (Github)
It also implements the secure token option of Recaptcha 2.0 (look at full source code for that bit, I have stripped out relevant pieces of code ONLY for validating a result).
This one doesn't rely on newtonsoft's json parser and instead uses the built in .NET one.
Here is the relevant snippet of code from the RecaptchaV2.NET library (from recaptcha.cs):
namespace RecaptchaV2.NET
{
/// <summary>
/// Helper Methods for the Google Recaptcha V2 Library
/// </summary>
public class Recaptcha
{
public string SiteKey { get; set; }
public string SecretKey { get; set; }
public Guid SessionId { get; set; }
/// <summary>
/// Validates a Recaptcha V2 response.
/// </summary>
/// <param name="recaptchaResponse">g-recaptcha-response form response variable (HttpContext.Current.Request.Form["g-recaptcha-response"])</param>
/// <returns>RecaptchaValidationResult</returns>
public RecaptchaValidationResult Validate(string recaptchaResponse)
{
RecaptchaValidationResult result = new RecaptchaValidationResult();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=" + SecretKey + "&response="
+ recaptchaResponse + "&remoteip=" + GetClientIp());
//Google recaptcha Response
using (WebResponse wResponse = req.GetResponse())
{
using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
{
string jsonResponse = readStream.ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
result = js.Deserialize<RecaptchaValidationResult>(jsonResponse.Replace("error-codes", "ErrorMessages").Replace("success", "Succeeded"));// Deserialize Json
}
}
return result;
}
private string GetClientIp()
{
// Look for a proxy address first
String _ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
// If there is no proxy, get the standard remote address
if (string.IsNullOrWhiteSpace(_ip) || _ip.ToLower() == "unknown")
_ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
return _ip;
}
}
public class RecaptchaValidationResult
{
public RecaptchaValidationResult()
{
ErrorMessages = new List<string>();
Succeeded = false;
}
public List<string> ErrorMessages { get; set; }
public bool Succeeded { get; set; }
public string GetErrorMessagesString()
{
return string.Join("<br/>", ErrorMessages.ToArray());
}
}
}
Google's ReCaptcha API no longer accepts the payload as query string parameters in a GET request. Google always returned a "false" success response unless I sent the data via HTTP POST. Here is an update to Ala's (excellent!) class which POSTs the payload to the Google service endpoint:
using Newtonsoft.Json;
using System.Net;
using System.IO;
using System.Text;
public class RecaptchaHandler
{
public static string Validate(string EncodedResponse, string RemoteIP)
{
var client = new WebClient();
string PrivateKey = "PRIVATE KEY";
WebRequest req = WebRequest.Create("https://www.google.com/recaptcha/api/siteverify");
string postData = String.Format("secret={0}&response={1}&remoteip={2}",
PrivateKey,
EncodedResponse,
RemoteIP);
byte[] send = Encoding.Default.GetBytes(postData);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = send.Length;
Stream sout = req.GetRequestStream();
sout.Write(send, 0, send.Length);
sout.Flush();
sout.Close();
WebResponse res = req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
string returnvalue = sr.ReadToEnd();
var captchaResponse = JsonConvert.DeserializeObject<RecaptchaHandler>(returnvalue);
return captchaResponse.Success;
}
[JsonProperty("success")]
public string Success
{
get { return m_Success; }
set { m_Success = value; }
}
private string m_Success;
[JsonProperty("error-codes")]
public List<string> ErrorCodes
{
get { return m_ErrorCodes; }
set { m_ErrorCodes = value; }
}
private List<string> m_ErrorCodes;
}
Using dynamic to validate recaptcha at server side
Calling Function
[HttpPost]
public ActionResult ClientOrderDetail(FormCollection collection, string EncodedResponse)
{
Boolean Validation = myFunction.ValidateRecaptcha(EncodedResponse);
return View();
}
Function Declaration
public static Boolean ValidateRecaptcha(string EncodedResponse)
{
string PrivateKey = "YourSiteKey";
var client = new System.Net.WebClient();
var GoogleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse));
var serializer = new JavaScriptSerializer();
dynamic data = serializer.Deserialize(GoogleReply, typeof(object));
Boolean Status = data["success"];
string challenge_ts = data["challenge_ts"];
string hostname = data["hostname"];
return Status;
}
the example I posted in this so post uses Newtonsoft.JSON to deserialize the full returned JSON, posts the data to Google(as opposed to using a querystring) stores the relevant variables in the web.config rather than hard coded.

RestSharp: Deserialize Xml to c# Object return null

i've an xml from some api :
<auditypes>
<auditype code="a" description="aaa"/>
<auditype code="b" description="bbb"/>
<auditype code="c" description="ccc"/>
<auditype code="d" description="ddd"/>
<auditype code="e" description="eee"/>
</auditypes>
and mapping as object in C# class :
public class auditypes
{
public List<auditype> auditype { get; set; }
}
public class auditype
{
public string code { get; set; }
public string description { get; set; }
}
I call it with this function :
public List<auditypes> Execute<auditypes>(RestRequest request) where auditypes : new()
{
var client = new RestClient();
client.BaseUrl = "https://www.myurl.com/auditypes";
var response = client.Execute<auditypes>(request);
return response.Data as List<auditypes>;
}
public List<auditypes> GetCall()
{
var request = new RestRequest();
request.RequestFormat = DataFormat.Xml;
request.RootElement = "auditype";
return Execute<auditypes>(request);
}
but it always return null, does anyone knows why is this happening?
The generic parameter passed to Execute<T> is the type that should be deserialized by the RestSharp library. That means that your response.Data property is already of type T, which in your case is auditypes. But when you return you try to cast it to a List<auditypes> where no such cast exists.
Also, there is no need for the type constraint, as your method is not generic as it accepts an explicit type.
Refactor your method:
public auditypes Execute<auditypes>(RestRequest request)
{
var client = new RestClient();
client.BaseUrl = "https://www.myurl.com/auditypes";
var response = client.Execute<auditypes>(request);
return response.Data;
}
Finally, it work for me :)
public auditypes Execute<auditypes>(RestRequest request) where auditypes : new()
{
var client = new RestClient();
client.BaseUrl = "https://www.myurl.com/auditypes";
var response = client.Execute<auditypes>(request).Data;
return response;
}
public auditypes GetCall()
{
var request = new RestRequest();
request.RequestFormat = DataFormat.Xml;
return Execute<auditypes>(request);
}

RESTful WCF json request and json response returns null

I am trying to build a sample for RESTful WCF. The request and response is JSON. The response that I get is:
{"FirstName":null,"LastName":null}
I need to get proper response.
Here is the code:
Web.config has configuration for Restful:
service contract:
[OperationContract]
[WebInvoke(UriTemplate = "Data",
ResponseFormat = WebMessageFormat.Json)]
person getData(person name);
Implementation:
public person getData(person name)
{
return new person{ FirstName= name.FirstName, LastName= name.LastName };
}
[DataContract]
public class person
{
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
}
Client:
class Program
{
static void Main(string[] args)
{
string baseAddress = "http://localhost/RESTfulService";
SendRequest(baseAddress + "/Data", "POST", "application/json", #"{""getData"" : {""name"" :{""FirstName"":""John"", ""LastName"":""Doe""}}");
}
public static string SendRequest(string uri, string method, string contentType, string body)
{
string responseBody = null;
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Method = method;
if (!String.IsNullOrEmpty(contentType))
{
req.ContentType = contentType;
}
if (body != null)
{
byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
req.GetRequestStream().Close();
}
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException e)
{
resp = (HttpWebResponse)e.Response;
}
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Stream respStream = resp.GetResponseStream();
if (respStream != null)
{
responseBody = new StreamReader(respStream).ReadToEnd();
Console.WriteLine(responseBody);
}
else
{
Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
}
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
return responseBody;
}
}
public static string SendRequest(string uri, string method, string contentType, string body) {...}
somehow it works only fine for "GET" methods.
For POST methods, I had to call the service operations in different manner on the client side:
uri = "http://localhost/RestfulService";
EndpointAddress address = new EndpointAddress(uri);
WebHttpBinding binding = new WebHttpBinding();
WebChannelFactory<IRestfulServices> factory = new WebChannelFactory<IRestfulServices>(binding, new Uri(uri));
IRestfulServices channel = factory.CreateChannel(address, new Uri(uri));
channel.getData(new Person{firstName = 'John', LastName = 'Doe'});
[ServiceContract]
public interface IRestfulService
{
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, UriTemplate = "Data")]
object getData(Person name)
}
I believe the DataContract object needs to have a parameterless constructor for the serializer to work correctly. I.e. public Person() { }, also you may need to add getters and setters for your public members, public string FirstName{ get; set; }.
Problem:
Getting an empty JSON response of { }
The Interface:
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Client/{idsHashed}", ResponseFormat = WebMessageFormat.Json)]
Summary GetClientDataById(string idsHashed);
The web method:
public Summary GetClientDataById(string idsHashed)
{
Summary clientSum = new Summary().GetClientDataById(clientId);
return clientSum;
}
In the class, I had turned the fields to internal and private!!!
public class Summary
{
private string clientName { get; set; } //<-- wont be rendered out as json because its private
Solution:
Check class properties are Public.
1.Method name is not required for the restful wcf.
2.Json deserializer does not require parameter name, it treat it as property name.
So use {""name"" :{""FirstName"":""John"", ""LastName"":""Doe""}" instead of
{""getData"" : {""name"" :{""FirstName"":""John"", ""LastName"":""Doe""}}.

Categories

Resources