C# ASP.NET以表单形式传递完整对象

C# ASP.NET以表单形式传递完整对象,c#,razor,asp.net-core,razor-pages,C#,Razor,Asp.net Core,Razor Pages,我有一个非常基本的问题,但似乎找不到解决办法 我有一个在我的OnGet方法中初始化的对象。我希望客户端更新信息,然后将其更新回数据库。(对象的某些信息仅存储在数据库中,但用户不可见或不可编辑) 现在,我试图以我的形式传递完整的对象,并结合来自客户机的输入。如果我尝试访问该对象,则所有属性都为null。相反,如果我试图在表单中仅将单个属性作为字符串传递,它就可以正常工作 这是我的代码: public class UpdateLicenseModel : PageModel { privat

我有一个非常基本的问题,但似乎找不到解决办法

我有一个在我的
OnGet
方法中初始化的对象。我希望客户端更新信息,然后将其更新回数据库。(对象的某些信息仅存储在数据库中,但用户不可见或不可编辑)

现在,我试图以我的形式传递完整的对象,并结合来自客户机的输入。如果我尝试访问该对象,则所有属性都为null。相反,如果我试图在表单中仅将单个属性作为字符串传递,它就可以正常工作

这是我的代码:

public class UpdateLicenseModel : PageModel
{
    private readonly license_backupContext _db;
    public UpdateLicenseModel(license_backupContext db)
    {
        _db = db;
    }
    public IList<License> Licenses { get; set; }

    [BindProperty]
    public License SelectedLicense { get; set; }


    [Auhtorize]
    public void OnGet()
    {
        Licenses = _db.License.ToList();
        SelectedLicense = Licenses.SingleOrDefault(s => s.Licenseid.ToString().Equals(LicenseString));
    }

    public IActionResult OnPost()
    {
        var license = SelectedLicense;
        if (!ModelState.IsValid)
        {
            return Page();
        }
        _db.License.Update(license);
        _db.SaveChanges();

        return RedirectToPage("./Licenses");
    }
}
public类UpdateLicenseModel:PageModel
{
私有只读许可证\u备份上下文\u数据库;
公共UpdateLicenseModel(许可证\备份上下文数据库)
{
_db=db;
}
公共IList许可证{get;set;}
[BindProperty]
公共许可证SelectedLicense{get;set;}
[补充]
公共互联网
{
许可证=_db.License.ToList();
SelectedLicense=Licenses.SingleOrDefault(s=>s.Licenseid.ToString().Equals(LicenseString));
}
public IActionResult OnPost()
{
var license=所选许可证;
如果(!ModelState.IsValid)
{
返回页();
}
_db.License.Update(许可证);
_db.SaveChanges();
返回重定向Topage(“/许可证”);
}
}
在上面的代码中,OnPost中的许可证成员仅在用户编辑内容的字段中具有值,所有其他字段均为null(不应为null)

这是我的表格(简化):


身份证件
名称

您不能以您尝试过的方式在HTML表单中发布.NET对象。您只能发布其成员值,并让ModelBinding在服务器上为您构造对象

通常,您会使用隐藏字段存储选定对象的键值,然后使用该值确定数据库中需要更新的数据行


或者,您可以将
SelectedLicense
序列化为JSON,然后使用Base64或类似工具对其进行编码,并将其存储在隐藏字段中。然后可以在服务器上对其进行解码和反序列化。但是,精明的用户可以在浏览器中访问该值,并可以自己解码。

您不能以您尝试过的方式在HTML表单中发布.NET对象。您只能发布其成员值,并让ModelBinding在服务器上为您构造对象

通常,您会使用隐藏字段存储选定对象的键值,然后使用该值确定数据库中需要更新的数据行


或者,您可以将
SelectedLicense
序列化为JSON,然后使用Base64或类似工具对其进行编码,并将其存储在隐藏字段中。然后可以在服务器上对其进行解码和反序列化。然而,精明的用户将能够访问浏览器中的值,并可以自己解码。

谢谢,这解释了很多。不过,我很好奇什么是最佳实践。我应该传递对象的ID,然后在my
OnPost
中再次加载对象列表并根据ID找到它吗?您可以再次加载它,也可以根据提交的值进行更新。如果您使用的是EntityFrameworkCore,您将使用主键值创建存根对象,附加该对象,并将提交的属性值设置为已修改:谢谢,这解释了很多。不过,我很好奇什么是最佳实践。我应该传递对象的ID,然后在my
OnPost
中再次加载对象列表并根据ID找到它吗?您可以再次加载它,也可以根据提交的值进行更新。如果您使用的是Entity Framework Core,则应使用主键值创建存根对象,附加该对象,并将提交的属性值设置为已修改:
<form method="post">
<div class="row">
    <div class="col-6 form-group">
        <label for="ID"><b>ID</b></label>
        <input class="form-control input-sm" id="ID" value="@Model.SelectedLicense.ID" asp-for="SelectedLicense.ID" />
    </div>
    <div class="col-6 form-group">
        <label for="Name"><b>Name</b></label>
        <input class="form-control input-sm" id="Name" value="@Model.SelectedLicense.Name" asp-for="SelectedLicense.Name" />
    </div>
</div>
<div class="row">
    <div class="col">
        <input type="submit" class="btn btn-success" value="Speichern" />
    </div>
</div>
<input type="hidden" asp-for="SelectedLicense" />
</form>