很抱歉,如果这只是一个简单或愚蠢的问题,我对MVC和Razor还是陌生的,因为没有接受任何最新的正式培训而深陷其中。
我不明白为什么第一个视图中可用模型中的数据,而第二个视图中不可用。
控制器使用代码初始化模型的实例
Product _Product = new Product();
然后在运行一堆初始数据查询后调用第一个视图。使用
调用该视图return View("Attributes", _Product)
调用传递视图的视图作为模型的_Product实例。
我的第一个视图做了很多事情,但是与此问题相关,它显示了一个表,该表使用SQL填充在模型上存储的控制器上的数据集上的foreach行。
@foreach(DataRow row in Model.attList.Tables[0].Rows)
该视图具有多个按钮,例如添加,删除,编辑...每个按钮都有自己的操作,例如
<input type="submit" class="btn btn-primary" name="action:btnDelete" value="Delete" />
如果用户按下该视图上触发HTTPPOST的按钮之一。其中一个调用新视图,但是如果我再次将模型传递给该视图,数据现在为空吗?我将模型传递给视图,并在HTTPPOST中接受它并将其传递给下一个视图(或者我认为)。
我正在使用非常通用的开始形式
@using (Html.BeginForm()) {
此按钮的控制器代码非常基本
[HttpPost]
[MultipleButton(Name = "action", Argument = "btnEditValues")]
public ActionResult btnEditValues(Product _Product)
{
return View("btnEditValues", _Product);
}
但是在第二个视图中,如果我尝试重新显示同一张表,现在它说我的Model.attList为空。我添加了console.log(@Model.attList);
的快速脚本,当我单击按钮时,它显示了第二个视图,但是控制台正在记录一个空白值(不是NULL,只是空白)...
我确定我只是缺少一些简单的东西-也许我正在尝试做一些我做不到的事情?
以下内容已从错误发布的“答案”中复制/粘贴(未进行编辑)到该问题中,该答案旨在对该问题进行编辑。答案已被标记,应删除。
根据David的要求。
这里是完整的M,V,V和C(不包括其他两个不使用模型且都正常工作的视图)...
!!!注意!!! :此代码在每个人都具有SQL管理器和SQL Server管理员权限的地方使用。因此,未使用SQL参数。如果在开放网站上使用,此代码将容易受到SQL注入的攻击。
型号
namespace P21.Rules.Visual.Areas.KCDA_ItemMaint_Attributes.Models
{
public class Product
{
// Variables used between views
public int RowSelected { get; set; }
// Declare datasets to use as list
public DataSet attList { get; set; }
public DataSet lowList { get; set; }
}
}
控制器
namespace P21.Rules.Visual.Areas.KCDA_ItemMaint_Attributes.Controllers
{
#region Multiple Buttons
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultipleButtonAttribute : ActionNameSelectorAttribute
{
public string Name { get; set; }
public string Argument { get; set; }
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
var isValidName = false;
var keyValue = string.Format("{0}:{1}", Name, Argument);
var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);
if (value != null)
{
controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
isValidName = true;
}
return isValidName;
}
}
#endregion
public class KCDA_ItemMaint_AttributesController : BaseRuleController
{
#region public variables
// public dataset for loading SQL values
DataSet attload = new DataSet();
DataSet lowload = new DataSet();
#endregion
#region Main Action
// GET: KCDA_ItemMaint_Attributes/KCDA_ItemMaint_Attributes
public ActionResult Attributes()
{
if (Data.Fields["item_id"].FieldValue == string.Empty)
{
// Report error and prevent form pop-up if no product group has been selected
Rule.RuleResult.Success = false;
Rule.RuleResult.Message = "You must first select an Item before listing Attributes";
return RedirectToAction("Close", "Initialize", new { area = "" });
}
else
{
try
{
// Create container and setup Group values
Product _Product = new Product();
//Get Attributes for selected item
LoadAttributes();
_Product.attList = attload.Copy();
//Get ECom Server Side Attribute for selected item
LoadLower();
_Product.lowList = lowload.Copy();
return View("Attributes", _Product);
}
catch (Exception ex)
{
//catch the error and send it to the Error view with the HandleErrorInfo
return View("Error", new HandleErrorInfo(ex, "KCDA_ItemMaint_Attributes", "Attributes"));
}
}
}
#endregion
#region Buttons
[HttpPost]
[MultipleButton(Name = "action", Argument = "btnDelete")]
public ActionResult btnDelete(Product _Product)
{
// create SQL command to delete the
string sqlDelete = "UPDATE BL_ProductAttribute SET DeleteFlag = '1' WHERE [KEY] = '" + _Product.RowSelected + "'";
// Run the sqlDELETE command
SqlCommand cmdDelete = new SqlCommand(sqlDelete, P21SqlConnection);
cmdDelete.ExecuteNonQuery();
SqlDataAdapter daDelete = new SqlDataAdapter(cmdDelete);
return View("btnDelete", _Product);
}
[HttpPost]
[MultipleButton(Name = "action", Argument = "btnAdd")]
public ActionResult btnAdd(Product _Product)
{
// Retrieve selected/loaded drop-down values
string ddGroup = Request["ApplyGroup"];
string ddName = Request["AttributeName"];
string ddValue = Request["AttributeValue"];
if (ddValue == "")
{
ViewBag.msg = "No Value Selected";
}
else
{
// default duplicate count to 0
int duplicate = 0;
// create SQL command to check for duplicate attribute
string sqlDuplicate = "SELECT COUNT(1) FROM BL_ProductAttribute " +
"WHERE SKU = '" + Data.Fields["item_id"].FieldValue + "' " +
"AND AttributeGroupName = '" + ddGroup + "'";
// Run the sqlDuplicate command
SqlCommand cmdDuplicate = new SqlCommand(sqlDuplicate, P21SqlConnection);
cmdDuplicate.CommandType = CommandType.Text;
SqlDataAdapter daDuplicate = new SqlDataAdapter(cmdDuplicate);
// Create dataset from duplicate check
DataTable dupcheck = new DataTable();
daDuplicate.Fill(dupcheck);
// Set count if exists
duplicate = int.Parse(dupcheck.Rows[0][0].ToString());
// if exists update/undelete otherwise insert
if (duplicate > 0)
{
// create SQL command to update the attribute
string sqlAdd = "UPDATE BL_ProductAttribute " +
"SET BL_ProductAttribute.Value = '" + ddValue.Replace("'", "''") + "', " +
"BL_ProductAttribute.AttributeTitle = '" + ddName + "', " +
"BL_ProductAttribute.DeleteFlag = 0, " +
"BL_ProductAttribute.ProductID = '" + Data.Fields["product_group_id"].FieldValue + "' " +
"FROM BL_ProductAttribute " +
"WHERE SKU = '" + Data.Fields["item_id"].FieldValue + "' AND AttributeGroupName = '" + ddGroup + "' ";
// Run the sqlAdd command
SqlCommand cmdAdd = new SqlCommand(sqlAdd, P21SqlConnection);
cmdAdd.ExecuteNonQuery();
SqlDataAdapter daAdd = new SqlDataAdapter(cmdAdd);
ViewBag.msg = "Record Updated";
}
else
{
// If adding determine next key value for unique ID
string newKey = string.Empty;
// create SQL command to get next KEY value for insert reset current maxkey
string sqlMax2 = "SELECT max([key])+1 FROM BL_AttributeEnumValue";
// Run the sqlMax command
SqlCommand cmdKey2 = new SqlCommand(sqlMax2, P21SqlConnection);
cmdKey2.CommandType = CommandType.Text;
SqlDataAdapter daKey2 = new SqlDataAdapter(cmdKey2);
// Create dataset from newKey check and assign to newKey
DataTable KeyCheck2 = new DataTable();
daKey2.Fill(KeyCheck2);
newKey = KeyCheck2.Rows[0][0].ToString();
// create SQL command to update the attribute
string sqlAdd = "INSERT INTO BL_ProductAttribute ([Key], ProductId, SKU, AttributeTitle, " +
"isSKUlevel, isRequired, isDefault, Value, AttributeGroupName, DeleteFlag) " +
"VALUES('" + newKey + "', '" + Data.Fields["product_group_id"].FieldValue + "', '" +
Data.Fields["item_id"].FieldValue + "', '" + ddName + "', 1, 1, 1, '" +
ddValue.Replace("'", "''") + "', '" + ddGroup + "', 0)";
// Run the sqlAdd command
SqlCommand cmdAdd = new SqlCommand(sqlAdd, P21SqlConnection);
cmdAdd.ExecuteNonQuery();
SqlDataAdapter daAdd = new SqlDataAdapter(cmdAdd);
ViewBag.msg = "Record Added";
}
}
return View("btnAdd", _Product);
}
[HttpPost]
[MultipleButton(Name = "action", Argument = "btnEditValues")]
public ActionResult btnEditValues(Product _Product)
{
return View("btnEditValues", _Product);
}
#endregion
#region SQL Loads
private void LoadAttributes()
{
// Define SQL select command
string sqlAttributes = "SELECT * FROM BL_ProductAttribute " +
"WHERE SKU = '" + Data.Fields["item_id"].FieldValue + "' AND DeleteFlag = '0' " +
" AND AttributeGroupName in ('SKU_Color', 'SKU_SelectableAttribute_1', 'SKU_SelectableAttribute_2')";
// Set SQL command type to text and run it
SqlCommand cmdlist = new SqlCommand(sqlAttributes, P21SqlConnection);
cmdlist.CommandType = CommandType.Text;
SqlDataAdapter dalist = new SqlDataAdapter(cmdlist);
// Load results from SQL into DataSet
dalist.Fill(attload);
}
private void LoadLower()
{
string DBconn = "vsldb1";
// Define SQL select command
string sqllist = "SELECT [Key], ProductID, SKU, AttributeTitle, isSKUlevel, isRequired, isDefault, " +
"\"Value\" = Case " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '0') then '0 - Warehouse Regular Item' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '1') then '1 - Not on Website/Pending' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '2') then '2 - RFQ' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '3') then '3 - Limited Quote' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '4') then '4 - Discontinued/Obsolete' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '5') then '5 - Specials' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '6') then '6 - Direct Ship' " +
"when (AttributeTitle = 'KCDASKUStatus' and ltrim(convert(varchar,Value)) = '7') then '7 - Offline' " +
"else value end, AttributeGroupName, UpdateFlag FROM OPENDATASOURCE('SQLOLEDB','Data Source=" + DBconn + ";user " +
"id=sa;password=KCDAAdmin').KCDA.dbo.KCDA_ProductAttribute PA" +
" WHERE PA.SKU = '" + Data.Fields["item_id"].FieldValue + "' AND PA.AttributeGroupName not in " +
"('SKU_Color', 'SKU_SelectableAttribute_1', 'SKU_SelectableAttribute_2')";
// Set SQL command type to text and run it
SqlCommand cmdlist = new SqlCommand(sqllist, P21SqlConnection);
cmdlist.CommandType = CommandType.Text;
SqlDataAdapter dalist = new SqlDataAdapter(cmdlist);
// Load results from SQL into DataSet
dalist.Fill(lowload);
}
#endregion
#region Drop Downs
[HttpPost]
public ActionResult GetAttributeNames(string selectedOption)
{
// Define variables for JSON query to use
JsonResult result = new JsonResult();
List<string> attNames = new List<string>();
List<string> attValues = new List<string>();
if (selectedOption != null)
{
// SQL to get attribute name for the selected attribute group for this product group
string sql = "SELECT Title FROM BL_Attribute (NOLOCK) WHERE BL_Attribute.DeleteFlag = '0' AND BL_Attribute.AttributeGroupName = '" + selectedOption + "'" +
" AND BL_Attribute.Title in (select AD.AttributeTitle from BL_AttributeDept AD where AD.product_group_id = '" + Data.Fields["product_group_id"].FieldValue.Substring(0, 2) +"')";
using (SqlCommand selectAttNames = new SqlCommand(sql, P21SqlConnection))
{
using (SqlDataReader reader = selectAttNames.ExecuteReader())
{
while (reader.Read())
{
attNames.Add(reader["Title"].ToString());
}
}
}
// SQL to get list of current available values for this attribute type
string sql2 = "SELECT Value FROM BL_AttributeEnumValue (NOLOCK) WHERE DeleteFlag = '0' and AttributeTitle = '" +
attNames[0] + "' ORDER BY Value";
using (SqlCommand selectAttValues = new SqlCommand(sql2, P21SqlConnection))
{
using (SqlDataReader reader2 = selectAttValues.ExecuteReader())
{
while (reader2.Read())
{
attValues.Add(reader2["Value"].ToString());
}
}
}
// define return object
var retObj = new
{
retNames = attNames,
retValues = attValues
};
return Json(retObj, JsonRequestBehavior.AllowGet);
}
return Json(new { Success = "false" });
}
#endregion
#region Edit Values
#endregion
#region Close Rule
[HttpPost]
public ActionResult Return()
{
Rule.RuleResult.Success = true;
//IMPORTANT - This is what returns the Visual Rule control back to the server
//DO NOT REMOVE
return RedirectToAction("Close", "Initialize", new { area = "" });
}
#endregion
}
}
属性视图
@using P21.Rules.Visual.Areas.KCDA_ItemMaint_Attributes.Models
@using System.Data
@model Product
@{
ViewBag.Title = "Attributes";
Layout = "~/Views/Shared/_VisualRuleLayout.cshtml";
var listAttGroups = new List<SelectListItem>
{
new SelectListItem { Text = "SKU_Color", Value = "SKU_Color"},
new SelectListItem { Text = "SKU Select Att 1", Value = "SKU_SelectableAttribute_1"},
new SelectListItem { Text = "SKU Select Att 2", Value = "SKU_SelectableAttribute_2"}
};
}
@section scripts{
<script>
$(function () {
$("#ApplyGroup").change(function () {
var option = $(this).val();
//Clear and activate 2nd and 3rd drop down
$("#AttributeName").empty();
$("#AttributeValue").empty();
$("#AttributeName").prop('disabled', false);
$("#AttributeValue").prop('disabled', false);
var url = "GetAttributeNames?selectedOption=" + option;
$.post(url, function (retObj) {
$.each(retObj.retNames, function (i, attName) {
$("#AttributeName").append($('<option></option>').val(attName).html(attName));
});
$.each(retObj.retValues, function (i, attValue) {
$("#AttributeValue").append($('<option></option>').val(attValue).html(attValue));
});
});
});
});
</script>
}
@using (Html.BeginForm())
{
<div class="container">
<div class="row">
<label class="col-md-3 control-label" for="ApplyGroup" id="lblApplyGroup">Attribute Group</label>
<label class="col-md-3 control-label" for="AttributeName" id="lblAttributeName">Attribute Name</label>
<label class="col-md-2 control-label" for="AttributeValue" id="lblAttributeValue">Attribute Value</label>
<div class="col-md-2">
<input type="submit" class="btn btn-primary" name="action:btnEditValues" value="Edit Values" />
</div>
</div>
<div class="row" style="padding-top:5px">
<div class="col-md-3">
@Html.DropDownList("ApplyGroup", listAttGroups, "Select Group", new { @id = "ApplyGroup", @class = "form-control" })
</div>
<div class="col-md-3">
@Html.DropDownList("AttributeName", new List<SelectListItem>(), new { @id = "AttributeName", @class = "form-control", disabled = "disabled" })
</div>
<div class="col-md-3">
@Html.DropDownList("AttributeValue", new List<SelectListItem>(), new { @id = "AttributeValue", @class = "form-control", disabled = "disabled" })
</div>
<div class="col-md-3">
<span class="pull-right">
<input type="submit" class="btn btn-primary" name="action:btnAdd" value="Add\Update" />
</span>
</div>
</div>
<div class="row" style="padding-top:20px">
<div class="col-md-10">
</div>
<div class="col-md-2">
<span class="pull-right">
<input type="submit" class="btn btn-primary" name="action:btnDelete" value="Delete" />
</span>
</div>
</div>
<div class="row" style="padding-top:10px">
<div class="col-md-12">
<table id="attTable" style="width:100%" cellpadding="0" cellspacing="0" border="1" class="row">
<tbody>
<tr style="background-color: #F0F8FF;">
<th></th>
<th>Dept</th>
<th>Item #</th>
<th>Attribute Name</th>
<th>SKU Level</th>
<th>Required</th>
<th>Default</th>
<th>Attribute Value</th>
<th>Attribute Group</th>
</tr>
@foreach (DataRow row in Model.attList.Tables[0].Rows)
{
<tr class="selectable-row">
<td>@Html.RadioButtonFor(m => Model.RowSelected, row[0])</td>
<td>@row[1]</td>
<td>@row[2]</td>
<td>@row[3]</td>
<td>@row[4]</td>
<td>@row[5]</td>
<td>@row[6]</td>
<td>@row[7]</td>
<td>@row[8]</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="row" style="padding-top:50px">
<div class="col-md-12">
<table id="lowTable" style="width:100%" cellpadding="0" cellspacing="0" border="1" class="row">
<tbody>
<tr style="background-color: #F0F8FF;">
<th>Dept</th>
<th>Item #</th>
<th>Attribute Name</th>
<th>SKU Level</th>
<th>Required</th>
<th>Default</th>
<th>Attribute Value</th>
<th>Attribute Group</th>
</tr>
@foreach (DataRow row in Model.lowList.Tables[0].Rows)
{
<tr class="selectable-row">
<td>@row[1]</td>
<td>@row[2]</td>
<td>@row[3]</td>
<td>@row[4]</td>
<td>@row[5]</td>
<td>@row[6]</td>
<td>@row[7]</td>
<td>@row[8]</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
}
btnEditValues视图
@using P21.Rules.Visual.Areas.KCDA_ItemMaint_Attributes.Models
@using System.Data
@model Product
@{
ViewBag.Title = "btnEditValues";
Layout = "~/Views/Shared/_VisualRuleLayout.cshtml";
var listAttGroups = new List<SelectListItem>
{
new SelectListItem { Text = "SKU_Color", Value = "SKU_Color"},
new SelectListItem { Text = "SKU Select Att 1", Value = "SKU_SelectableAttribute_1"},
new SelectListItem { Text = "SKU Select Att 2", Value = "SKU_SelectableAttribute_2"}
};
}
@section scripts{
<script>
console.log(@Model.attList);
</script>
}
<p align="right"><button type="button" class="btn btn-primary" onclick="location.href='@Url.Action("Attributes", "KCDA_ItemMaint_Attributes")'">X</button></p>
<center><h2>Edit Item Attribute Availble Values</h2></center>
@using (Html.BeginForm())
{
<div class="container">
<div class="row">
<label class="col-md-4 control-label" for="EditApplyGroup" id="lblEApplyGroup">Attribute Group</label>
<label class="col-md-4 control-label" for="EditAttributeName" id="lblEAttributeName">Attribute Name</label>
</div>
<div class="row" style="padding-top:5px">
<div class="col-md-4">
@Html.DropDownList("EditApplyGroup", listAttGroups, "Select Group", new { @id = "EditApplyGroup", @class = "form-control" })
</div>
<div class="col-md-4">
@Html.DropDownList("EditAttributeName", new List<SelectListItem>(), "Select Name", new { @id = "EditAttributeName", @class = "form-control", disabled = "disabled" })
</div>
</div>
<div class="row" style="padding-top:10px">
<div class="col-md-12">
<table id="attEditTable" style="width:100%" cellpadding="0" cellspacing="0" border="1" class="row">
<tbody>
<tr style="background-color: #F0F8FF;">
<th></th>
<th>Attribute Value</th>
<th>Item Count</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
}
答案 0 :(得分:2)
如果您的最终问题是:“如何发布带有所有数据的模型?”,
public class Product
{
// Variables used between views
public int RowSelected { get; set; }
// Declare datasets to use as list
public DataSet attList { get; set; }
public DataSet lowList { get; set; }
}
那么唯一的真实答案就是“做很多工作”。接下来的答案可能大多数都是自以为是的,因此,这并不是一个很好的SO答案,但是反映了我的经验。
基本上,此控制器操作:
[HttpPost]
[MultipleButton(Name = "action", Argument = "btnEditValues")]
public ActionResult btnEditValues(Product _Product)
{
// ... other code
return View("btnEditValues", _Product);
}
期望模型绑定器能够构造Product
类的实例。为此,它需要使每个公共属性都作为对此控制器操作发出的HTTP请求中的表单值存在。这些表单值来自successful controls,基本上是具有 name <的任何表单元素(通常是<input />
,<select>
或<textarea>
) / strong>(name="propertynamehere"
属性)。如果该字段不存在,则其值不存在。
鉴于DataSet
类的复杂程度,我不建议尝试构建足够的表单字段以成功从模型绑定程序中获取数据。您真正需要关心的唯一事情是RowSelected
-它使您可以从数据库中获取所需的数据。鉴于SQL连接和查询通常都非常快,因此也可能会带来更好的用户体验,因为发布足够的数据以重新填充DataSet需要很多表单值(您甚至可能会遇到超过最大允许数量的问题字段,尽管可以在ASP.NET中进行配置)。如果这有意义并且听起来很可行,那么我可以详细说明如何至少重构此操作以匹配MVC的工作方式。
请注意,如果目标是将用户带到编辑页面,那么将其作为GET请求更有意义;加载编辑屏幕是idempotent操作,它与GET的语义匹配。 POST通常用于更新值,而您在此处不这样做。
您可能会发现这很有用,因为它描述了建议遵循的模式(PRG或POST-Redirect-GET):https://en.wikipedia.org/wiki/Post/Redirect/Get
当然,如果您要学习的材料是较旧的,ASP.NET(通过WebForms)使用POST来传输称为ViewState的东西,这曾经/曾经给人一种状态错觉在Web应用程序中-这个想法是“ Windows的Web窗体”,但是它增加了很多您实际上不需要现代应用程序的开销。但是,根据您的背景,它(WebForms)可能更合适,因为它使您可以专注于事件驱动的开发模型。
答案 1 :(得分:1)
该表单没有用于构建模型的任何数据。
退后一步,考虑正在发出的HTTP请求。 HTML <form>
提交后,会请求操作URL(在这种情况下为POST请求),并包含该表单中存在的任何 form值。这可能不包括禁用的表单元素。 (对此我可能会弄错。)而且肯定不包含表单的HTML。
(您已经表明您不是来自WebForms背景的,但碰巧的是,这对于犯错的人来说是一个非常常见的错误。)
除了按钮之外,我看到的唯一表单元素是三个下拉列表(ApplyGroup,AttributeName,AttributeValue)以及循环中发出的名为RowSelected
的单选按钮。 / p>
但是该模型需要创建更多值:
public int RowSelected { get; set; }
// Declare datasets to use as list
public DataSet attList { get; set; }
public DataSet lowList { get; set; }
该模型具有RowSelected
,并且您可以调试以确认该值是否正确填充。 (您的问题仅表示您正在尝试调试DataSet
属性的存在,而不是RowSelected
属性的调试。)
但是包括来自两个DataSet
属性的所有数据将更加复杂。而且,也许更重要的是,这完全没有必要。退后一步,以为您将用用户不希望编辑的数据填充页面,然后将所有数据发布回刚来自的服务器。
在执行操作时,您可以通过多种方式获得该RowSelected
属性。作为方法参数,模型属性或仅在当前通过其他操作方法获取表单值时使用
string rowSelected = Request["RowSelected"];
如果需要,可以使用int.TryParse()
将其转换为整数值。尽管您正在使用的SQL代码是连接字符串,所以您仍然不需要这样做。
(附带说明:很好的是,您已经意识到SQL注入是一件坏事。即使在您的特定情况下,它不一定是 security 问题,请注意,SQL注入是也是非常常见的错误来源。值得学习正确的做事方式。)
如果您可以使用标识符从数据库中获取完整模型,那将是理想的选择。当然,仅传递标识符比传递整个复杂模型要容易得多,尤其是在您不希望用户在该页面上编辑该模型的情况下。
总而言之,当您实际上要发布的只是模型的标识符时,您似乎只是希望将整个模型发布到服务器。幸运的是,这实际上是您真正需要的。只需使用该标识符即可获取预期的记录。