Hi,
I am trying to implement Kendo Captcha. I tried to implement same way as in this article.
ASP.NET MVC Captcha Component Validation - Telerik UI for ASP.NET MVC
But I am getting below error. what am I doing wrong?
My code is like this
@(Html.Kendo().Captcha() .Name("Captcha") .CaptchaImage((string)ViewData["Captcha"]) .CaptchaId((string)ViewData["CaptchaID"]) .DataCaptchaField("Captcha") // The field containing the Captcha from the server-side should be called Captcha. .DataCaptchaIdField("CaptchaID") // The field containing the Captcha's ID from the server-side should be called CaptchaID. .Handler(handler => handler.Action("Reset", "IUA")) .ValidationHandler(handler => handler.Action("Validate", "IUA")) .ValidateOnBlur(true) )
namespace Portal.Controllers { public class IuaController : Controller { // GET: Iua public ActionResult Index ( string pin ) { var model = portalServices.getExistingData(); if (string.IsNullOrEmpty(model.CaptchaID)) { GenerateNewCaptcha(); } else { CaptchaImage captchaImage = (CaptchaImage)Session["captcha" + model.CaptchaID]; if (captchaImage != null && CaptchaHelper.Validate(captchaImage, model.Captcha.ToUpperInvariant())) { ModelState.Clear(); GenerateNewCaptcha(); } } //return View(); return View(model); } private void GenerateNewCaptcha() { CaptchaImage captchaImage = CaptchaHelper.GetNewCaptcha(); Session["captcha" + captchaImage.UniqueId] = captchaImage; ViewData["Captcha"] = GetCatchaImage(captchaImage.UniqueId);//Url.Action("image", "IUA", new { captchaId = captchaImage.UniqueId }); ViewData["CaptchaID"] = captchaImage.UniqueId; } public ActionResult Reset() { CaptchaImage newCaptcha = CaptchaHelper.GetNewCaptcha(); Session["captcha" + newCaptcha.UniqueId] = newCaptcha; return Json(new { captcha = GetCatchaImage(newCaptcha.UniqueId),//Url.Action("image", "IUA", new { captchaId = newCaptcha.UniqueId }), captchaId = newCaptcha.UniqueId }, JsonRequestBehavior.AllowGet); } public ActionResult Image(string captchaId) { CaptchaImage captcha = (CaptchaImage)Session["captcha" + captchaId]; var image = CaptchaHelper.RenderCaptcha(captcha); byte[] bmpBytes; using (MemoryStream ms = new MemoryStream()) { image.Save(ms, ImageFormat.Png); bmpBytes = ms.ToArray(); } return File(bmpBytes, "image/png"); } public ActionResult GetCatchaImage(string captchaId) { CaptchaImage captcha = (CaptchaImage)Session["captcha" + captchaId]; var image = CaptchaHelper.RenderCaptcha(captcha); byte[] bmpBytes; using (MemoryStream ms = new MemoryStream()) { image.Save(ms, ImageFormat.Png); bmpBytes = ms.ToArray(); } return File(bmpBytes, "image/png"); } public ActionResult Audio(string captchaId) { CaptchaImage captcha = (CaptchaImage)Session["captcha" + captchaId]; byte[] bmpBytes; using (MemoryStream audio = CaptchaHelper.SpeakText(captcha)) { bmpBytes = audio.ToArray(); } return File(bmpBytes, "audio/wav"); } public ActionResult Validate(string captchaId, string captcha) { CaptchaImage captchaImage = (CaptchaImage)Session["captcha" + captchaId]; return Json(CaptchaHelper.Validate(captchaImage, captcha.ToUpperInvariant()), JsonRequestBehavior.AllowGet); } } } Model class public class IuaModel { [Key] public string Pin { get; set; } [Display(Name = "Ticket #")] public long Id { get; set; } [Required] [Display(Name = "First Name")] public string FirstName { get; set; } [Display(Name = "Middle Initial")] public string MiddleInitial { get; set; } [Required] [Display(Name = "Last Name")] public string LastName { get; set; } [Display(Name = "Facility Name")] public string FacilityName { get; set; } private string _captchaValue; public string Captcha { get { return string.IsNullOrEmpty(_captchaValue) ? "" : _captchaValue; } set { _captchaValue = value; } } public string CaptchaID { get; set; } }
I'm using Captcha for MVC.
I got everything working on ASP.Net 6, except for the Reset.
The Reset-Endpoint is called properly and gives back sucess with the CaptchaModel (captchaUrl, captchaId).
But the Url is not set in the src-Tag of the Captcha-Image, so the Endpoint for getting the rendered Captcha-Image is not called, instead the src-tag is just emptied and the field becomes grey.
When I set the Image-Url I got in the xhr-Request into the src-Tag manually it works as expected.
Audio and Validation working as expected.
XHR:
View Code:
<p>Captcha:</p>
@(Html.Kendo().Captcha()
.Name("captcha")
.CaptchaImage((string)ViewData["Captcha"])
.CaptchaId((string)ViewData["CaptchaID"])
.DataCaptchaField("Captcha")
.DataCaptchaIdField("CaptchaID")
.Handler(handler => handler.Action("Reset", "Captcha"))
.AudioHandlerFunction("audioHandler")
.ValidationHandler(handler => handler.Action("Validate", "Captcha"))
.ValidateOnBlur(true)
.ResetButton(true)
.AudioButton(true)
)
<script>
$(document).on("kendoReady",
function() {
$("#mailform").kendoValidator();
});
function audioHandler(args) {
args.success("@Url.Action("Audio", "Captcha")?captchaId=" + args.data.CaptchaID);
}
</script>
Controller:
public class CaptchaController : Controller
{
public ActionResult Image(string captchaId)
{
CaptchaImage captcha = (CaptchaImage)HttpContext.Session.Get<CaptchaImage>("captcha" + captchaId);
var image = CaptchaHelper.RenderCaptcha(captcha);
byte[] bmpBytes;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
bmpBytes = ms.ToArray();
}
return File(bmpBytes, "image/png");
}
[HttpGet]
public ActionResult Reset()
{
CaptchaImage newCaptcha = CaptchaHelper.GetNewCaptcha();
HttpContext.Session.Set("captcha" + newCaptcha.UniqueId, newCaptcha);
return Json(new CaptchaModel { Captcha = Url.Action("image", "captcha", new { captchaID = newCaptcha.UniqueId }), CaptchaID = newCaptcha.UniqueId });
}
public ActionResult Audio(string captchaId)
{
CaptchaImage captcha = (CaptchaImage)HttpContext.Session.Get<CaptchaImage>("captcha" + captchaId);
byte[] bmpBytes;
using (MemoryStream audio = CaptchaHelper.SpeakText(captcha))
{
bmpBytes = audio.ToArray();
}
return File(bmpBytes, "audio/wav");
}
[HttpGet]
public ActionResult Validate(CaptchaModel model)
{
CaptchaImage captchaImage = (CaptchaImage) HttpContext.Session.Get<CaptchaImage>("captcha" + model.CaptchaID);
return Json(CaptchaHelper.Validate(captchaImage, model.Captcha.ToUpperInvariant()));
}
}