为什么 form method=post 会重置一个数据实例?
Why is form method=post resetting a data instance?
我正在尝试将图像 url 字符串添加到数据库中的访问者徽章 属性。我有一个页面,我从数据库中调用访问者的实例,然后格式化来自访问者的一些信息,对其进行截图,并生成图像 url。 OnGetAsync 工作正常,但是,我无法在 OnPostAsync 期间将 url 到 post 发送到服务器。我已将问题缩小到表单标签,因为当我尝试使用表单标签方法 post 数据时 =post,访问者的实例丢失,因此 ModelState 无效(当删除表单标签时,会生成 url,所以我知道 BadgeDataUrl 不是空的)。
为什么访问者实例会重置?我一直在搜索其他 post,但没有看到任何人有类似的重置问题。我还尝试在 OnPostAsync 中再次设置访问者,但 ModelState 仍然无效,因为它将访问者的属性视为 null(这很奇怪,因为当我添加属性监视时,数据正确显示 - 我是不确定为什么 ModelState 无效)。
RegistrationSuccess.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);
}
RegistrationSuccess.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>
我是新手,非常感谢您的帮助!
编辑
Registration.cshtml.cs 没有 ModelState 验证:
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 和 post 来获取元素值 ajax (如果你想在 post 返回时做任何事情,这会有点复杂) .另一种方法是为每个 属性.
设置隐藏输入
如果你使用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>
我正在尝试将图像 url 字符串添加到数据库中的访问者徽章 属性。我有一个页面,我从数据库中调用访问者的实例,然后格式化来自访问者的一些信息,对其进行截图,并生成图像 url。 OnGetAsync 工作正常,但是,我无法在 OnPostAsync 期间将 url 到 post 发送到服务器。我已将问题缩小到表单标签,因为当我尝试使用表单标签方法 post 数据时 =post,访问者的实例丢失,因此 ModelState 无效(当删除表单标签时,会生成 url,所以我知道 BadgeDataUrl 不是空的)。
为什么访问者实例会重置?我一直在搜索其他 post,但没有看到任何人有类似的重置问题。我还尝试在 OnPostAsync 中再次设置访问者,但 ModelState 仍然无效,因为它将访问者的属性视为 null(这很奇怪,因为当我添加属性监视时,数据正确显示 - 我是不确定为什么 ModelState 无效)。
RegistrationSuccess.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);
}
RegistrationSuccess.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>
我是新手,非常感谢您的帮助!
编辑
Registration.cshtml.cs 没有 ModelState 验证:
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 和 post 来获取元素值 ajax (如果你想在 post 返回时做任何事情,这会有点复杂) .另一种方法是为每个 属性.
设置隐藏输入如果你使用
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>