ASP.NET MVC: хранить данные модели в виде строки JSON - PullRequest
0 голосов
/ 21 сентября 2018

Я работаю над (на данный момент) самообучающимся проектом по созданию пакета бухгалтерского программного обеспечения для управления данными о клиентах, счетах, сметах и ​​т. Д.

В настоящее время я работаю надКлиентская система.Я знаю, как настроить приложение для хранения разных фрагментов данных в разных столбцах, но я хотел узнать, как хранить все в виде строки JSON.

Модели:

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

Iзатем создал модель 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")
}

CustomerController:

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.Затем в представлении «Индекс клиента» я десериализирую строку JSON в объект Customer и отображаю отдельные значения Customer.Затем я создал отдельное приложение с полями формы, используя HTML / JavaScript, чтобы выплевывать строку JSON, в которую я могу копировать / вставлять.

Если бы это использовал только я, это прекрасно, как вставка в строку JSON.,Допустим, я хотел настроить приложение для другого пользователя, редактировать минимизированную строку JSON громоздко.

Я хотел бы создать представление на основе определенной выше модели Customer и отправить строку JSON в базу данных.из CustomerController.Может ли кто-нибудь указать мне правильное направление?Спасибо.

1 Ответ

0 голосов
/ 03 октября 2018

Я взял перерыв в этом на несколько недель, и я наконец-то нашел ответ.Если я понимаю, что происходит:

В действии Update GET CustomerController я просто десериализирую входное свойство Obj_Data CustomerDb (в моем случае это строка 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);
    }

Было несколько вещей, которые мне пришлось изменить;для модели заказчика мне пришлось заменить свойства словаря отдельными строковыми свойствами.Например, я удалил словарь телефонов и заменил его первичными, альтернативными и факсимильными строковыми свойствами, а словарь электронных писем теперь стал строкой.Я уверен, что есть способ работы со свойствами словаря, но каждый раз, когда я проверял все, используя их, я получал от них исключение ссылки Null.

Затем, некоторые простые изменения различных действий контроллера дляДобавляйте и удаляйте записи о клиентах из базы данных, и это работает очень хорошо.

@ Тецуя Ямамото, еще раз спасибо за помощь.

...