Import Json data from URL to SQL server - c#

I have a .Json URL that contains Json format data.
HTTPS://XXXX/fetch-transaction?fromdate=2020-10-13&toDate=2020-10-20 (Not working just an example)
[
{
"orderId": 110,
"consignmentNumber": "TEST",
"itemNumbers": [
"TEST"
],
"country": "UK",
"orderType": "ORDER_HOME_DELIVERY",
"paymentTransactionId": "395611",
"priceInOre": 5900,
"paidAt": "2020-10-16 10:51:08",
"orderNumber": "7000067718",
"articleName": "SOUTH-2"
}
]
I would like to insert data into a SQL server table and wonder if it's possible to use SQL server and t-SQL directly here or should I go for VS and C#?
If C# is the preferred choice can someone pleae guide me on how I would accomplish it?
I have created a Console application in Visual studio (however it might be a better solution to use something els then to create a command line applcation?) or guide me in the right direction.

You can try the following code to get the value from the json txt and transfer it to the sql server table.
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string json = File.ReadAllText("D:\\test1.txt");
List<Example> list = JsonConvert.DeserializeObject<List<Example>>(json);
string strcon = #"Connstr";
SqlConnection connection = new SqlConnection(strcon);
connection.Open();
string sql = "Insert into JsonData(orderId,consignmentNumber,itemNumbers,country,orderType,paymentTransactionId,priceInOre,paidAt,orderNumber,articleName) values(#orderId,#consignmentNumber,#itemNumbers,#country,#orderType,#paymentTransactionId,#priceInOre,#paidAt,#orderNumber,#articleName)";
SqlCommand command = new SqlCommand(sql, connection);
foreach (Example item in list)
{
command.Parameters.AddWithValue("#orderId", item.orderId);
command.Parameters.AddWithValue("#consignmentNumber", item.consignmentNumber);
command.Parameters.AddWithValue("#itemNumbers", item.itemNumbers.First());
command.Parameters.AddWithValue("#country", item.country);
command.Parameters.AddWithValue("#orderType", item.orderType);
command.Parameters.AddWithValue("#paidAt", item.paidAt);
command.Parameters.AddWithValue("#paymentTransactionId", item.paymentTransactionId);
command.Parameters.AddWithValue("#priceInOre", item.priceInOre);
command.Parameters.AddWithValue("#articleName", item.articleName);
command.Parameters.AddWithValue("#orderNumber", item.orderNumber);
}
command.ExecuteNonQuery();
connection.Close();
}
}
public class Example
{
public int orderId { get; set; }
public string consignmentNumber { get; set; }
public List<string> itemNumbers { get; set; }
public string country { get; set; }
public string orderType { get; set; }
public string paymentTransactionId { get; set; }
public int priceInOre { get; set; }
public string paidAt { get; set; }
public string orderNumber { get; set; }
public string articleName { get; set; }
}
Final result:
Edit:
var json = new WebClient().DownloadString("URL");

Related

Dapper SQL Call Returning NULL and 0 values

Working with Dapper on making SQL calls and mapping them to objects.
I am having an issue with SQL Dapper call not mapping correctly to C# Class.
Using ASP.NET Core API and have one controller and one class.
Controller Class
public class DapperController : Controller
{
private const string connectionString = #"";
[HttpGet("")]
public async Task<IActionResult> Index()
{
var sql = #"SELECT product_name, model_year,list_price
FROM [production].[products]";
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
var product = await connection.QueryAsync<Products>(sql);
return Ok(product);
}
}
}
Products Class
public class Products
{
[JsonPropertyName("product_name")]
public string ProductName { get; set; }
[JsonPropertyName("model_year")]
public int ModelYear { get; set; }
[JsonPropertyName("list_price")]
public double ListPrice { get; set; }
}
Getting back the following data but that is not correct since the database does have data
[
{
"product_name": null,
"model_year": 0,
"list_price": 0
},
{
"product_name": null,
"model_year": 0,
"list_price": 0
}
]
When using the above without mapping to class I get the correct data. Not sure what I am doing wrong
[
{
"product_name": "Trek 820 - 2016",
"model_year": 2016,
"list_price": 379.99
},
{
"product_name": "Ritchey Timberwolf Frameset - 2016",
"model_year": 2016,
"list_price": 749.99
}
]
Not sure what I am doing wrong
Because JsonPropertyName is for Json serialize instead of Dapper ORM
so that we might need to modify class property as below code or
#Yong Shun as say modify the script alias name which aligns with your c# property (case sensitive)
public class Products
{
public string product_name { get; set; }
public int model_year { get; set; }
public double list_price { get; set; }
}
I think we might need to use our customer as this link ColumnAttribute instead of JsonPropertyName
Our customer map needs to implement SqlMapper.ITypeMap
public class Products
{
[Column("product_name")]
public string ProductName { get; set; }
[Column("model_year")]
public int ModelYear { get; set; }
[Column("list_price")]
public double ListPrice { get; set; }
}
Also here is a link V2: [Column] and [Table] Attributes #722 which dapper official discusses Column mapping attributes for dapper.

Data is null .This method or property cannot be called on null values [duplicate]

This question already has answers here:
Data is Null. This method or property cannot be called on Null values
(13 answers)
Closed last year.
I want to retrieve various information from my DB. But during testing my code I got the message:
Data is null. This method or property cannot be called on null values
There are nullable columns in my dB and I think those are causing the problem. Please someone help me to solve this problem. Here is my code:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using WpfDropDownNavigate.Models;
namespace WpfDropDownNavigate.Business
{
public class MusteriBusiness
{
public static List<Musteriler> MusterileriGetir()
{
string sqltrtr = "select * from Customers";
SqlDataReader reader = Helper.ExecuteReader(sqltrtr, CommandType.Text);
List<Musteriler> musteriler = new List<Musteriler>();
while (reader.Read())
{
musteriler.Add(new Musteriler
{
MusteriID =reader.GetString(0),
FirmaAdi = reader.GetString(1),
SorumluKisi = reader.GetString(2),
Yetkisi = reader.GetString(3),
Adres = reader.GetString(4),
Sehir = reader.GetString(5),
Ulke = reader.GetString(6),
TelefonNo = reader.GetString(7),
}) ;
}
reader.Close();
return musteriler;
}
public static int MusteriGuncelle(string firmaAdi, string sorumluKisi, string yetkisi, string adres, string sehir, string ulke, string telefonNo,string musteriId)
{
string sqltrt = string.Format("update Customers set CompanyName='{0}',ContactName='{1}',ContactTitle='{2}',Address='{3}',City='{4}',Country='{5}',Phone='{6}' where CustomerID='{7}'", firmaAdi, sorumluKisi, yetkisi, adres, sehir, ulke, telefonNo, musteriId);
return Helper.ExecuteNonQuery(sqltrt, CommandType.Text);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace WpfDropDownNavigate.Models
{
public class Musteriler
{
public string FirmaAdi { get; set; }
public string SorumluKisi { get; set; }
public string Yetkisi { get; set; }
public string Adres { get; set; }
public string Sehir { get; set; }
//public string Bolge { get; set; }
//public string PostaKodu { get; set; }
public string Ulke { get; set; }
public string TelefonNo { get; set; }
//public string FaxNo { get; set; }
public string MusteriID { get; set; }
}
}
Nullable columns must be tested for null. E.g. Assuming that Adres can be null
Adres = reader.IsDBNull(4) ? null : reader.GetString(4),
This is not necessary for columns declared as NOT NULL in the database.
See also:
SQL Injection
What are good ways to prevent SQL injection?

C#: Dapper with JsonConvert.SerializeObject() not working properly

I'm new to Newtonsoft.Json and Dapper.
I am executing an SQL query, and using the query's result I'm converting it to a JSON string to try to make it look like this:
{ "Orders" : [{"OrderID":10248, "Quantity":12}, {"OrderID":10343, "Quantity":4}, ...etc...]}
However when I run my C# code, my output looks completely different along with some unexpected additions:
[
{
"JSON_F52E2B61-18A1-11d1-B105-00805F49916B": "{\"Orders\":[{\"OrderID\":10248,\"Quantity\":12},{\"OrderID\":10248,\"Quantity\":10}{\"OrderID\":10271,\"Quantity\":24},{\"OrderID\":10272,\"Quantity\":6},{\"OrderID\":1027"
},
{
"JSON_F52E2B61-18A1-11d1-B105-00805F49916B": "2,\"Quantity\":40},{\"OrderID\":10272,\"Quantity\":24}, ...etc... ]
As you can see I do not understand why it is adding the additional "JSON_F52E2B61-18A1-11d1-B105-00805F49916B". How do I remove these? How do I change my code to make it look like my desired output json string?
This is my code. I also made a fiddle with the incorrect output I'm getting https://dotnetfiddle.net/uWV6vs :
// Dapper Plus
// Doc: https://dapper-tutorial.net/query
// #nuget: Dapper -Version 1.60.6
using Newtonsoft.Json;
using Dapper;
using System;
using System.Data.SqlClient;
public class Program
{
public class OrderDetail
{
public int OrderDetailID { get; set; }
public int OrderID { get; set; }
public int ProductID { get; set; }
public int Quantity { get; set; }
}
public static void Main()
{
string sql = "SELECT OrderID, Quantity FROM OrderDetails FOR JSON PATH, root ('Orders'), INCLUDE_NULL_VALUES";
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
dynamic orderDetail = connection.Query(sql);
//edit: the answer is to use connection.Query<string>, orderDetail[0]
orderDetail = JsonConvert.SerializeObject(orderDetail,Formatting.Indented);
Console.WriteLine(orderDetail);
}
}
}
I believe you don't need to request JSON from SQL, Dapper will parse results to the objects automatically
Removing "FOR JSON PATH, root ('Orders'), INCLUDE_NULL_VALUES" should help
string sql = "SELECT OrderID, Quantity FROM OrderDetails";
UPDATE:
sorry, keep updating the answer. This one gives you objects with the right structure and no extra backslashes
using Newtonsoft.Json;
using Dapper;
using System;
using System.Data.SqlClient;
using System.Collections.Generic;
public class Program
{
public class OrderDetail
{
public int OrderDetailID { get; set; }
public int OrderID { get; set; }
public int ProductID { get; set; }
public int Quantity { get; set; }
}
public class Result
{
public IEnumerable<OrderDetail> Orders { get; set; }
}
public static void Main()
{
string sql = "SELECT OrderID, Quantity FROM OrderDetails";
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
var orderDetail = connection.Query<OrderDetail>(sql);
var str = JsonConvert.SerializeObject(new Result { Orders = orderDetail },Formatting.Indented);
Console.WriteLine(str);
}
}
}

Deserialize JSON array of values in C#

I've got some difficulties with this json script:
{
"insured_agent_flag": "a",
"id": "1",
"agent": {
"fullName": "John Travolta",
"mobileNumberPdf": "+987654321",
"mobileNumber": "",
"identityCard": {
"identityCardExpirationDate": null
},
"secondIdentityCard": {
"identityCardExpirationDate": null
},
"notes": {},
"sign": "ADVANCED"
},
"basicData": {
"personType": "PERSON",
"agreeWithCompleteAnalysis": false,
"investmentInterest": false
},
"nonOfferedProducts": [
"PROD_A",
"PROD_B",
"PROD_C"
]
}
I would like to get some parameters from this script and put it into sql server table.
In order to do that, I used and transformed a C# script shared by https://mycontraption.com:
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Web.Script.Serialization;
using Microsoft.SqlServer.Dts.Pipeline;
namespace SC_c7e2d8c3918d46a5a07a1b438ddc7642
{
public class BasicData
{
public string agreeWithCompleteAnalysis { get; set; }
public string inOtherSystem { get; set; }
public string investmentInterest { get; set; }
}
public class ParentObject
{
public BasicData BasicData { get; set; }
public int id { get; set; }
public string insured_agent_flag { get; set; }
public IEnumerable<string> NonOfferedProducts { get; set; }
}
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
JavaScriptSerializer js = new JavaScriptSerializer();
// Give the input column a variable to make it easier to reference.
BlobColumn combinedColumn = Row.parameterscon;
// Convert from blob to string
string reviewConverted = System.Text.Encoding.ASCII.GetString(combinedColumn.GetBlobData(0, Convert.ToInt32(combinedColumn.Length)));
// Deserialize the string
ParentObject obj = js.Deserialize<ParentObject>(reviewConverted);
var rows = obj.NonOfferedProducts.ToList();
Row.agreeWithCompleteAnalysis = obj.BasicData.agreeWithCompleteAnalysis;
Row.inOtherSystem = obj.BasicData.inOtherSystem;
Row.investmentInterest = obj.BasicData.investmentInterest;
Row.projectionid = obj.id;
Row.insuredagentflag = obj.insured_agent_flag;
//Row.nonOfferedProducts =
}
}
}
For 'standard' objects it works fine, but there is a problem with array "nonOfferedProducts". After compiling I get an error:
„object reference not set to an instance of an object”.
Here are my questions:
1. How should I handle 'nonOfferedProducts' array in C# script?
2. Why do I get foregoing error?
3. Unfortunately there exists a possibility, that json scripts would have some errors, like missing braces. How should I handle that?
Thank you!
Thanks a lot for your answers. According to your comments I'll try to give you more explanations:
1. The json script I have added in this post - it's only small part of whole script. In complete script there is a lot of different parameters. What is more, my C# code should scan about 40.000 json scripts (stored in sql server table in one column). These scripts has got similiar structure - but not the same.
So I thought about C# resolution, that will be searching for the parameters that I need. For json scripts without these parameters the c# code will put nulls to the right output columns.
Here are my output columns:
-agreeWithCompleteAnalysis
-inOtherSystem
-investmentInterest
-projectionId
-insuredAgentFflag
-nonOfferedProducts
I understood, that structure of my classes were wrong - I'll improve that.
But I've got one doubt - is it possible to prepare c# code structure, that will handle only these parameters I need?
And finally, I would like to put the results into my database.
For example if nonOfferedProducts property will have 3 values (not always!), I'd like to send to my database table 3 records (3 different values for nonOfferedProducts column and 3 the same values for the rest columns -agreeWithCompleteAnalysis, inOtherSystem etc).
I hope that will be clear now.
Thanks a lot for your help!
J
Use https://quicktype.io and paste json, it will generate c# model and serializer code.
As I said in my comment, your c# model doesn't match the JSON object.
If the model was made up of various nested objects to better reflect the actual JSON then you'll have more luck:
public class IdentityCard
{
public DateTime? IdentityCardExpirationDate { get; set; }
}
public class Notes
{
//No idea what should be in here...
}
public class BasicData
{
public string PersonType { get; set; }
public bool AgreeWithCompleteAnalysis { get; set; }
public bool InvestmentInterest { get; set; }
}
public class Agent
{
public string FullName { get; set; }
public string MobileNumberPdf { get; set; }
public string MobileNumber { get; set; }
public IdentityCard IdentityCard { get; set; }
public IdentityCard SecondIdentityCard { get; set; }
public Notes Notes { get; set; }
public string Sign { get; set; }
}
//Note: THIS is the actual class that matches the JSON sample given.
public class ParentObject
{
public string insured_agent_flag { get; set; }
public int Id { get; set; }
public Agent Agent { get; set; }
public BasicData BasicData { get; set; }
public IEnumerable<string> NonOfferedProducts { get; set; }
}
Once the model is correct, then Deserialization works fine for me with the given example (I did this in a unit test, but assuming your string matches your example this should be fine)
//get json
string json = #"
{
""insured_agent_flag"": ""a"",
""id"": ""1"",
""agent"": {
""fullName"": ""John Travolta"",
""mobileNumberPdf"": ""+987654321"",
""mobileNumber"": """",
""identityCard"": {
""identityCardExpirationDate"": null
},
""secondIdentityCard"": {
""identityCardExpirationDate"": null
},
""notes"": {},
""sign"": ""ADVANCED""
},
""basicData"": {
""personType"": ""PERSON"",
""agreeWithCompleteAnalysis"": false,
""investmentInterest"": false
},
""nonOfferedProducts"": [
""PROD_A"",
""PROD_B"",
""PROD_C""
]
}";
var js = new JavaScriptSerializer();
ParentObject obj = js.Deserialize<ParentObject>(json);
//do things...
var rows = obj.NonOfferedProducts.ToList();
Assert.AreEqual(3, rows.Count);
Assert.AreEqual("PROD_A", rows.First());
The asserts pass - This code happily gets the list of strings in the NonOfferedProducts property with the given example.
Obviously if you cannot rely on the consistency of the JSON (either structure or how well-formed it is) then you'll have problems, but that's a different issue.
To answer your question no 2) you are getting the object reference error because the BasicDataClass.nonOfferedProducts is null and you are trying iterate over it , this may be a reason that you are sending the wrong json which JavaScriptSerializer is not able to deserilize.
your 3rd question you can always validate your json with json validators which are there online like https://jsonformatter.org/

Accessing data from database in Xamarin Android using SQLite

I'm writing an app and I'm trying to get data out of an existing database. I succeeded in importing the database and addressing it correctly using this tutorial. When I try to execute a query, my object are empty.
This is my code
public void TestDB() {
using (var conn = new SQLite.SQLiteConnection(dbPath))
{
var cmd = new SQLite.SQLiteCommand (conn);
cmd.CommandText = "select * from totem";
var r = cmd.ExecuteQuery<Totem> ();
tekst.Text = r[0].Title;
}
}
}
public class Totem
{
[PrimaryKey, AutoIncrement]
public string TotemId { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string Synonyms { get; set; }
}
According to debug, r is a list and it contains 395 entries (the number of entries there are in Totem), but the Totem objects are empty as you can see:
Does anyone know how to initialize them?
Thanks in advance.

Categories