I have a class which models the format of the CSV being uploaded (I'm using the FileHelpers library):
[DelimitedRecord(",")]
public class CSVModel
{
[FieldQuoted('"', QuoteMode.OptionalForBoth, MultilineMode.NotAllow)]
public string Field1;
[FieldQuoted('"', QuoteMode.OptionalForBoth, MultilineMode.NotAllow)]
public string Field2;
}
Then I have a class to display the result of the upload after I've parsed the file row-by-row:
public class UploadResult
{
public List<CSVModel> InvalidField;
public List<CSVModel> Valid;
}
I won't go into detail about how I implement FileHelpers because it all works - a file can be uploaded successfully - it only breaks when I try add an instance of the CSV model to a list like so:
public static UploadResult ProcessCSV(CSVModel[] records)
{
UploadResult uploadResult = new UploadResult();
for (int i = 1; i < records.Length; i++)
{
CSVModel csvModel = records[i];
// check stuff
uploadResult.Valid.Add(csvModel); // this is where it breaks
}
return uploadResult;
}
The exception is giving me nothing more than null reference. What could I be doing incorrectly?
edit: When I debug, 'csvModel' is definitely not null when I try add it to the List
Valid is null, you have to initialize it:
public class UploadResult
{
public List<CSVModel> InvalidField = new List<CSVModel>();
public List<CSVModel> Valid = new List<CSVModel>();
}
or via constructor:
public class UploadResult
{
public UploadResult()
{
InvalidField = new List<CSVModel>();
Valid = new List<CSVModel>();
}
public List<CSVModel> InvalidField;
public List<CSVModel> Valid;
}
You are initializing UploadResult but not the List properties. Try something like this:
UploadResult uploadResult = new UploadResult {
InvalidField = new List<CSVModel>(),
Valid = new List<CSVModel>()
};
Related
I have a Json file, it contains connectionstring. I want to asynchronously read the file and deserialize it to a ConnectionString object and I always get a null result. I'm using .NET Core 6 and System.Text.Json.
Here is contents of my Json file:
{
"ConnectionStrings": {
"ConnStr": "Data Source=(local);Initial Catalog=MyData;Integrated Security=False;TrustServerCertificate=True;Persist Security Info=False;Async=True;MultipleActiveResultSets=true;User ID=sa;Password=MySecret;",
"ProviderName": "SQLServer"
}
}
Here are the contents of my classes:
internal class DBConnectionString
{
[JsonPropertyName("ConnStr")]
public string ConnStr { get; set; }
[JsonPropertyName("ProviderName")]
public string ProviderName { get; set; }
public DBConnectionString()
{
}
}
public class DBConnStr {
private static string AppSettingFilePath => "appsettings.json";
public static async Task<string> GetConnectionStringAsync()
{
string connStr = "";
if (File.Exists((DBConnStr.AppSettingFilePath)))
{
using (FileStream sr = new FileStream(AppSettingFilePath, FileMode.Open, FileAccess.Read))
{
//string json = await sr.ReadToEndAsync();
System.Text.Json.JsonDocumentOptions docOpt = new System.Text.Json.JsonDocumentOptions() { AllowTrailingCommas = true };
using (var document = await System.Text.Json.JsonDocument.ParseAsync(sr, docOpt))
{
System.Text.Json.JsonSerializerOptions opt = new System.Text.Json.JsonSerializerOptions() { AllowTrailingCommas = true, PropertyNameCaseInsensitive = true };
System.Text.Json.JsonElement root = document.RootElement;
System.Text.Json.JsonElement element = root.GetProperty("ConnectionStrings");
sr.Position = 0;
var dbConStr = await System.Text.Json.JsonSerializer.DeserializeAsync<DBConnectionString>(sr, opt);
if (dbConStr != null)
{
connStr = dbConStr.ConnStr;
}
}
}
}
return connStr;
}
}
The following is the syntax that I use to call the GetConnectionStringAsync method:
string ConnectionString = DBConnStr.GetConnectionStringAsync().Result;
When the application is running in debug mode, I checked, on line
var dbConStr = await
System.Text.Json.JsonSerializer.DeserializeAsync(sr,
opt);
The DBConnectionString object property is always empty.
I also tried the reference on the Microsoft website, https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/how-to?pivots=dotnet-6-0 but it doesn't work succeed.
using System.Text.Json;
namespace DeserializeFromFileAsync
{
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
public class Program
{
public static async Task Main()
{
string fileName = "WeatherForecast.json";
using FileStream openStream = File.OpenRead(fileName);
WeatherForecast? weatherForecast =
await JsonSerializer.DeserializeAsync<WeatherForecast>(openStream);
Console.WriteLine($"Date: {weatherForecast?.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast?.Summary}");
}
}
}
Do you have a solution for my problem or a better solution? I appreciate all your help. Thanks
Sorry about my English if it's not good, because I'm not fluent in English and use google translate to translate it
To begin with, if you want to read information from appSettings.json, you should explore more into reading configurations. There are helper classes provided by .Net for the same.
Coming back to your code, if you want to use your own code for Json Deserialization, then you need to make the following change to it.
var dbConStr = System.Text.Json.JsonSerializer.Deserialize<DBConnectionString>(element.GetRawText(), opt);
where, element according to code shared in the question is defined as
System.Text.Json.JsonElement element = root.GetProperty("ConnectionStrings");
This ensures the Raw Json associated with the JsonElement ConnectStrings is de-serialized.
However, I recommend you to read more into Reading configurations using the IConfiguration and related .Net helpers.
I am new to the C# community. I created a controller and a class with the class containing some logic from a COM reference that I want to be executed.
When I call the API, it does not seem to be going into the ImportInventory method and no logic is executed in that public string (as seen from the debugging breakpoints).
Can someone please assist on how to get this part of the code executed? I am new to C# and can't seem to find the issue.
Code snippet of the controller:
using MDRDS_PastelIntegrator.Models;
using Microsoft.AspNetCore.Mvc;
namespace MDRDS_PastelIntegrator.Controllers
{
[ApiController]
[Route("[controller]")]
public class InventoryController : ControllerBase
{
private readonly ILogger<InventoryController> _logger;
public InventoryController(ILogger<InventoryController> logger)
{
_logger = logger;
}
[HttpPost(Name = "POSTInventory")]
public IEnumerable<POSTInventory> Get(string pParameter, string pPath)
{
return Enumerable.Range(1, 1).Select(index => new POSTInventory
{
Parameter = pParameter,
Path = pPath
})
.ToArray();
}
}
}
Code snippet of the class:
namespace MDRDS_PastelIntegrator.Models
{
public class POSTInventory
{
//public string? StrReturn;
public string? Parameter { get; set; }
public string? Path { get; set; }
public string ImportInventory(string Parameter, string Path)
{
var SDK = new PasSDK.PastelPartnerSDK();
//Set License
var F_GetLisence = new SetLicense();
F_GetLisence.MethodSetLicense();
//Set Data Path
var StrReturn = SDK.SetDataPath(Path);
if (StrReturn == "0")
{
var StrIn = Parameter;
var StrCodeIn = StrIn;
//Import Inventory Item
StrReturn = SDK.ImportInventory(StrIn);
};
//Blank return string - No serial number
if (StrReturn.Length == 0)
{
StrReturn = "Serial Number Not Specified.";
//return StrReturn;
};
//Get Result Code
if (StrReturn == "0")
{
StrReturn = "0 = Success";
}
else
{
StrReturn = "1 = Unsuccessfull";
};
return StrReturn;
}
}
}
You create an object POSTInventory but you never call the ImportInventory method of this object
I have a Json file with following structure
{"status":"OK","masterlist":{"session":{"session_id":1621,"session_name":"Regular Session 2019"}
,"0":{"bill_id":001,"number":"2","change_hash":"xxxxxx","url":"xxxx","status_date":"2019-03-05","status":"1","last_action_date":"2019-03-05","last_action":"action","title":xxx,"description":xxxx"},
"2":{"bill_id":001,"number":"2","change_hash":"xxxxxx","url":"xxxx","status_date":"2019-03-05","status":"1","last_action_date":"2019-03-05","last_action":"action","title":xxx,"description":xxxx"},
"3":{"bill_id":001,"number":"2","change_hash":"xxxxxx","url":"xxxx","status_date":"2019-03-05","status":"1","last_action_date":"2019-03-05","last_action":"action","title":xxx,"description":xxxx"},
"4":{"bill_id":001,"number":"2","change_hash":"xxxxxx","url":"xxxx","status_date":"2019-03-05","status":"1","last_action_date":"2019-03-05","last_action":"action","title":xxx,"description":xxxx"},
I'm trying to put the contents to list of class like this:
public class LegiBill
{
public string bill_id;
public string number;
public string change_hash;
public string url;
public string status_date;
public string last_action_date;
public string last_action;
public string title;
public string description;
}
I'm using Newtonsoft.Jason with following code:
public static T ReadFromJsonStr<T>(string str) where T : new()
{
TextReader reader = null;
try
{
return JsonConvert.DeserializeObject<T>(str);
}
finally
{
if (reader != null)
reader.Close();
}
}
I don't have any problem with reading and parsing! I just don't know how to put the main contents which have labels like "0","1","2","3",.... to list of LegiBill like List<LegiBill>.
Thank you in advance.
If you cannot change json. You can do something like this inside ReadFromJsonStr method
public static List<LegiBill> ReadFromJsonStr(string str)
{
var parsedObject = JObject.Parse(str);
var popupJson = parsedObject["masterlist"].ToString();
var popupObj = JsonConvert.DeserializeObject<Dictionary<string, LegiBill>>(popupJson);
var filteredList = popupObj.Where(kvp => kvp.Key.Equals("session") == false).Select(x=>x.Value).ToList();
List<LegiBill> legiBills = new List<LegiBill>(filteredList);
foreach (var legiBill in filteredList)
{
if (legiBill != null)
{
legiBills.Add(legiBill);
}
}
return legiBills;
}
My Xml loader saves data from xml file to list of class . Dialog is class with 2 properties: id and text, where are save content of xml file. I want to get "text" variable value in DialogLoader.cs from list in DialogContainer.cs by value of id variable. How can I do that? It's probably easy, but i don't know how.
dialogs.xml
<?xml version="1.0" encoding="UTF-8"?>
<DialogCollection>
<Dialogs>
<Dialog id="1">
<Text>Hello my friend</Text>
</Dialog>
<Dialog id="2">
<Text>Hello my grandma</Text>
</Dialog>
<Dialog id="3">
<Text>Hello my grandpa</Text>
</Dialog>
</Dialogs>
</DialogCollection>
DialogLoader.cs
public class DialogLoader : MonoBehaviour
{
public const string path = "dialogs";
void Start()
{
DialogContainer dc = DialogContainer.Load(path);
//There I want to get text for example by id 1 (Hello my friend)
foreach (Dialog item in dc.dialogs)
{
print(item.text);
}
}
DialogContainer.cs
[XmlRoot("DialogCollection")]
public class DialogContainer
{
[XmlArray("Dialogs")]
[XmlArrayItem("Dialog")]
public List<Dialog> dialogs = new List<Dialog>();
public static DialogContainer Load(string path)
{
TextAsset _xml = Resources.Load<TextAsset>(path);
XmlSerializer serializer = new XmlSerializer(typeof(DialogContainer));
StringReader reader = new StringReader(_xml.text);
DialogContainer dialogs = serializer.Deserialize(reader) as DialogContainer;
reader.Close();
return dialogs;
}
}
Dialog.cs
public class Dialog
{
[XmlAttribute("id")]
public string id;
[XmlElement("Text")]
public string text;
}
You could either add a Dictionary like
[XmlRoot("DialogCollection")]
public class DialogContainer
{
[XmlArray("Dialogs")]
[XmlArrayItem("Dialog")]
public List<Dialog> dialogs = new List<Dialog>();
public Dictionary<string, string> IdToText = new Dictionary<string, string>();
public static DialogContainer Load(string path)
{
TextAsset _xml = Resources.Load<TextAsset>(path);
XmlSerializer serializer = new XmlSerializer(typeof(DialogContainer));
// use a better variable name since "dialogs" is also a field of it
DialogContainer dialogContainer;
// use "using" for disposables
using(StringReader reader = new StringReader(_xml.text))
{
dialogContainer = serializer.Deserialize(reader) as DialogContainer;
}
// reset dictionary
dialogContainer.IdToText.Clear();
foreach(var entry in dialogContainer.dialogs)
{
dialogContainer.IdToText.Add(entry.id, entry.text);
}
return dialogContainer;
}
}
Than you can later use e.g.
aDialogContainer.idTotext["1"];
note that this will throw an exception is searched key is not in the dictionary! So refer to the solution below.
Anther option is to implement a getter method instead of the dictionary to look up the correct text on the fly using LINQ: FirstOrDefault:
public string IdtoText(string id)
{
var foundDialog = dialogs.FirstOrDefault(dialog => string.Equals(dialog.id, id));
// here you can decide whether to |
// return null or "" if no element found v
return foundDialog != null ? foundDialog.text : "";
}
Than you would use
aDialogContainer.IdTotext("1");
You could use Linq to filter a list of dialogs and simply return the first one matching your condiction.
Something like this:
public Dialog GetSingleDialog(string id, List<Dialog> dialogs){
return dialogs.Where(x=>x.id==id).FirstOrDefault();
}
You can use like this:
DialogContainer dc = DialogContainer.Load(path);
//Get list of dialogs
var dialogs=dc.dialogs;
var theDialog=GetSingleDialog("1",dialogs);
//Get your text
Debug.Log(theDialog.Text);
Why do have this error on this part of the code ?
this part
var data = serializer.Deserialize<EmailTemplate>(httpRequest.Form["data"].ToString());
my procedure
public int UpdateEmailTemplate()
{
HttpResponseMessage result = null;
ObjectService uploadFile = new ObjectService();
List<ActiveUp.Net.Mail.Attachment> attachment = new List<ActiveUp.Net.Mail.Attachment>();
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Form["data"] != null)
{
var serializer = new JavaScriptSerializer();
var data = serializer.Deserialize<EmailTemplate>(httpRequest.Form["data"].ToString());
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
MemoryStream target = new MemoryStream();
httpRequest.Files[file].InputStream.CopyTo(target);
uploadFile.AddObject(data.Id, "SU_ENTITY_MSG_TEMPLATE","", target.GetBuffer(), httpRequest.Files[file].FileName);
}
}
AdminService List = new AdminService();
return List.UpdateEmailTemplate(data);
}
MY class
public class EmailTemplate
{
public int Id;
public string TypeObject;
public int? idObject;
public string ObjectName;
public string IdTeam;
public string IdTask;
public string Team;
public string task;
public string Title;
public string Subject;
public string dataHtml;
public List<Objects> fileListRequest;
}
It's pretty plainly saying that the contents of:
httpRequest.Form["data"]
...is an array of some sort. Adding .ToString() will just return it's type name. Passing that to Deserialize is what's giving you the error, as Deserialize is expecting an array and just getting a string.
Try taling the .ToString() off - this may not work. If it doesn't you'll have to convert httpRequest.Form["data"] to what ever data type you've put into it (whuich you do not say).