asp.net-mvc-4 - ASP.NET MVC:将模型数据存储为 JSON 字符串
问题描述
我正在开展一个(暂时)自学项目,以创建一个会计软件包来管理客户、发票、估计等数据。
我目前正在开发客户系统。我知道如何设置应用程序以将不同的数据存储在不同的列中,但我想学习如何将所有内容存储为 JSON 字符串。
楷模:
[Table("Customers")]
public partial class CustomerDb
{
public int Id { get; set; }
public string Obj_Data { get; set; }
}
然后,我为各个数据创建了一个 Customer 模型:
public partial class Customer
{
public int Company_Id { get; set; }
public string Customer_Name { get; set; }
public string Customer_Company { get; set; }
public Dictionary<string, string> Phones { get; set; }
public List<Dictionary<string, string>> Emails { get; set; }
public string Terms { get; set; }
public Dictionary<string, string> Locations { get; set; }
public Dictionary<string, string> Preferences { get; set; }
public string Exemptions { get; set; }
}
添加新客户视图:
@model BSheets.Models.Custom.CustomerDb
@{
ViewBag.Title = "Add";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Customer</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Obj_Data, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.Obj_Data, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Obj_Data, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Add" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
客户控制器:
using BSheets.Models;
using BSheets.Models.Custom;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
namespace BSheets.Controllers
{
public class CustomerController : Controller
{
private BSheetsEntities _db = new BSheetsEntities();
private ViewModel _vm = new ViewModel();
// GET: Customer
public ActionResult Index(string search)
{
_vm.Companies = _db.Companies.ToList();
_vm.Customers = _db.Customers.ToList();
if (string.IsNullOrEmpty(search))
{
AllResults();
}
else
{
FilteredResults(search);
}
return View();
}
public PartialViewResult AllResults()
{
return PartialView(Json(_vm));
}
public PartialViewResult FilteredResults(string search)
{
return PartialView(Json(_vm));
}
// GET: Customer/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
CustomerDb customer = _db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// GET: Customer/Add
public ActionResult Add()
{
return View();
}
// POST: Customer/Add
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add([Bind(Include = "ID,Obj_Data")] CustomerDb customer)
{
if (ModelState.IsValid)
{
_db.Customers.Add(customer);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
// GET: Clients/Update/5
public ActionResult Update(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
CustomerDb customer = _db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// POST: Clients/Update/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Update([Bind(Include = "ID,Obj_Data")] CustomerDb customer)
{
if (ModelState.IsValid)
{
_db.Entry(customer).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
// GET: Clients/Remove/5
public ActionResult Remove(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
CustomerDb customer = _db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// POST: Clients/Remove/5
[HttpPost, ActionName("Remove")]
[ValidateAntiForgeryToken]
public ActionResult RemoveConfirmed(int id)
{
CustomerDb customer = _db.Customers.Find(id);
_db.Customers.Remove(customer);
_db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_db.Dispose();
}
base.Dispose(disposing);
}
}
}
从某种意义上说,我设法完成了这项工作:添加/更新客户信息的视图有一个 TextArea,我只需在其中添加 JSON 字符串。然后,在 Customer Index 视图中,我将 JSON 字符串反序列化为 Customer 对象并显示各个 Customer 值。然后,我使用 HTML/JavaScript 创建了一个带有表单字段的单独应用程序,以吐出我可以复制/粘贴到的 JSON 字符串。
如果只是我在使用它,那么就像粘贴到 JSON 字符串中一样,这完全没问题。假设我想为不同的用户设置我的应用程序,编辑一个缩小的 JSON 字符串很麻烦。
我想根据上面定义的 Customer 模型创建一个视图,并从 CustomerController 向数据库提交一个 JSON 字符串。有人可以指出我正确的方向吗?谢谢。
解决方案
我休息了几个星期,终于想出了一个答案。如果我理解发生了什么:
在 CustomerController 的 Update GET 操作中,我只是将输入 CustomerDb 的 Obj_Data 属性(在我的例子中是 JSON 字符串)反序列化为 Customer 对象。然后我将 Customer 对象传递回视图,到目前为止它运行良好(当然我绑定了相关的模型属性):
// GET: Clients/Update/5
public ActionResult Update(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
CustomerDb customerDb = _db.Customers.Find(id);
if (customerDb == null)
{
return HttpNotFound();
}
Customer customer = JsonConvert.DeserializeObject<Customer>(customerDb.Obj_Data);
return View(customer);
}
// POST: Clients/Update/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Update([Bind(Include = "Id,Customer_Name,Customer_Company,Phones,Emails,Terms,Locations,Preferences,Exemptions")] Customer customer)
{
if (ModelState.IsValid)
{
_db.Entry(customer).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
有几件事我必须改变;对于客户模型,我必须用单独的字符串属性替换 Dictionary 属性。例如,我删除了电话词典并将其替换为主要、备用和传真字符串属性,而电子邮件词典现在是一个字符串。我确信有一种方法可以使用 Dictionary 属性,但是每次我使用它们测试所有内容时,我都会从它们那里得到一个 Null 引用异常。
然后,对各种控制器操作进行一些简单的编辑,以从数据库中添加和删除客户记录,它工作得非常好。
@Tetsuya Yamamoto,再次感谢您的帮助。
推荐阅读
- javascript - Promise.all 导致 Jest 显示 UnhandledPromiseRejectionWarning
- python - 使用 XPath 在内部属性中接收数据
- tensorflow - 将神经网络拆分为 2 个微服务
- python - 如何使用 Graph API 和用户令牌抓取 Facebook 数据?
- python - 理解模块/包的问题
- r - 在 R Shiny with Leaflet 中选择多个过滤器选项的问题
- laravel - Laravel 路由组问题(空白页)
- node.js - 在 chrome 扩展启动时加载最后查看的页面
- shell - 在awk中处理两个文件中的打印内容
- angular - 在 Angular 中显示 formControlName 的验证消息