我有以下实体模型:如何执行一个复杂的对象模型,通过一个POST请求
public class AssetLabel
{
public string QRCode { get; set; }
public string asset { get; set; }
public virtual IEnumerable<Conversation> Conversations { get; set; }
}
public class Conversation
{
public int ID { get; set; }
public virtual AssetLabel AssetLabel{ get; set; }
public string FinderName { get; set; }
public string FinderMobile { get; set; }
public string FinderEmail { get; set; }
public ConversationStatus Status{ get; set; }
public IEnumerable<ConversationMessage> Messages { get; set; }
}
public class ConversationMessage
{
public int ID { get; set; }
public DateTime MessageDateTime { get; set; }
public bool IsFinderMessage { get; set; }
public virtual Conversation Conversation { get; set; }
}
public enum ConversationStatus { open, closed };
public class FinderViewModel : Conversation
{/*used in Controllers->Found*/
}
我的MVC应用程序会提示在POST请求QRCode
。然后我验证这个代码存在于数据库AssetLabel
中,并且其他一些服务器端逻辑得到满足。然后我需要请求用户联系人详细信息来创建一个新的Conversation
记录。 目前我有一个GET控制器操作,它返回第一个表单来捕获代码。如果这是有效的,那么我创建一个新的FinderViewModel
,用QRCode
的对象填充AssetLabel
,然后返回一个视图来使用虚拟机并显示Name
,Mobile
和Email
的字段。 我的问题是,虽然AssetLabel
作为FinderViewModel
的一部分传递给视图,我可以显示来自AssetLabel
的字段;图形对象AssetLabel
不会在POST中传回。我知道我可以修改FinderViewModel
,以便将Conversation
作为一个属性,并将QRCode
设置为单独的属性,该属性可以是表单中的隐藏字段,然后重新找到作为第二个处理的一部分的AssetLabel
形式,但这看起来像很多工作,因为我已经验证过一次,以创建第二个表单(这就是为什么我要离开PHP MVC框架)。
第一个问题是如何?第二个问题是我以错误的方式接近这种设计模式。是否有更多的.NETty方法来通过多种形式保存数据?在我学习的这一刻,我并不想将信息存储在cookie中或使用ajax。
作为第一个表单POST,第二个视图和第二个表单POST的代码的其余部分参考下面显示(简化以消除不相关的逻辑)。
public class FoundController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Found
public ActionResult Index()
{
AssetLabel lbl = new AssetLabel();
return View(lbl);
}
[HttpPost]
public ActionResult Index(string QRCode)
{
if (QRCode=="")
{
return Content("no value entered");
}
else
{
/*check to see if code is in database*/
AssetLabel lbl = db.AssetLables.FirstOrDefault(q =>q.QRCode==QRCode);
if (lbl != null)
{
var vm = new FinderViewModel();
vm.AssetLabel = lbl;
vm.Status = ConversationStatus.open;
return View("FinderDetails", vm);
}
else
{/*Label ID is not in the database*/
return Content("Label Not Found");
}
}
}
[HttpPost]
public ActionResult ProcessFinder(FinderViewModel vm)
{
/*
THIS IS WHERE I AM STUCK! - vm.AssetLabel == NULL even though it
was passed to the view with a fully populated object
*/
return Content(vm.AssetLabel.QRCode.ToString());
//return Content("Finder Details posted!");
}
FinderView.cshtml
@model GMSB.ViewModels.FinderViewModel
@{
ViewBag.Title = "TEST FINDER";
}
<h2>FinderDetails</h2>
@using (Html.BeginForm("ProcessFinder","Found",FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Finder Details</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.AssetLabel)
<div class="form-group">
@Html.LabelFor(model => model.FinderName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FinderName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FinderName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FinderMobile, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FinderMobile, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FinderMobile, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FinderEmail, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FinderEmail, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FinderEmail, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
渲染HTML代码段,用于AssetLabel
<input id="AssetLabel" name="AssetLabel" type="hidden"
value="System.Data.Entity.DynamicProxies.AssetLabel_32653C4084FF0CBCFDBE520EA1FC5FE4F22B6D9CD6D5A87E7F1B7A198A59DBB3"
/>
感谢斯蒂芬。 –