问题描述
我正在尝试将图像 url 字符串添加到数据库中访问者的 Badge 属性。我有一个页面,我从数据库中调用访问者的实例,然后从访问者那里格式化一些信息,对其进行截图,并生成一个图像 url。 OnGetAsync 工作正常,但是,我无法在 OnPostAsync 期间获取要发布到服务器的 url。我已经将问题缩小到表单标签,因为当我尝试使用表单标签 method=post 发布数据时,访问者的实例丢失了,因此 ModelState 无效(当表单标签被删除时,url生成,所以我知道它不是 BadgeDataUrl 为空)。
为什么访问者实例会重置?我一直在搜索其他帖子,但没有看到任何人有类似的重置问题。我还尝试在 OnPostAsync 中再次设置访问者,但 ModelState 仍然无效,因为它将访问者的属性视为空(这很奇怪,因为当我为属性添加监视时,数据正确显示 - 我是不知道为什么 ModelState 是无效的)。
注册成功.cshtml.cs
public async Task<IActionResult> OnGetAsync(string visitorId)
{
if (visitorId == null)
{
return NotFound();
}
Visitor = await _context.Visitor.FirstOrDefaultAsync(m => m.ID.ToString() == visitorId);
if (Visitor == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
//Badge processing
var base64Badge = BadgeDataUrl.Split(",")[1];
var binaryBadge = Convert.FromBase64String(base64Badge);
System.IO.File.WriteallBytes("Badge.jpg",binaryBadge);
Visitor.FutureBadge = BadgeDataUrl;
_context.Attach(Visitor).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (dbupdateConcurrencyException)
{
if (!VisitorExists(Visitor.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("/Visitors/RegistrationSuccess");
}
private bool VisitorExists(int id)
{
return _context.Visitor.Any(e => e.ID == id);
}
注册成功.cshtml
@page "{visitorId}"
@model VisitorManagementSystem.Pages.Visitors.RegistrationSuccessModel
@{
}
@{
ViewData["Title"] = "Success";
}
<head>
<Meta charset="utf-8">
<Meta name="viewport" content="width=device-width,initial-scale=1">
<title>HTML TO IMAGE</title>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script type="text/javascript">
function downloadimage() {
var container = document.getElementById("htmltoimage");; // full page
html2canvas(container,{ allowTaint: true }).then(function (canvas) {
var badgeData = canvas.toDataURL("image/jpeg");
$('#BadgeDataUrl').val(badgeData);
});
}
</script>
<style>
#htmltoimage {
width: 65%;
margin: auto;
}
</style>
</head>
<body>
<form method="post">
<br />
<div id="htmltoimage">
<div id="badge" style=" Box-sizing: border-Box; background-color: white; border: 2px solid black; margin: 50px; padding: 0px; width: 10.15cm; height: 6.096cm">
<div style="text-align:center; float:left; padding:0; float:left; vertical-align:top; background-color:red; color:white; font-family:Arial; font-size:25px; width:10.06cm">
<label>VISITOR</label>
</div>
<div style="float:left">
<img style="margin-left:18px; margin-top:13px; border:1px solid black; width: 3.2cm; height:2.4cm" src="@Model.Visitor.Picture" alt="Visitor Picture" />
<div style="text-align:left; margin-left:15px; margin-top:9px; line-height:0.8; font-size:13px; padding:5px;">
<label>CCI Host:</label><br>
<label id="destinationlabel">@Model.Visitor.Destination</label><br><br />
</div>
</div>
<div style="float:right; margin-top:3px; margin-right:7px; margin-bottom:0px; font-family: Arial; vertical-align:top">
<label id="datelabel">@Model.Visitor.DateCheckedIn.ToShortDateString()</label>
</div>
<div style="float:left; line-height:0.8; vertical-align:top">
<div style="font-size:45px; margin-top: 30px; line-height:0.1; margin-bottom:5px; margin-left:20px; margin-right:0; font-weight: bold;">@Model.Visitor.FirstName</div><br />
<div style="font-size:45px; margin-top: 5px; margin-bottom:10px; margin-left:20px; margin-right:0; font-weight: bold;">@Model.Visitor.LastName</div>
<label id="companynamelabel" style="font-size:18px; margin-left: 20px">@Model.Visitor.CompanyName</label><br>
<label id="titlelabel" style="font-size:18px; margin-left:20px">@Model.Visitor.CompanyTitle</label>
</div>
<div style="padding: 0px; margin: 0px; position: absolute; bottom: 0; left: 0; width: 10.05cm; background-color: red; color: white; font-family: Arial; font-size: 15px; text-align: right">
<label id="bottomredbar"></label>
</div>
</div>
</div>
<button type="submit" onclick="downloadimage()" class="clickbtn" id="downloadButton">Download/Print Badge</button><br />
<div>
@*This is here just to check if the url is generating*@
<input asp-for="@Model.BadgeDataUrl">
</div>
</form>
</body>
我是新手,所以非常感谢您的帮助!
编辑
没有 ModelState 验证的 Registration.cshtml.cs:
public class RegistrationSuccessModel : PageModel
{
[BindProperty]
public Visitor Visitor { get; set; }
[BindProperty]
public string BadgeDataUrl { get; set; }
private readonly VisitorManagementSystem.Data.VisitorManagementSystemContext _context;
public RegistrationSuccessModel(VisitorManagementSystem.Data.VisitorManagementSystemContext context)
{
_context = context;
}
public async Task<IActionResult> OnGetAsync(string visitorId)
{
if (!string.IsNullOrEmpty(visitorId))
{
Visitor = _context.Set<Visitor>().FirstOrDefault(i => i.ID.ToString() == visitorId);
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string visitorId)
{
Visitor = _context.Set<Visitor>().FirstOrDefault(i => i.ID.ToString() == visitorId);
var base64Badge = BadgeDataUrl.Split(",")[1];
var binaryBadge = Convert.FromBase64String(base64Badge);
System.IO.File.WriteallBytes("Badge.jpg",binaryBadge);
Visitor.FutureBadge = BadgeDataUrl;
_context.Attach(Visitor).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (dbupdateConcurrencyException)
{
if (!VisitorExists(Visitor.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("/Visitors/RegistrationSuccess");
}
private bool VisitorExists(int id)
{
return _context.Visitor.Any(e => e.ID == id);
}
}
解决方法
-
Visitor
值在 OnGet 方法中设置而不是全局设置。所以你不能把它保留在另一个请求中。此外,您使用BindProperty
并且此属性用于绑定您场景中表单的值。 -
但是您使用了无法绑定到后端的标签元素。一种方法是您可以通过使用 jquery 获取元素值并通过 ajax 发布它们(如果您想在回发时执行任何操作,这将有点复杂)。另一种方法是为每个属性设置隐藏输入。
-
如果你使用
type="submit"
输入,它不会点击 onclick 事件。您需要更改为type="button"
。 -
html2canvas.js
的引用在我的项目中出错。所以我改成:<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.1.4/dist/html2canvas.min.js"></script>
这是一个完整的工作演示:
Registration.cshtml:
<head>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.1.4/dist/html2canvas.min.js"></script>
<script type="text/javascript">
function downloadimage() {
var container = document.getElementById("htmltoimage");; // full page
html2canvas(container,{ allowTaint: true }).then(function (canvas) {
var badgeData = canvas.toDataURL("image/jpeg");
$('#BadgeDataUrl').val(badgeData);
$('form').submit(); //add this...
});
}
</script>
</head>
<body>
<form method="post"> //add hidden input to make form data post successfully....
<input asp-for="Visitor.Destination" hidden />
<input asp-for="Visitor.DateCheckedIn" hidden />
<input asp-for="Visitor.FirstName" hidden />
<input asp-for="Visitor.LastName" hidden />
<input asp-for="Visitor.CompanyName" hidden />
<input asp-for="Visitor.CompanyTitle" hidden />
<input asp-for="Visitor.Picture" hidden />
<br />
<div id="htmltoimage">
<div id="badge" style=" box-sizing: border-box; background-color: white; border: 2px solid black; margin: 50px; padding: 0px; width: 10.15cm; height: 6.096cm">
<div style="text-align:center; float:left; padding:0; float:left; vertical-align:top; background-color:red; color:white; font-family:Arial; font-size:25px; width:10.06cm">
<label>VISITOR</label>
</div>
<div style="float:left">
<img style="margin-left:18px; margin-top:13px; border:1px solid black; width: 3.2cm; height:2.4cm" src="@Model.Visitor.Picture" alt="Visitor Picture" />
<div style="text-align:left; margin-left:15px; margin-top:9px; line-height:0.8; font-size:13px; padding:5px;">
<label>CCI Host:</label><br>
<label id="destinationlabel">@Model.Visitor.Destination</label><br><br />
</div>
</div>
<div style="float:right; margin-top:3px; margin-right:7px; margin-bottom:0px; font-family: Arial; vertical-align:top">
<label id="datelabel">@Model.Visitor.DateCheckedIn.ToShortDateString()</label>
</div>
<div style="float:left; line-height:0.8; vertical-align:top">
<div style="font-size:45px; margin-top: 30px; line-height:0.1; margin-bottom:5px; margin-left:20px; margin-right:0; font-weight: bold;">@Model.Visitor.FirstName</div><br />
<div style="font-size:45px; margin-top: 5px; margin-bottom:10px; margin-left:20px; margin-right:0; font-weight: bold;">@Model.Visitor.LastName</div>
<label id="companynamelabel" style="font-size:18px; margin-left: 20px">@Model.Visitor.CompanyName</label><br>
<label id="titlelabel" style="font-size:18px; margin-left:20px">@Model.Visitor.CompanyTitle</label>
</div>
<div style="padding: 0px; margin: 0px; position: absolute; bottom: 0; left: 0; width: 10.05cm; background-color: red; color: white; font-family: Arial; font-size: 15px; text-align: right">
<label id="bottomredbar"></label>
</div>
</div>
</div>
//change here....
<button type="button" onclick="downloadimage()" class="clickbtn" id="downloadButton">Download/Print Badge</button><br />
<div>
<input asp-for="@Model.BadgeDataUrl">
</div>
</form>
</body>