将 jQuery JSON 对象保存到 SQL 表中,而无需在 MVC ASP.NET Core 中创建视图模型类

Posted

技术标签:

【中文标题】将 jQuery JSON 对象保存到 SQL 表中,而无需在 MVC ASP.NET Core 中创建视图模型类【英文标题】:Save jQuery JSON object into SQL table without creating View model class in MVC ASP.NET Core 【发布时间】:2021-06-02 09:50:37 【问题描述】:

我正在从 URL 读取 JSON 数据并将其插入到 SQL 表中。我使用了这个示例 URL https://raw.githubusercontent.com/wedeploy-examples/supermarket-web-example/master/products.json 并创建了一个模型类文件,如下所示。

查看模型类

public class ApiJsonViewModel

    public string Title  get; set; 
    public string Type  get; set; 
    public string Description  get; set; 
    public string Filename  get; set; 
    public string Height  get; set; 
    public string Width  get; set; 
    public string Price  get; set; 
    public string Rating  get; set; 

我有一个带有一个文本框控件的表单,用于显示来自第三方 API URL 的 JSON 键数据和一个包含数据库值的下拉列表。

The model class used to populate dropdownlist

     public class K360DbCatgViewModel

    
        public string Name  get; set; 
        public string MetaTitle  get; set; 
        public string MetaKeywords  get; set; 
        public string MetaDescription  get; set;       
        public string ShortDescription  get; set; 
        public string Description  get; set; 
        public string Specification  get; set; 
        public decimal Price  get; set; 
        public decimal? OldPrice  get; set; 
        public decimal? SpecialPrice  get; set; 
        public DateTimeOffset? SpecialPriceStart  get; set; 
        public DateTimeOffset? SpecialPriceEnd  get; set;      
        public int StockQuantity  get; set; 
        public string Sku  get; set; 
        public string Gtin  get; set; 
        public string NormalizedName  get; set; 
        public int DisplayOrder  get; set;      
        public int ReviewsCount  get; set; 
        public double? RatingAverage  get; set;       
    

Razor 查看页面

<table class="table" id="tb_properties" style="width:100%">
<tr>
    @if (ViewBag.ApiProp != null)
    
        @foreach (var itemApiProp in ViewBag.ApiProp)
               
        <td>
            <input type="text" value="@itemApiProp.Key" class="form-control" />
        
                <select class="form-control">
                    <option value="">--Select-- </option>
                    @foreach (var itemK360Prop in ViewBag.K360Prop)
                    
                    <option>@itemK360Prop.Key</option>
                    
                </select>
        </td>
        
        
    
</tr>
<tr>
      <td> 
          <button type="submit" class="btn btn-primary" style="margin- 
          right:50px">Catalog Mapping</button>
     </td>
</tr>
</table>

用于获取视图控件值的控制器代码

public IActionResult Index()

    string strAPIUrl = "https://raw.githubusercontent.com/wedeploy-examples/supermarket-web-example/master/products.json";
    string jsonUrlProducts;
    using (WebClient client = new WebClient())
    
        jsonUrlProducts = client.DownloadString(strAPIUrl);
    

    CreateDynamicAPiProp(jsonUrlProducts);
    CreateK360Prop();
    return View();


[HttpGet]
public IActionResult CreateDynamicAPiProp(string ApiUrl)

    Dictionary<string, object> dictResultsAdd = new Dictionary<string, object>();
    var objResponseB = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ApiUrl);
    foreach (Dictionary<string, object> DictMainKV in objResponseB)
    
        foreach (KeyValuePair<string, object> item in DictMainKV)
        
            dictResultsAdd.Add(item.Key, item.Value);
        

        break;
    

    ViewBag.ApiProp = dictResultsAdd;
    return RedirectToAction("Index");


[HttpGet]
public IActionResult CreateK360Prop()

    var ListK360Prop = new List<ApiMapDbViewModel>();
    PropertyInfo[] propertyInfosK360 = typeof(K360DbCatgViewModel).GetProperties();
    foreach (PropertyInfo propertyInfoK360 in propertyInfosK360)
    
        ListK360Prop.Add(new ApiMapDbViewModelValue = propertyInfoK360.Name.ToString(), Key = propertyInfoK360.Name.ToString());
    

    ViewBag.K360Prop = ListK360Prop;
    return RedirectToAction("Index");

我使用了下面的 jQuery 并将 JSON 模型对象传递给 HTTP post 上的控制器插入方法以保存选定的记录。

jQuery 代码

@section scripts 
<script>
    $(function() 
        $("button[type='submit']").click(function() 
            event.preventDefault();
            var properties = [];
            $("#tb_properties tr:first").find("td").each(function(index, item) 
                var propertyname = $(item).find("input[type='text']").val();
                var selctedvalue = $(item).find("select").val();
                properties.push('"' + propertyname + '":"' + selctedvalue + '"');
            );
            var jsonstr = '' + properties.join(",") + '';
            var jsobject = JSON.parse(jsonstr);
            $.ajax(
                type: "Post",
                url: "/KEMap/Insert",
                data: 
                    jsonModel: jsobject
                ,
                success: function(response) 
                    toastr.info(response.status + "<br>" + "<br>" + response.message);
                    $("#tb_properties select").val("");
                    $("#partial_div").load(window.location.href + " #partial_div");
                ,
                error: function(xhr, textStatus, errorThrown) 
                    console.log('in error');
                
            );

        );
    );
</script>

插入方法

[HttpPost]
public IActionResult Insert(ApiJsonViewModel jsonModel)

    Type type = jsonModel.GetType();
    PropertyInfo[] props = type.GetProperties();
    List<K360mapMaster> K360mapListObj = new List<K360mapMaster>();
    K360mapListObj = props.Where(c => !string.IsNullOrEmpty(c.GetValue(jsonModel, null)?.ToString())).Select(c => new K360mapMaster()
    ClientCatalog = c.Name, K360catalog = c.GetValue(jsonModel, null)?.ToString()).ToList();
    if (K360mapListObj.Count > 0)
    
        _context.K360mapMasters.AddRange(K360mapListObj);
        _context.SaveChanges();
        return Json(new  Status = "Sucess", Message = "Mapped" );
    

    return Json(new  Status = "Fail", Message = "Not done" );

SQL 表

CREATE TABLE [dbo].[K360Map_Master](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ClientCatalog] [nvarchar](450) NOT NULL,
    [K360Catalog] [nvarchar](450) NOT NULL,
    [MapFlag] [bit] NOT NULL,
 CONSTRAINT [PK_K360Map_Master] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

一切正常。我能够将选定的文本框和下拉列表值插入到 SQL 表中。

问题是我使用的来自第三方 API URL 的 JSON 数据动态不同。例如对于以下 2 个示例 URL,我需要再次创建 2 个模型类文件。https://gist.githubusercontent.com/dpetersen/1237910/raw/6ceb2161f756d4b4d5c22754d1ed8d869249f186/product_grid.js https://raw.githubusercontent.com/mdn/fetch-examples/master/fetch-json/products.json.

我得到的反馈是带有静态数据的硬编码编码。不允许我为每个 URL 创建单独的模型类。

如果不创建模型类文件,我也不知道如何继续。我需要将选定的控制值传递给没有 JSON 模型对象的控制器插入方法。

我希望有人可以在这里帮助我。

【问题讨论】:

您好,欢迎您。编辑队列已满,所以我无法更改您的问题。我建议为您的代码块使用更好的格式。 我继续修复了其中的一些问题,但老实说,这里有很多代码,甚至没有任何 JSON,这确实应该在问题本身中,而不是作为链接指向可能会消失的其他地方的 URL。 嗨@Sivakumar N,你的K360DbCatgViewModel是什么? 它的模型类文件来自另一个 SQL 表。它包含大约 30 列用于映射 JSON 数据 @Rena,非常感谢您的帮助。代码工作正常。 【参考方案1】:

这是一个您可以关注的工作演示:

型号:

public class ApiMapDbViewModel

    public string Value  get; set; 
    public string Key  get; set; 

public class K360mapMaster

    public string ClientCatalog  get; set; 
    public string K360catalog  get; set; 

public class K360DbCatgViewModel

    public string AA  get; set; 
    public string BB  get; set; 
    public string CC  get; set; 
    public string DD  get; set; 

查看:

<table class="table" id="tb_properties" style="width:100%">
    <tr>
        @if (ViewBag.ApiProp != null)
        
            @foreach (var itemApiProp in ViewBag.ApiProp)
            
                <td>
                    <input type="text" value="@itemApiProp.Key" class="form-control" />

                    <select class="form-control">
                        <option value="">--Select-- </option>
                        @foreach (var itemK360Prop in ViewBag.K360Prop)
                        
                            <option>@itemK360Prop.Key</option>
                        
                    </select>
                </td>

            
        
    </tr>
    <tr>
        <td>
            <button type="submit" class="btn btn-primary" style="margin-
          right:50px">
                Catalog Mapping
            </button>
        </td>
    </tr>
</table>

JS(添加 data: jsonstr,contentType:"application/json"):

@section scripts
    <script>
        $(function () 
            $("button[type='submit']").click(function () 
                event.preventDefault();
                var properties = [];
                $("#tb_properties tr:first").find("td").each(function (index, item) 
                    var propertyname = $(item).find("input[type='text']").val();
                    var selctedvalue = $(item).find("select").val();
                    properties.push('"' + propertyname + '":"' + selctedvalue + '"');
                );
                var jsonstr = '' + properties.join(",") + '';
                //var jsobject = JSON.parse(jsonstr);
   
                $.ajax(
                    type: "Post",
                    url: "/KEMap/Insert",
                    //data: jsobject,
                    data: jsonstr,
                    contentType:"application/json",
                    success: function (response) 
                        toastr.info(response.status + "<br>" + "<br>" + response.message);
                        $("#tb_properties select").val("");
                        $("#partial_div").load(window.location.href + " #partial_div");
                    ,
                    error: function (xhr, textStatus, errorThrown) 
                        console.log('in error');
                    
                );

            );
        );
    </script>

控制器:

[HttpPost]
public IActionResult Insert([FromBody]JObject jsonModel)

    Type type = jsonModel.GetType();
    PropertyInfo[] props = type.GetProperties();
    List<K360mapMaster> K360mapListObj = new List<K360mapMaster>();
    foreach (JProperty prop in jsonModel.Children())
    
        string key = prop.Name.ToString();
        string value = prop.Value.ToString();
        K360mapListObj.Add(new K360mapMaster()  ClientCatalog = key, K360catalog = value );
    
       
    //do your stuff...
    return Json(new  Status = "Fail", Message = "Not done" );

注1

因为ApiJsonViewModel中的mapped属性首字母大写,所以ClientCatalog = c.Name,这里得到的数据是大写的。从我提供的代码中,string key = prop.Name.ToString();这里的代码得到json(https://raw.githubusercontent.com/wedeploy-examples/supermarket-web-example/master/products.json)键名是小写。如果要保留首字母大写,可以更改以下行:

string key = prop.Name.ToString().First().ToString().ToUpper() + prop.Name.ToString().Substring(1); 

注2

如果您的项目是asp.net core 3.x 或asp.net 5,请确保您的项目有Newtonsoft 支持,否则,您无法将数据传递到后端成功了。更多细节可以参考:

.NET 5.0 MVC return Json is throwing a JSON Parser error

结果:

【讨论】:

非常感谢。我将实施您的代码并尽快更新您 是的,我只在使用 asp.net core 5。 我需要关于表格对齐问题的更多帮助。我已通过更新的答案部分发布了该问题。请看看并帮助我。 我创建了一个新线程***.com/questions/66486022/…。请帮帮我 好的。请稍等。

以上是关于将 jQuery JSON 对象保存到 SQL 表中,而无需在 MVC ASP.NET Core 中创建视图模型类的主要内容,如果未能解决你的问题,请参考以下文章

将 CR/LF 保存在 json 数据中

如何将 SQL 数据映射到 Java JSON 对象和 JSON 数组?

jquery在cookie中保存json数据对象

JQuery使用JQuery 合并两个 json 对象

jQuery插件,用于将html表导出为JSON、XML、CSV、TSV、TXT、SQL、Word、Excel、PNG和PDF

Laravel - 从 JSON 数组创建对象以将其保存在 SQL 数据库中