0

I am working on reading JSON data from the URL and insert it into the SQL table. I have used this sample URL https://raw.githubusercontent.com/wedeploy-examples/supermarket-web-example/master/products.json and create a Model class file as below.

View Model Class

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; }
}

I have a form with one textbox control to display JSON key data from the third-party API URL and a drop-down list with values from the database.

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 View Page

<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>

Controller code to fetch values for the view controls

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 ApiMapDbViewModel{Value = propertyInfoK360.Name.ToString(), Key = propertyInfoK360.Name.ToString()});
    }

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

I have used the below jQuery and passed the JSON Model object to controller insert method on HTTP post to save selected records.

jQuery Code

@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>

Insert Method

[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 Table

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

Everything working fine. I was able to insert selected textbox and dropdown list values into the SQL table.

The problem is JSON data I am using from the third-party API URL differ dynamically. For example for the below 2 sample URLs, I need to create again 2 model class file.https://gist.githubusercontent.com/dpetersen/1237910/raw/6ceb2161f756d4b4d5c22754d1ed8d869249f186/product_grid.js https://raw.githubusercontent.com/mdn/fetch-examples/master/fetch-json/products.json.

I get the feedback as hardcoded coding with static data. I was not permitted to create a separate model class for each URL.

I also don't know how to proceed without creating a model class file. I need to pass selected control values to the controller insert method without a JSON model object.

I hope anybody can help me here.

5
  • 1
    Hey and welcome. The edit queue is full, so I cannot change your question. I would suggest use a better format for your code blocks. Commented Mar 3, 2021 at 19:22
  • I went ahead and fixed some of it, but honestly, there's a lot of code here, and that's even without any of the JSON, which really should be in the question itself, not as a link to a URL to somewhere else that might disappear. Commented Mar 3, 2021 at 21:31
  • Hi @Sivakumar N,What is your K360DbCatgViewModel? Commented Mar 4, 2021 at 2:53
  • Its model class file from another SQL table. It contains around 30 columns which are used to map JSON data Commented Mar 4, 2021 at 5:07
  • @Rena, Thanks a lot for your kind help. Code working fine. Commented Mar 4, 2021 at 6:25

1 Answer 1

1

Here is a working demo you could follow:

Model:

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; }
}

View:

<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(Add 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>
}

Controller:

[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" });
}

Note 1:

Because the mapped property in ApiJsonViewModel capitalize the first letter,so the data you get here ClientCatalog = c.Name, is capital.From my provided code,The code here string key = prop.Name.ToString(); get the json(https://raw.githubusercontent.com/wedeploy-examples/supermarket-web-example/master/products.json) key name which is lower case.If you want to keep the first letter capital,you could change the following line:

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

Note 2:

If your project is asp.net core 3.x or asp.net 5,be sure your project has Newtonsoft support,otherwise,you cannot pass data to backend successfully.More details you could refer to:

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

Result:

enter image description here

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks a lot. I Will implement your code and update you soon
Yes, I am working on asp.net core 5 only.
I need one more help regarding the table alignment issue. I have posted the issue with an updated answer section. Please have a look and kindly help me.
I have created a new thread stackoverflow.com/questions/66486022/…. Please help me out
Ok.Please wait a while.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.