How do you make a class method modify itself? - asp.net

asp.net C#4
I have a simple class to working with query strings.
A new instance is created like this:
public QueryString(string querystring)
{
try
{
_table = new Hashtable();
if (querystring.Length > 0)
{
foreach (string pair in querystring.Split('&'))
{
string[] item = pair.Split('=');
_table.Add(item[0].ToLower(), item[1]);
}
}
}
catch (Exception)
{
}
}
I want to add a method to this that will remove a key value pair. I don't want it to return a new querystring, I just want it to remove the pair from the current instance. Not sure how to do that since it says I can't assign a value to 'this'
public void Remove(string key)
{
String querystring = this.ToString();
try
{
_table = new Hashtable();
if (key.Length > 0)
{
foreach (string pair in querystring.Split('&'))
{
string[] item = pair.Split('=');
if (item[0] != key)
{
_table.Add(item[0].ToLower(), item[1]);
}
}
this = _table;
}
}
catch (Exception)
{
}
}

You're overcomplicating things. Since your class's state is made up of the _table field, all you need to do is remove the item with the given key from that field.
The following example replaces your untyped Hashtable wit a strongly-typed Dictionary. I also chose to initialize the dictionary with a LINQ statement, but you could keep your old code there if you prefer.
public class QueryString
{
private readonly Dictionary<string, string> _table;
public QueryString(string querystring)
{
if (querystring.Length > 0)
{
var pairs =
from pair in querystring.Split('&')
let item = pair.Split('=')
select new {key = item[0], value = item[1]};
_table = pairs.ToDictionary(p => p.key, p => p.value);
}
}
public void Remove(string key)
{
_table.Remove(key);
}
}

You cannot assign a value to this since it is a reference to the object itself.
However, if you remove the line this = _table; , isn't things working as they should then? I guess your ToString() is somewhat using the hashtable to generate a "printer friendly" QueryString, and if that is the case, the way I see it, your Remove() method should be working (since you are replacing the _table variable with a new HashTable not including the key-value pair you want to exclude).

you are passing a querystring into the class so the original querystring IS intact.
However you then break down the querystring into a a Hashtable of key/value pairs. If you want to keep THAT intact you need to clone the HashTable and perform the remove on the clone.
In any case it's probably a good idea to keep the querystring you are passing in as a constructor parameter in a member variable for safe keeping.

Related

How to serialize dynamic field names using JSON parser

I am using JSON.Net to serialize my objects. For eg, if this is my object
Class MainData
{
[JsonProperty("keyValues")]
string val;
}
the data for 'val' is a key value pair string like this key1:value1.
I have a scenario where I should not get the above 'keyValues' name in my final serialized string and instead get a serialized string which looks like this
{
"key1":"value1"
}
Currently with my serializer I am getting this, which is not what I need
{
"keyValues":"key:value1"
}
Can somebody guide me to any documentation/solution to dynamically assign the name of the field instead of using the default variable name/JSONProperty Name defined inside the object?
Thanks a lot in advance.
I've been struggling with this all day, what I've done is used a dictionary object and serialised this
however I had an error message that was "cannot serialise dictionary", should have read the whole message, "cannot serialise dictionary when the key is not a string or object"
this now works for me and gives me a key/value pair
i have the following objects
public class Meal {
public int mealId;
public int value;
public Meal(int MealId, int Value) {
mealId = MealId;
value = Value;
} }
public class Crew
{
public Meal[] AllocatedMeals {
get {
return new Meal[]{
new Meal(1085, 2),
new Meal(1086, 1) }; } }
public int AllocatedMealTotal {
get {
return this.AllocatedMeals.Sum(x => x.value); } }
}
then the following code
Dictionary<string,string> MealsAllocated = crew.AllocatedMeals.ToDictionary(x => x.mealId.ToString(), x => x.value.ToString());
return new JavaScriptSerializer().Serialize(
new {
Allocated = new {
Total = crew.AllocatedMealTotal,
Values = MealsAllocated } )
to get
"Allocated":{"Total":3,"Values":{"1085":"2","1086":"1"}}

how to update the values while iterating dictionary items?

I have a dictionary:
Dictionary<string, long> Reps = new Dictionary<string, long>();
and I want to update the values while iterating through all items, like this:
foreach (string key in Reps.keys)
{
Reps[key] = 0;
}
it is giving me an error saying:
"Collection was modified; enumeration operation may not execute"
can anyone tell me why it is giving me this error, because I have one more function that adds the value, and it is called when button is clicked:
public static void Increment(string RepId, int amount)
{
long _value = Convert.ToInt64(Reps[RepId]);
_value = _value + amount;
Reps[RepId] = _value;
}
and this function is working fine. so whats the problem when updating all the values? And whats the solution for this?
more simplified, do this:
foreach (string key in Reps.keys.ToList())
{
Reps[key] = 0;
}
and the reason for the error is you are trying to edit the actual object which is in use and if you make a copy of it and then use it like this:
var repscopy = Reps;
foreach (string key in repscopy.keys)
{
Reps[key] = 0;
}
it'll give the same error as it also pointing to the original object, and when the ToList() is added it created a new object of List
The problem is no updating the values, you just cannot change the collection that your foreach() is based on while the foreach is being iterated.
Try somehting like this
List<string> keylist = Reps.keys.ToList();
foreach(string r in keylist)
{
Reps[r] = 0;
}
this would work.
This happens because you are changing the element in the Dictionary<string, long> while looping over it with foreach. Try this.
foreach (string key in Reps.Keys.ToList())
{
Reps[key] = 0;
}
Now you are looping over a list created from the dictionarys key. As it is not the original collection thats modified, the error will go away.

Pass property from controller to Model

I am trying to pass a variable from a method in my Controller to a method in a Model. Since the method in the Model takes one argument (which was designed earlier), I cannot pass my variable as an argument to the method in the Model. And also, the method in this Model is called by other controllers too, so if I change the argument, I have to change all the controllers too, which would be a tedious task.
What I have been trying so far is- I created one MyVariableClass and declared a property. Then I instantiated that class and set the property string to the variable that I wanted to pass. Now, in my Model's method, I instantiated the same MyVariableClass again, but when I did that, the value of the variable was set to null. The code I have right now is -
public ActionResult ItemInformation( string id)
{
//Pass a string to MyVariable
MyVariableVClass params = new MyVariableClass();
params.myVariable = "abc";
//This is what My Model is taking as an argument(id), and I don't want to
//pass mYvariable along with that argument because it will break other controllers
// too which calls this method
var itemInformation = _repository.GetItemInformation(id);
return View(itemInformation);
}
and MyVariableClass
public class MyVariableClass
{
public string myVariable { get; set; }
}
and the method in My Model
public IList<Items> GetItemInformation(string itemId)
{
MyVariableClass webType = new MyVariableClass();
var _params = webType.myVariable;
//Check this variable and perform database query
if (_params =="this")
{
var query = myFirstQuery;
}
else
{
var query = mySecondQuery;
}
//return ....
}
Anybody has solution to this? Thanks in Advance!
Any reason why subclassing your model and overriding the GetItemInformation method wouldn't work? Or, even easier, why not just overload the GetItemInformation method with one that takes two strings? Your other controllers can still use the one that only takes a single string.
public IList<Items> GetItemInformation(string itemId, MyVariableClass webType)
{
var _params = webType.myVariable;
//Check this variable and perform database query
if (_params == "this")
{
var query = myFirstQuery;
}
else
{
var query = mySecondQuery;
}
//return ....
}
public IList<Items> GetItemInformation(string itemId)
{
MyVariableClass fauxType = new MyVariableClass();
fauxType.myVariable = "not this";
return GetItemInformation(itemId, fauxType);
}
Try using session variable.

ASP.NET: How to check the value of a cached dictionary?

Not really sure how to do this but i can cache the dictionary like this:
Cache.Insert("CacheName", Dictionary)
need some direction. the dictionary is two string values taken from a database. The user will input a string and i need to compare it against the values in the cached dictionary.
In general you need to access the object from the cache, cast it, and the use the ContainsKey property. Here is an example:
First add the dictionary to the Cache:
IDictionary<string, string> testDict = new Dictionary<string, string>();
testDict.Add("Test", "test");
Cache.Insert("dict", testDict);
Then, when you need to do so, access the cached object and use it ContainsKey property to determine whether it contains the searched key or not.
var dict = Cache["dict"] as IDictionary<string, string>;
if (dict != null)
{
string testValue = "test";
if(dict.ContainsKey(testValue))
{
/* some logic here */
}
}
You can access the value the following way:
if (dict != null)
{
string testValue = "test";
if(dict.ContainsKey(testValue))
{
/* some logic here */
string value = dict[testValue];
}
}
You can get the dictionary out of the cache by writing
var dict = (Dictionary<X, Y>) cache["CacheName"];

Iterate through Custom Object's Property Names and Values

I'm trying to create an export Excel/CSV function that will iterate through a custom object and first output the property names and then output the values. I want to use reflection only where necessary so I'm attempting to save the property names when I output the headers and then reuse them to print the values.
Is this possible? I'm a little weary of using reflection in a loop but is there a better way?
Psuedo Code:
Dim Cust1 = New Customer("Tom", "123 Main Street")
Dim Cust2 = New Customer("Mike", "456 Main Street")
Dim Cust3 = New Customer("Joe", "789 Main Street")
Dim CustList As New Arraylist()
CustList.Add(Cust1)
CustList.Add(Cust2)
CustList.Add(Cust3)
CSVExport(CustList, New Customer())
Function CSVExport(List As ArrayList, CustomObject as Object) As StringWriter
Dim sw as Stringwriter
dim proplist as arraylist
'output header
Foreach CustProperty as System.Reflection.PropertyInfo CustomObject.GetType().GetProperties()
proplist.add(CustProperty.Name)
sw.write(CustProperty + ",")
EndFor
'output body
'??
'?? Here I'd like to loop through PropList and List instead of using reflection
'??
Return Sw
End Function
Its all reflection regardless of whether or not you have the names stored in a list.
Do you have a degree of control over the CustomObject. You could store the info within the CustomObject and query that info instead without using reflection. For instance, this is the code I use for my basic domain objects.
public class DomainObject
{
private HashTable _values = new HashTable();
public HashTable Properties
{
get
{
return _values;
}
}
protected void SetValue<T>(string property, T value)
{
if (_values.ContainsKey(property))
{
_values[property] = value;
}
else
{
_values.Add(property, value);
}
}
protected T GetValue<T>(string property)
{
if (_values.ContainsKey(property))
{
return (T)_values[property];
}
else
{
return default(T);
}
}
}
public class TootsieRoll : DomainObject
{
public string Size
{
get { return GetValue<string>("Size"); }
set { SetValue<string>("Size",value); }
}
public string Flavor
{
get { return GetValue<string>("Flavor"); }
set { SetVlaue<string>("Flavor", value); }
}
public int Ounces
{
get { return GetValue<int>("Ounces"); }
set { SetValue<int>("Ounces", value); }
}
}
Now your CSV code would only need to access and loop through the Key=>Value pairs within the "Properties" HashTable it inherited from the DomainObject to get the names and values. But obviously this only works if you have a level of control over your objects necessry to make them inherit from the DomainObject, and it wouldnt involve 30 years of drugery to rewrite all your property accessors. If that is the case, then reflection is your way to go.
In your Pseudo Code you're already populating an arraylist using reflection. If all you want to do is loop through the ArrayList, you can have a look at the ArrayList Class MSDN entry. It shows how to implement IEnumerable to iterate your array list, e.g:
Dim obj As [Object]
For Each obj In CType(myList, IENumberable)
Console.Write(" : {0}", obj)
Next obj
That's untested as is, I'm not sure if it should be CType(myList, IENumberable) or DirectCast(myList, IENumberable).
There is another option, using Object Serialization in VB.Net, a road far less traveled (at least around our offices).

Resources