Put a key in Redis via C# - c#

I am trying to build custom DLL which puts a particular key to Redis key-value storage. I builds, executes, but doesnt do anything. No key added. This is my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using TSLab.Script;
using TSLab.Script.Handlers;
using StackExchange.Redis;
namespace TSLab.pmus
{
[HandlerCategory("Redis")]
[InputsCount(2)]
public class WriteToRedis : ITwoSourcesHandler, ISecurityInput0, IDoubleInputs, IDoubleReturns, IStreamHandler, IValuesHandlerWithNumber, IContextUses
{
private ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
public IContext Context { set; private get; }
[HandlerParameter(Name = "table", NotOptimized = true)]
public int table { get; set; }
[HandlerParameter(Name = "key", Default = "mykey", NotOptimized = true)]
public string key { get; set; }
public IList<double> Execute(ISecurity sec, params IList<double>[] dataArr)
{
return new double[0];
}
public double Execute(ISecurity sec, ConnectionMultiplexer redis, params double[] dataArr)
{
IDatabase db = redis.GetDatabase(table);
db.StringSet("testKey", "Test string");
return 0;
}
}
}

As #MarcGravell said, the problem was in two 'Execute' methods.
I changed code to:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using TSLab.Script;
using TSLab.Script.Handlers;
using StackExchange.Redis;
namespace TSLab.pmus
{
[HandlerCategory("Redis")]
[InputsCount(2)]
public class WriteToRedis : ITwoSourcesHandler, ISecurityInput0, IDoubleInputs, IDoubleReturns, IStreamHandler, IValuesHandlerWithNumber, IContextUses
{
private ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
public IContext Context { set; private get; }
[HandlerParameter(Name = "table", NotOptimized = true)]
public int table { get; set; }
[HandlerParameter(Name = "key", Default = "mykey", NotOptimized = true)]
public string key { get; set; }
public IList<double> Execute(ISecurity sec, params IList<double>[] dataArr)
{
IDatabase db = redis.GetDatabase(table);
db.StringSet("testKey", "Test string");
return new double[0];
}
}
}
And now it works fine.

Related

dotNet Core 5 API Service adds objects to list but result has multiple copies of the last item

dotNet Core 5 C# Web API project, Service class adds objects (based on a viewmodel) to a list. Debugging shows all data correct as the object is built and added to the List, but the returned result has multiple (matching the count it should have) copies of the last item added only. Service code and viewmodel code below. What am I missing?
using FS.Data.Repositories;
using FS.Models;
using FS.ViewModels;
using FS.ViewModels.APVendor;
using Microsoft.Extensions.Options;
using NLog;
using System.Collections;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
namespace FS.Services
{
public class GLAccountSetService : IGLAccountSetService
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
private readonly IOptions<AppSettingsModel> AppSettings;
private readonly HttpClient Client;
GlAccountSetResponseViewModel result = new GlAccountSetResponseViewModel();
public GLAccountSetService(HttpClient client, IOptions<AppSettingsModel> app)
{
Client = client; //?? throw new ArgumentNullException(nameof(client));
AppSettings = app;
}
public async Task<GlAccountSetResponseViewModel> GetGLAccountSets(IList<GlAccountSetRequestViewModel> req, IAPCorpRepository apcr)
{
result.GlAccountSetViewModels = new List<GlAccountSetViewModel>();
result.SuccessErrorWarningResult = new SuccessErrorWarningResult();
GlAccountSetViewModel accountSet = new GlAccountSetViewModel();
string payorID = "";
string payeeID = "";
string payorCashAccount = "";
string payeeCashAccount = "";
string expenseAccount = "";
string offsetAccount = "";
string type = "";
long reqID = 0;
foreach (GlAccountSetRequestViewModel glr in req)
{
type = glr.Type;
expenseMain = glr.ExpenseAccount;
payorID = glr.PayorCorpID;
payeeID = glr.PayeeCorpID;
reqID = glr.ReqID;
//...skipping calculation code that works
accountSet.ExpenseAccount = expenseAccount;
accountSet.PayorCashAccount = payorCashAccount;
accountSet.PayeeCashAccount = payeeCashAccount;
accountSet.OffsetAccount = offsetAccount;
accountSet.ReqID = reqID;
result.GlAccountSetViewModels.Add(accountSet);
}
return result;
}
}
}
using FS.Common;
using System.Collections.Generic;
namespace FS.ViewModels.APVendor
{
public class GlAccountSetResponseViewModel : FSObject<GlAccountSetResponseViewModel>
{
public IList<GlAccountSetViewModel> GlAccountSetViewModels { get; set; }
public SuccessErrorWarningResult SuccessErrorWarningResult { get; set; }
}
}
namespace FS.ViewModels.APVendor
{
public class GlAccountSetViewModel
{
public string ExpenseAccount { get; set; }
public string PayorCashAccount { get; set; }
public string PayeeCashAccount { get; set; }
public string OffsetAccount { get; set; }
public long ReqID { get; set; }
}
}
You're adding the same accountSet instance to the list multiple times, only modifying it in the loop. Thus all references to it in the list will "have" the most recently set values.
You need to create a new GlAccountSetViewModel instance in the loop and add that one, or make it a struct to copy it when being added.

Getting parts of a repetitive string in C#

Extracting parts of a string is a common question, but here the string content, e.g. ' "main\":{\"temp\": ' is repetitive:
string test = "{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[{\"dt\":1576810800,\"main\":{\"temp\":288.19,\"feels_like\":284.44,\"temp_min\":288.19,\"temp_max\":291.53,\"{\"dt\":1576821600,\"main\":{ \"temp\":283.97,\"feels_like\":281.56,\"temp_min\":283.97,\"temp_max\":286.47,\"pressure\":1007,\"sea_level\":1007,\"grnd_level\":997,\"humidity\":93,\"temp_kf\":-2.5},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rai\",\"icon\":\"10d\"}],\"clouds\":{\"all\":90},\"wind\"";
Using
string s = test.Substring(test.IndexOf("\"main\":{\"temp\":") + 15);
I get
288.19,"feels_like":284.44,,"temp_min":288.19,"temp_max":291.53,"{"dt":157682160
0,"main":{ "temp":283.97,"feels_like":281.56,"temp_min":283.97,"temp_max":286.47
,"pressure":1007,"sea_level":1007,"grnd_level":997,"humidity":93,"temp_kf":-2.5}
,"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}],
"clouds":{"all":90},"wind"
instead of
288.19
Any clue what command would help? Should be something that can be adapted to ' "temp_max" ' or ' "pressure" '.
Cheers
Thanks to Mohammed, here's the working code spitting out all tempeatures:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json;
namespace ConsoleApp2
{
public class RootObject
{
public List<MyList> list { get; set; }
}
public class MyList
{
public Main main { get; set; }
}
public class Main
{
public double temp { get; set; }
}
class Program
{
static void Main()
{
using (WebClient client = new WebClient())
{
Console.WriteLine("ACCESSING ...");
string test = client.DownloadString("http://api.openweathermap.org/data/2.5/forecast?q=Auckland,NZ&APPID=45c3e583468bf450fc17026d6734507e");
//string test = "{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[{\"dt\":1576810800,\"main\":{\"temp\":288.19,\"feels_like\":284.44,\"temp_min\":288.19,\"temp_max\":291.53,\"{\"dt\":1576821600,\"main\":{ \"temp\":283.97,\"feels_like\":281.56,\"temp_min\":283.97,\"temp_max\":286.47,\"pressure\":1007,\"sea_level\":1007,\"grnd_level\":997,\"humidity\":93,\"temp_kf\":-2.5},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rai\",\"icon\":\"10d\"}],\"clouds\":{\"all\":90},\"wind\"";
var myobject = JsonConvert.DeserializeObject<RootObject>(test); //test is JSON response as string
foreach (var item in myobject.list)
{
var temp = item.main.temp;
Console.WriteLine(temp);
}
Console.ReadLine();
}
}
}
}
Using
var regexGroups = Regex.Matches(test, "\"main\" ?: ?{ ?\"temp\" ?: ?(\\d+\\.\\d+)")
.Select(x => x.Groups[1].Value);
You can get all \"main\":{\"temp\": values.
//classes.cs
public class RootObject
{
public List<MyList> list { get; set; }
}
public class MyList
{
public Main main { get; set; }
}
public class Main
{
public double temp { get; set; }
}
//API client
using Newtonsoft.Json;
var myobject = JsonConvert.DeserializeObject<RootObject>(test); //test is JSON response as string
foreach(var item in myobject.list){
var temp = item.main.temp;
}
//Hope it helps

Is it bad to use static ADO.NET function for a website?

Below is a model class for my ASP.NET MVC Project.
I am concerned about the below code. Is it a good idea to use static function to return a list for a website when multiple users will be using it?
Will there be a conflict when users are accessing the data through a static function?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BusinessLogic;
using System.Configuration;
using System.Data;
namespace Exam.Models
{
public class QuestionGroups
{
public int GroupID { get; set; }
public DateTime CreatedDate { get; set; }
public string GroupTitle { get; set; }
public string PreviewText { get; set; }
public string Keywords { get; set; }
public int ExamID { get; set; }
public string ExamName { get; set; }
public static List<QuestionGroups> GetQuestionGroupList ()
{
List<QuestionGroups> questionGroupList = new List<QuestionGroups>();
string constr = ConfigurationManager.ConnectionStrings["ExamConstr"].ConnectionString;
string sqlQuery = "SELECT A.*, B.ExamName FROM QuestionGroups A INNER JOIN Exams B ON A.ExamID = B.ExamID";
DataLayer dl = new DataLayer(constr);
DataTable tableData = dl.GetRows(sqlQuery, null);
foreach(DataRow singleRow in tableData.Rows)
{
QuestionGroups qgroup = new QuestionGroups();
qgroup.GroupID = Convert.ToInt32(singleRow["GroupID"]) ;
qgroup.CreatedDate = Convert.ToDateTime(singleRow["CreatedDate"]);
qgroup.GroupTitle = singleRow["GroupTitle"].ToString();
qgroup.PreviewText = singleRow["PreviewText"].ToString();
qgroup.Keywords = singleRow["Keywords"].ToString();
qgroup.ExamID = Convert.ToInt32(singleRow["ExamID"]);
qgroup.ExamName = singleRow["ExamName"].ToString();
questionGroupList.Add(qgroup);
}
return questionGroupList;
}
}
}
Below is the code of my DataLayer class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace BusinessLogic
{
public class DataLayer
{
string connectionString = "";
public DataLayer(string constr)
{
connectionString = constr;
}
public DataTable GetRows(string sqlQuery, SqlParameter[] sqlParam)
{
DataTable tableData = new DataTable();
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand com = new SqlCommand(sqlQuery, con))
{
com.Parameters.AddRange(sqlParam);
con.Open();
SqlDataReader dread = com.ExecuteReader();
var dataTable = new DataTable();
dataTable.Load(dread);
dread.Close();
}
}
return tableData;
}
}
}
Static functions are fine - they just let you call the function without an instance of the containing class.
Static data can be very bad for ASP.NET sites since static data will be shared across all sessions.
That said, since you're not using any static data, there is no reason for the method to be static. I would say you need to separate the "get data" function from the data class itself into a "repository" class or the like, and use non-static methods.

Using Linq to sql for windows phone

I am trying to show out History for my windows 8 application which includes date, time , Floor ,Zone , Longitutde and latitude. I tried the code below but there was no output in it above.
THe image you can see on the link down below that I want to show on my application.But I can see nothing when I run my program.
I have three classes for using linq to sql to retrieve database and show information through it.The main class is History.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.IO.IsolatedStorage;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Text;
using System.Data.Linq;
namespace SmartParking
{
public partial class History : PhoneApplicationPage
{
private readonly HistoryDataContext historylog;
public History()
{
InitializeComponent();
// createDB();
}
public HistoryDataContext Log
{
get { return historylog; }
}
public void createDB()
{
using (HistoryDataContext historylog = new HistoryDataContext(HistoryDataContext.DBConnectionString))
{
if (historylog.DatabaseExists() == false)
{
historylog.CreateDatabase();
addDataDB();
}
}
}
public void addDataDB()
{
using (HistoryDataContext historylog = new HistoryDataContext(HistoryDataContext.DBConnectionString))
{
HistoryDB hdb = new HistoryDB
{
// Date = DateTime.Today,
// Time = DateTime.Now.TimeOfDay,
Zone = Checkin.Zone_st,
Floor = Checkin.Floor_st,
location_latitude = Checkin.Latitud_do,
location_longtitud = Checkin.Longtitude_do
};
historylog.history.InsertOnSubmit(hdb);
historylog.SubmitChanges();
GetHistoryLog();
}
}
public IList<HistoryDB> GetHistoryLog()
{
IList<HistoryDB> HistoryList = null;
using (HistoryDataContext historylog = new HistoryDataContext(HistoryDataContext.DBConnectionString))
{
IQueryable<HistoryDB> query = from histoy in historylog.history select histoy;
HistoryList = query.ToList();
}
return HistoryList ;
}
}
}
The next class is HistoryDB.cs with the tables and columns
[Table]
public class HistoryDB
{
[Column(CanBeNull = false)]
public DateTime Date
{ get; set; }
[Column(CanBeNull = false)]
public TimeSpan Time
{ get; set; }
[Column(CanBeNull = false)]
public String Zone
{ get; set; }
[Column(CanBeNull = false)]
public String Floor
{ get; set; }
[Column(CanBeNull = false)]
public double location_latitude
{ get; set; }
[Column(CanBeNull = false)]
public double location_longtitud
{ get; set; }
}
The next class is HistoryDataContext.cs.
public class HistoryDataContext:DataContext
{
public static string DBConnectionString = "Data Source=isostore:/History.sdf";
public HistoryDataContext(string DBConnectionString)
: base(DBConnectionString)
{
}
public Table<HistoryDB> history
{
get
{
return this.GetTable<HistoryDB>();
}
}
}
What I am trying is to get information from the NFC tag and store it in the local database and then retrieve it in the history page. The code below is to read from nfc tag but I dunno how again to save in the local databse from there and retrive it back in the history page.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Networking.Proximity;
using NdefLibrary.Ndef;
using NdefLibraryWp.Ndef;
using Windows.Networking.Sockets; // needed for DataReader, DataWriter
using Windows.UI.Popups;
using Microsoft.Phone.UserData;
using System.Text;
using Windows.Phone.PersonalInformation;
using SmartParking.Resources;
using System.Diagnostics;
namespace SmartParking
{
public partial class Checkin : PhoneApplicationPage
{
private ProximityDevice _device;
private long _subscriptionIdNdef;
public static double Latitud_do { get; set; }
public static double Longtitude_do { get; set; }
public static string Floor_st { get; set; }
public static string Zone_st { get; set; }
History store = new History();
public Checkin()
{
InitializeProximityDevice();
InitializeComponent();
}
private void SetLogStatus(string newStatus)
{
Dispatcher.BeginInvoke(() => { if (LogStatus != null) LogStatus.Text = newStatus; });
}
private void SetFloorStatus(string newStatus)
{
Dispatcher.BeginInvoke(() => { if (FloorStatus != null) FloorStatus.Text = newStatus; });
}
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
MessageBox.Show(" ");
}
private void InitializeProximityDevice()
{
_device = Windows.Networking.Proximity.ProximityDevice.GetDefault();
if (_device != null)
{
_subscriptionIdNdef = _device.SubscribeForMessage("NDEF", MessageReceivedHandler);
}
}
private void MessageReceivedHandler(ProximityDevice sender, ProximityMessage message)
{
var rawMsg = message.Data.ToArray();
var ndefMessage = NdefMessage.FromByteArray(rawMsg);
////// Loop over all records contained in the NDEF message
foreach (NdefRecord record in ndefMessage)
{
if (NdefTextRecord.IsRecordType(record))
{
// Convert and extract URI info
var textRecord = new NdefTextRecord(record);
//var str = textRecord.Text;
string[] str = textRecord.Text.Split('|');
var latitude = str[2];
Latitud_do = double.Parse(latitude);
var longtitude = str[3];
Longtitude_do = double.Parse(longtitude);
var Floor_st = str[0];
var Zone_st = str[1];
SetLogStatus("Floor: " + Floor_st + " Zone: " + Zone_st );
SetFloorStatus("Longitude: " + latitude + " Longitude: " + longtitude);
store.addDataDB();
}
}
}
}
}
The Image of the table is in the link below
https://www.dropbox.com/s/g87yta6hegjstge/Untitled.png?dl=0
try this:
In Database There Should be a Primary key otherwise it would Throw an Exception and the Datatype that is TimeSpan not supported so you need to take DateTime or String as Done Below :
[Table]
public class HistoryDB
{
[Column(IsPrimaryKey = true)]
public int Id { get; set; }
[Column(CanBeNull = false)]
public DateTime Date
{ get; set; }
[Column(CanBeNull = false)]
public DateTime Time
{ get; set; }
[Column(CanBeNull = false)]
public String Zone
{ get; set; }
[Column(CanBeNull = false)]
public String Floor
{ get; set; }
[Column(CanBeNull = false)]
public double location_latitude
{ get; set; }
[Column(CanBeNull = false)]
public double location_longtitud
{ get; set; }
}
public void addDataDB()
{
using (HistoryDataContext historylog = new HistoryDataContext(HistoryDataContext.DBConnectionString))
{
HistoryDB hdb = new HistoryDB
{
Id = 0,
Date = DateTime.Today,
Time = DateTime.Now,
Zone = "Zone",
Floor = "Floore",
location_latitude = 00.00,
location_longtitud = 00.00
};
historylog.history.InsertOnSubmit(hdb);
historylog.SubmitChanges();
GetHistoryLog();
}
}
I have implemented above thing and its working Properly

error when trying to add object to dictionary

I got a code with a list which im trying to change to dictionary. my problem its that in 'BankRates.cs' i fail to add objects to my dictionary. i get error :no overload of method 'Add' takes 1 argument...can some explain why?? (i understand i should add a string to the function but when i try to add empty one to make it compile, the dictionary contains only one nonfunctional object)
i have this 4 cs files:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Converter
{
class Currency
{
//members
//getters and setters
public string Code { get; set; }
public string Name { get; set; }
public double Rate { get; set; }
public double Unit { get; set; }
public string Country { get; set; }
//constractor
public Currency(string code, string name, double rate, double unit, string country)
{
this.Code = code;
this.Name = name;
this.Rate = rate;
this.Unit = unit;
this.Country = country;
}
//override ToString method for visualization
public override string ToString()
{
return (Name + "-" +Code);
}
}
}
currencyDictionary:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Converter
{
class CurrencyDic
{
//setter and getter
public Dictionary<string,Currency> currencyDic { get; set; }
//constractor
public CurrencyDic()
{
currencyDic = new Dictionary<string,Currency>();
}
public CurrencyDic(Dictionary<string,Currency> cur)
{
currencyDic = new Dictionary<string,Currency>(cur);
}
// implements foreach
public IEnumerator<Currency> GetEnumerator()
{
foreach (Currency cur in currencyDic.Values) { yield return cur;}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Converter
{
interface IBankRates
{
void GetRates();
double Convert(Currency from, Currency to, double amount);
}
}
and the last one:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.IO;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.Remoting.Messaging;
namespace Converter
{
class BankRates:IBankRates
{
private string Bank_URL = "http://www.boi.org.il/currency.xml";
CurrencyDic currencyDic = new CurrencyDic();
public void GetRates()
{
XDocument xdoc = new XDocument();
try
{
xdoc = XDocument.Load(Bank_URL);}
catch (XmlException)
{
MessageBox.Show("Failed to load Xml file");
System.Environment.Exit(1);
}
//load the xml
var allCurencies = from currency in xdoc.Descendants("CURRENCY") //linq query
select new
{
Name = currency.Descendants("NAME").First().Value,
Unit = currency.Descendants("UNIT").First().Value,
Code = currency.Descendants("CURRENCYCODE").First().Value,
Cuntry = currency.Descendants("COUNTRY").First().Value,
Rate = currency.Descendants("RATE").First().Value
};
foreach (var currency in allCurencies)
{
currencyDic.currencyDic.Add(new Currency(currency.Code, currency.Name,
double.Parse(currency.Rate),
double.Parse(currency.Unit), currency.Cuntry));
}
}
//returns the list
public CurrencyDic getDic()
{
return currencyDic;
}
//makes the converting calculation
public double Convert(Currency from,Currency to, double amount)
{
double inRate, outRate, excangeRate;
inRate = from.Rate / from.Unit;
outRate = to.Rate / to.Unit;
excangeRate = inRate / outRate;
return (amount * excangeRate);
}
}
}

Categories

Resources