为什么我的模型数据在开机自检时被清除



如果这个问题简单或愚蠢,我很抱歉,我对MVC和Razor非常陌生,没有接受过任何最新的正式培训。。。

我不明白为什么我的模型中的数据在第一个视图中可用,而在第二个视图中不可用。

控制器使用代码启动模型实例

Product _Product = new Product();

然后在运行了一堆初始数据查询之后调用第一个视图。使用调用视图

return View("Attributes", _Product)

以调用向其传递模型的_Product实例的视图。

我的第一个视图做了很多事情,但与这个问题相关的是,它显示了一个表,该表使用数据集上的foreach行,由存储在模型上的控制器上的SQL填充。

@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(不包括其他两个视图,它们不使用Model,两者都有效)。。。

!!!注意:此代码用于每个人都对SQL server拥有SQL管理器和管理员权限的地方。因此,没有使用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="AddUpdate" />
</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>
}

如果你的最终问题是,"我如何用它的所有数据发布这个模型?",

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); 
}

期望模型绑定器能够构造CCD_ 2类的实例。要做到这一点,它需要让每个公共属性都作为表单值出现在向该控制器操作发出的HTTP请求中。这些表单值来自所谓的成功控件,它基本上是任何具有名称(name="propertynamehere"属性)的表单元素(通常为<input /><select><textarea>)。如果字段不存在,则其值不存在。

考虑到DataSet类的复杂性,我不建议尝试构建足够的表单字段来成功地从模型绑定器中取回数据。您唯一真正应该关心的是RowSelected,它可以让您从数据库中获取所需的数据。考虑到SQL连接和查询通常都很快,这可能也是一种更好的用户体验,因为发布足够的数据来重新填充数据集需要大量的表单值(你甚至可能会遇到超过允许的最大字段数的问题,尽管这在ASP.NET中是可配置的),我可以详细说明如何重构至少这个操作,以匹配MVC的工作方式。

需要注意的是,如果目标是将用户带到编辑页面,那么作为GET请求更有意义;加载编辑屏幕是一个幂等操作,它与GET的语义相匹配。POST通常是用来更新值的,而您在那里并没有这样做。

您可能会发现这很有用,因为它描述了建议遵循的模式(PRG或POST重定向GET):https://en.wikipedia.org/wiki/Post/Redirect/Get

当然,如果你正在学习的材料是旧的,ASP.NET(通过WebForms)使用POST来传输一种名为ViewState的东西,它过去/现在用于在web应用程序中产生状态错觉-这个想法是"Windows Forms for the web",但它增加了很多开销,而这在现代应用程序中是你真正不想要的。考虑到您的背景,它(WebForms)可能更适合您,因为它可以让您专注于事件驱动的开发模型。

表单没有任何用于构建模型的数据。

退一步考虑正在进行的HTTP请求。HTML<form>在提交时请求操作URL(在本例中为POST请求),并包括该表单中存在的任何表单值。这可能不包括禁用的表单元素。(我可能搞错了。)而且它肯定不包括表单的HTML。

(你已经表明你不是来自WebForms背景,但巧合的是,对于那些来自WebForms的人来说,这是一个非常常见的错误。)

除了按钮之外,我看到的唯一表单元素是三个下拉列表(ApplyGroup、AttributeName、AttributeValue)以及循环中发出的单选按钮,称为RowSelected

但该模型需要创造更多的价值:

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注入是一件坏事,这很好。尽管在你的特定情况下,这不一定是安全问题,但请注意,SQL注入也是一个非常常见的错误来源。值得学习正确的做法。)

如果您可以使用标识符从数据库中获得完全填充的模型,那将是理想的选择。只传递标识符肯定比传递整个复杂模型更容易,尤其是如果您不希望用户在该页面上编辑该模型。

总而言之,看起来你只是希望整个模型发布到服务器上,而实际上你发布的只是模型的标识符。幸运的是,这正是你真正需要的。只需使用该标识符即可获取所需的记录。

相关内容

最新更新