Using FileHelpers how do I pass individual data into variables? - c#

Apologies in advance as I'm fairly new to this so imagine this is be being a fool.
Anyway, I looking to pass individual comma delimited data into fields/variables. I am using FileHelpers and have it working and passing back data but my C# skills now fail me.
The CSV Data is:
Tom, Password
Two, PassTwo
Three, PassThree
And the code I have is :
[DelimitedRecord(",")]
public class UserDetailsLogin
{
FileHelperEngine engine = new FileHelperEngine(typeof(UserDetails));
[Test]
public void TestData()
{
string User1;
string User2;
string User3;
string Password1;
UserDetails[] res = engine.ReadFile("TestData.csv") as UserDetails[];
foreach (UserDetails user in res)
{
User1 = user.UserName;
Console.WriteLine(User1);
}
}
}
[DelimitedRecord(",")]
public class UserDetails
{
public string UserName;
public string Password;
}
Which, for the purpose of checking writes to console:
Tom
Two
Three
How would I be able to pass individual data to variables e.g:
User1 = "Tom"
Password1 = "Password"
User2 = "Two" etc etc..

Neither your question nor your code is very clear.
I think you are asking how to verify the values you have read in to the UserDetails array, in which case you can use the following test:
[TestFixture]
public class UserDetailsTests
{
[Test]
public void TestData()
{
FileHelperEngine engine = new FileHelperEngine(typeof(UserDetails));
UserDetails[] res = engine.ReadFile("TestData.csv") as UserDetails[];
Assert.AreEqual(res[0].UserName, "User 1");
Assert.AreEqual(res[0].Password, "Password 1");
Assert.AreEqual(res[1].UserName, "User 2");
Assert.AreEqual(res[2].UserName, "User 3");
}
}

Related

REST API Best Practice method GET with many condition

I have 2 question :
1.what is best practice for REST API method GET if there are many condition with the parameters.
example :
i have customers API and the user wants the api with request parameter like these :
idnumber and mobilephone
name (can use contains if user input %) or mobilephone
idnumber and idtype or date of birth
should i make 3 custom api with the same route for each commbination of parameters?
i ve searched everywhere but i cant find the answer, most article only share common best practice like these :
api/customer -- get all customer
api/customer/{id} -- get customer by id
2.Regarding the response api
example :
I have customers API and the response is like this :
- CustomerID
- CustomerName
- IDNumber
- MobilePhone
- Address
lets say i have 2 user that consume this API but i only want 1 user can see response with "mobilephone" and "address" but another user only customrid,customername and idnumber , the question is how can i make the api?should i create 2 api?
sorry for my bad english
i googled everywhere but i cant find the right answwer please help
Let me attempt to answer these.
A typical way would be to still just create an api like api/customer. What you should expect from the user/application consuming the API is to pass in a Customer object(not in the literal OOP sense). Something like a json object
{
idnumber: "123",
mobilephone: "",
DOB: null
}
Something like this: https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api
When processing this object you can probably check the type of the user in the code. Is it a super-user or regular user(just an example). Based on this you can return an appropriate response.
I hope I understood your question correctly.
Regarding your first question, please try to make api calls distinct as possible.
1. For the above given example, you should ideally use three different methods as the validation logic will be different in each case.
2. Also, looking at scalability and maintainability, it will be real task to handle simple change without affecting the other two.
For your second query, you can integrate both the calls in a single method. Since the underlying model is same, generate a generic response and filter out the results accordingly. Or else, create a wrapper on model to generate customized response as per user.
But no need to expose two api calls for this.
always create different endpoint for each web api calls. if the parameters that sent are a different types for each scenario then you may be able to overload the conntroller method with the same name.
this is definitely requires two different endpoints, because the response model is different. this way you don't make alot of boxing and unboxing for the response datamodel.
[![class Program
{
static void Main(string\[\] args)
{
var customer = new Customer() { CustomerID = 666, CustomerName = "john", IDNumber = "john123", MobilePhone = "9834567899", Address = "Test address 1" };
//For user 1
var allewdProperties = new string\[\] { "CustomerName", "IDNumber", "CustomerID" };//For user 1
var json = JsonConvert.SerializeObject(customer
,
new JsonSerializerSettings() { ContractResolver = new CustomContractResolver(allewdProperties.ToList()) }
);
//Data for user1
Console.WriteLine("Data for user 1");
Console.WriteLine(json);
//for user 2
allewdProperties = new string\[\] { "MobilePhone", "Address" };//For user 2
json = JsonConvert.SerializeObject(customer,
new JsonSerializerSettings() { ContractResolver = new CustomContractResolver(allewdProperties.ToList()) }
);
Console.WriteLine("Data for user 2");
Console.WriteLine(json);
Console.ReadLine();
}
}
public class Customer
{
public int CustomerID { set; get; }
public string CustomerName { set; get; }
public string IDNumber { set; get; }
public string MobilePhone { set; get; }
public string Address { set; get; }
}
public class CustomContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
IEnumerable<string> _allowedProps = null;
public CustomContractResolver(IEnumerable<string> allowedProps)
{
_allowedProps = allowedProps;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return _allowedProps.Select(p => new JsonProperty()
{
PropertyName = p,
PropertyType = type.GetProperty(p).PropertyType,
Readable = true,
Writable = true,
ValueProvider = base.CreateMemberValueProvider(type.GetMember(p).First())
}).ToList();
}
}][1]][1]

How to retrieve a single record from Firebase Real Time Database in Xamarin-Android?

I need to read only one entity from Firebase Realtime Database and convert the result into a C# class matching the structure, but I haven't found a solution clear. Having this tree:
{
"characters" : {
"c1" : {
"Email" : "peter.pan#example.com",
"LastName" : "Pan",
"Name" : "Peter"
},
"c2" : {
"Email" : "harry.potter#example.com",
"LastName" : "Potter",
"Name" : "Harry"
}
}
}
And this C# class:
public class Character
{
public string Email {get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}
I would like to retrieve only one record by email, which I know and it is unique. But, if I do include the NuGet package Xamarin.Firebase.Database there not exists a method or extension method such as OnceSingle<T>() or OnceSingleAsync<T>() in it:
Character character = await FirebaseDatabase.Instance
.GetReference(CharactersRoot)
.OrderByChild("Email")
.EqualTo("harry.potter#example.com") //Works until here
.OnceSingleAsync<Character>(); //THIS METHOD IS NOT AVAILABLE. It doesn't work.
In the other hand, by including package Xamarin.Forms.FirebaseWrapper, an upgrade of the former Firebase.Xamarin, that supports OnceSingleAsync<T>() one can code something like this:
FirebaseClient fbClient= new FirebaseClient(Root);
var task = Task<Character>.Run(async () =>
{
return await fbClient.Child(CharactersRoot)
.OrderBy("Email")
.EqualTo("harry.potter#example.com")
.OnceSingleAsync<Character>().ConfigureAwait(false)
});
var character = task.Result;
// do something with character...
But it doesn't work. It raises a System.AggregateException: 'One or more errors occurred. (Response status code does not indicate success: 400 (Bad Request).)'
The following is the only I've managed to make it work, but it is under performant because it retrieves all the collection and performs the search locally.
FirebaseClient fbClient= new FirebaseClient(Root);
var task = Task<Character>.Run(async () =>
{
return await fbClient.Child(CharactersRoot)
.OnceAsync<Character>()
.ConfigureAwait(false);
});
var character = task.Result
.Where(item => item.Object.Email == "harry.potter#example.com")
.Select(itm => itm.Object)
.FirstOrDefault();
if (character != null)
{
//Do something with character
}
Any ideas that can help to clarify my mind to do it simpler and better will be appreciated.
I would like to retrieve only one record by email, which I know and it is unique.
What you are looking for is a way to query the database based on certain value(Email).
Reading through the Firebase Database Doc, you can find the Filtering Data which explains what you want.
To meet your scenario, what you need to do is:
Sort your children elements based on Email and use EuqalTo() to limit the output data range.
var db = FirebaseDatabase.Instance;
var mDatabase = db.GetReference("characters");
Query query = mDatabase.OrderByChild("Email")
.EqualTo("harry.potter#example.com");
Create a Child event listener to retrieve the filtered data.
public class MyChildEventListener : Java.Lang.Object, IChildEventListener
{
public void OnCancelled(DatabaseError error)
{}
public void OnChildAdded(DataSnapshot snapshot, string previousChildName)
{
//this method will be triggered
//snapshot's key is c2 namly harry potter
}
public void OnChildChanged(DataSnapshot snapshot, string previousChildName)
{}
public void OnChildMoved(DataSnapshot snapshot, string previousChildName)
{}
public void OnChildRemoved(DataSnapshot snapshot)
{}
}
Register MyChildEventListener:
query.AddChildEventListener(new MyChildEventListener());
public async Task<Character> GetAttendant(string email)
{
return (await firebase
.Child("Character")
.OnceAsync<Character>()).Select(item => new Character
{
EmailAddress = email,
}).FirstOrDefault();
}
//Hope this helps

Unity JSON string array into objects from cUrl [duplicate]

This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 4 years ago.
I am not sure how to accomplish this. I am getting some users from an www request like this:
Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Authorization", "Basic "+System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("user*pass")));
WWW www = new WWW("https://somedomain.com:8000/users", null, headers);
yield return www;
Debug.Log(www.text);
The debug returns this:
[{"user_id":"ho896ty6","user_name":"Mikje Flanders","age":43},{"user_id":"ft357hj","user_name":"Anna Simpson","age":56}]
Now, I have an object like this:
public class userData
{
string user_id;
string user_name;
int age;
}
which i would like to get the data into, but not sure when the json is an array. I tried like this, but with no luck:
userData thisUser = JsonUtility.FromJson<userData>(www.text);
Hope someone can help me with this and thanks in advance :-)
1) Install Newtonsoft.json from Nuget Package Manager and add reference to your program
like using Newtonsoft.Json;
2) This is your user model class
public class User
{
public string user_id { get; set; }
public string user_name { get; set; }
public int age { get; set; }
}
3) Then deserialize your json to your model like
class Program
{
static void Main(string[] args)
{
//Sample json i get in variable
var json = #"[{'user_id':'ho896ty6','user_name':'Mikje Flanders','age':43},{'user_id':'ft357hj','user_name':'Anna Simpson','age':56}]";
//This line convert your string json to c# object
List<User> userList = JsonConvert.DeserializeObject<List<User>>(json);
//Loop through to get each object inside users list
foreach (User user in userList)
{
Console.WriteLine($"user_id: {user.user_id}, user_name: {user.user_name}, age: {user.age}");
}
Console.ReadLine();
}
}
Output:
Try once may it help you.
you will have to parse the Json using delimiters, unless your using visual studio in that case, check your nuget for Newtonsoft.Json with this package installed you can:
Using NewtonSoft.Json;
List udat = JsonConvert.DeserializeObject>(json);
foreach( userData data in udat){
//do something here to each item;
}
using jsoneditoronline
[
{
"user_id": "ho896ty6",
"user_name": "Mikje Flanders",
"age": 43
},
{
"user_id": "ft357hj",
"user_name": "Anna Simpson",
"age": 56
}
]
i cleaned up your code a little so you can see what your doing.
added some getters and setters to your class...
it looks like your getting more than one userData return in your request, so you may need a list or array. if you need help with that let me know!
public class userData
{
public string user_id {get;set;}
public string user_name{get;set;}
public int age{get;set;}
}
public class userList
{
public List<userData> users{get;set;}
}

Extracting Information from json string and add it to a list in C#

I am new in json. I want information of different users and add them to a dataGridView or dataTable or dataSet in c# (.net development). Information sample is (The json is valid):
{
"JrPwbApfIHbQhCUmVIoiVJcPYv93": {
"address": "Jessore",
"name": "Dev"
},
"iBRZAyn8TQTOgKTcByGOvJjL9ZB3": {
"address": "Bogra",
"name": "Kumar Saikat"
}
}
I want them like this :
User1 | Jessore | Dev
User2 | Bogra | Kumar Saikat
Even it would help if I could make a list for all of them.
I believe I was able to deserialise them (not sure at all) by
var model = JsonConvert.DeserializeObject<user>(json);
where user is a class.
public class Item
{
public string name;
public string address;
}
from this question-answer. From this tutorial I am able to get values if property is known. But in my case my property would be unknown, (string "User1","User2" would be random, since I will get them from a database). Any help and light on this matter would be greatly appreciated. Thank you in advance.
You're looking at a JSON dictionary, so just deserialize it as such:
public static Dictionary<string,Item> ParseJson(string source)
{
return JsonConvert.DeserializeObject<Dictionary<string,Item>>(source);
}
If you call it like this:
public static void Main()
{
var input = #"{'JrPwbApfIHbQhCUmVIoiVJcPYv93': {'address': 'Jessore','name': 'Dev' }, 'iBRZAyn8TQTOgKTcByGOvJjL9ZB3': {'address': 'Bogra','name': 'Kumar Saikat'}}";
var result = ParseJson(input);
foreach (var r in result)
{
Console.WriteLine("Key={0};Name={1};Address={2}", r.Key, r.Value.name, r.Value.address);
}
}
The output is:
Key=JrPwbApfIHbQhCUmVIoiVJcPYv93;Name=Dev;Address=Jessore
Key=iBRZAyn8TQTOgKTcByGOvJjL9ZB3;Name=Kumar Saikat;Address=Bogra
This example dumps the list to the console, but you could easily modify the for loop to add to a list instead.
See my example on DotNetFiddle
Can use the nuget package Newtonsoft.Json. This code gives you what you are looking for:
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
var json =
"{\"JrPwbApfIHbQhCUmVIoiVJcPYv93\":{\"address\":\"Jessore\",\"name\":\"Dev\"}," +
"\"iBRZAyn8TQTOgKTcByGOvJjL9ZB3\":{\"address\":\"Bogra\",\"name\":\"Kumar Saikat\"}}";
var o = JsonConvert.DeserializeObject(json);
var items = new List<Item>();
foreach (dynamic x in o as IEnumerable)
{
var i = new Item();
var y = x.First;
i.Name = y.name.Value;
i.Address = y.address.Value;
items.Add(i);
}
}
public class Item
{
public string Name { get; set; }
public string Address { get; set; }
}
}
}
Your situation is a bit strange as those autocreated names like
"JrPwbApfIHbQhCUmVIoiVJcPYv93" or else it's easier, but should be fairly easy code.
Keep in mind I use "dynamic" there which means problems will hit you at runtime NOT design time as it's not checked.
The correct way to deserialize would be as below
var model = JsonConvert.DeserializeObject<Dictionary<string, Item>>(data);
In the code sample you have posted, your "user" class name is Item but you are trying to deserialize using "User" in your code. Also please note that you cannot directly directly deserialize data into users list as it is present as a value of some random strings.
var model = JsonConvert.DeserializeObject<user>(json);
For your code to deserialize correctly, your json format should be as below :
{
{
"address": "Jessore",
"name": "Dev"
},
{
"address": "Bogra",
"name": "Kumar Saikat"
}
}

How to write a C# unit test in Visual Studio?

This is my first unit test and wanted some help clearing out my thoughts about the process of writing a unit test.
I wanted to write a test method that will add a new user - using my AddUser method in my library class.
Document doc = new Document();
[TestMethod]
public string AddUser()
{
string name = doc.AddUser("Testing User");
Assert.IsNotNull(name);
}
The error I am getting on build:
Cannot implicitly convert type void to string
This is my AddUser method:
public void AddUser(string newUserName)
{
using (var db = new DataContext())
{
User user = new User()
{
FullName = newUserName,
ID = Guid.NewGuid()
};
db.Users.InsertOnSubmit(user);
db.SubmitChanges();
}
}
Your method does not have a return value:
public void AddUser
^^^^ no return value
So you can't store it into a string:
string name = doc.AddUser("Testing User");
^^^^^^^^^^^ AddUser has no return value
Make sure you return the name from from your AddUser(string newUserName) method.
Replace your method like
public String AddUser(string newUserName)
{
using (var db = new DataContext())
{
User user = new User()
{
FullName = newUserName,
ID = Guid.NewGuid()
};
db.Users.InsertOnSubmit(user);
db.SubmitChanges();
}
return newUserName;
}
AddUser doesn't return anything.
AddUser is written as a method, not a class. Your test attempts to call it like a method, but the method is void, which does not return a value.
Simply speaking you can't assign void to string.
To make it work you can do in 2 ways:
make your method AddUser return string type or add extra parameter to your method and use keyword out for this parameter
hope it help.

Categories