代码之家  ›  专栏  ›  技术社区  ›  Artorias2718

ASP.NET MVC:将模型数据存储为JSON字符串

  •  0
  • Artorias2718  · 技术社区  · 6 年前

    我正在(暂时)进行一个自学项目,创建一个会计软件包来管理客户、发票、估价等数据。

    我现在在做客户系统。我知道如何设置应用程序以将不同的数据段存储在不同的列中,但我想学习如何将所有内容存储为JSON字符串。

    [Table("Customers")]
    public partial class CustomerDb
    {
        public int Id { get; set; }
        public string Obj_Data { get; set; }
    }
    

    然后,我为各个数据段创建了一个客户模型:

    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值。然后我创建了一个单独的应用程序,其中formfields使用HTML/JavaScript输出一个JSON字符串,我可以复制/粘贴到其中。

    如果只是我在使用这个,那么粘贴在JSON字符串中也很好。假设我想为不同的用户设置我的应用程序,编辑一个缩小的JSON字符串是很麻烦的。

    我想基于上面定义的客户模型创建一个视图,并从CustomerController向数据库提交一个JSON字符串。有人能给我指出正确的方向吗?谢谢。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Artorias2718    6 年前

    如果我明白发生了什么:

    在CustomerController的updateget操作中,我只是将输入CustomerDb的Obj\u数据属性(在我的例子中是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属性。例如,我删除了Phones字典,并将其替换为primary、alternate和fax字符串属性,Emails字典现在是一个字符串。我确信有一种方法可以处理字典属性,但是每次我使用它们测试所有东西时,都会从它们那里得到一个空引用异常。

    然后,对各种控制器操作进行一些简单的编辑,以从数据库中添加和删除客户记录,并且工作得非常好。

    @山本铁树,再次感谢你的帮助。