我有一个动作方法,动态生成验证码图像并作为二进制文件返回。在我的视图页面上,我可以在页面加载时显示验证码。我还有一个刷新链接,调用action方法使用$ .ajax获取新的验证码图像,单击时不显示新的验证码图像。 $ .jax调用成功完成,但二进制文件未显示。我想在单击刷新链接时显示新图像而不重新加载整个页面。
我是否遗漏了某些内容,或者是否有另一种方法来调用操作方法而不使用jquery刷新页面。任何帮助,将不胜感激。以下是我的代码
//生成图像的动作方法
public class HomeController : Controller
{
public FileContentResult CaptchaImage(bool noisy = true)
{
var rand = new Random((int)DateTime.Now.Ticks);
//generate new question
int a = rand.Next(10, 99);
int b = rand.Next(0, 9);
var captcha = string.Format("{0} + {1} = ?", a, b);
//store answer
Session["Captcha"] = a + b;
//image stream
FileContentResult img = null;
using (var mem = new MemoryStream())
using (var bmp = new Bitmap(130, 30))
using (var gfx = Graphics.FromImage((Image)bmp))
{
gfx.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.FillRectangle(Brushes.White, new Rectangle(0, 0, bmp.Width, bmp.Height));
//add noise
if (noisy)
{
int i, r, x, y;
var pen = new Pen(Color.Yellow);
for (i = 1; i < 10; i++)
{
pen.Color = Color.FromArgb(
(rand.Next(0, 255)),
(rand.Next(0, 255)),
(rand.Next(0, 255)));
r = rand.Next(0, (130 / 3));
x = rand.Next(0, 130);
y = rand.Next(0, 30);
gfx.DrawEllipse(pen, x - r, y - r, r, r);
}
}
//add question
gfx.DrawString(captcha, new Font("Tahoma", 15), Brushes.Gray, 2, 3);
//render as Png
bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Png);
img = this.File(mem.GetBuffer(), "image/png");
}
return File(img.FileContents, img.ContentType);
}
}
//查看调用操作方法以显示验证码的页面
<a id="GetCaptcha" href="javascript:void(0)">Refresh</a>
<img id="CaptchaImg" alt="Captcha" src="@Url.Action("CaptchaImage")" style="" />
@section Scripts{
@Scripts.Render("~/bundles/jqueryval")
<script>
$(function () {
$('#GetCaptcha').click(function () {
$.ajax({
type: "GET",
url: '@Url.Action("CaptchaImage")',
contentType: "image/png",
success: function (data) {
alert("Success"); // For testing
$('#CaptchaImg').attr('src', "data:image/png;base64," + data);
},
error: function(error, txtStatus) {
console.log(txtStatus);
console.log('error');
}
});
});
});
</script>
}
答案 0 :(得分:0)
action方法没有生成base64编码的字符串,它正在创建一个完整的文件响应。
因此,要刷新验证码图像,您无需更新现有图像上的源,而是创建新的<img src="/home/captchaimage?randomString">
元素并用它替换现有的验证码图像。
缓存很可能是一个问题,因此您需要生成一个唯一的字符串以附加到路径,例如随机数或当前日期时间,因此每个请求都是唯一的。
否则,您可以更改action方法以返回base64字符串,然后将视图中的<img src="@Url.Action..
更改为<img src="data:image/png;base64,@Html.Action(...
或类似内容。