List being emptied on submit - c#

I have a C# application where I need the list to "remember" what has been previously entered in it.
http://oi40.tinypic.com/2ivhcuw.jpg
So once the attendee has been added, the previous attendee will stay in the list if a new one is added. Currently it just displays the most recent attendee, I want them to save, until I decide to clear them (maybe in a session?)
List<Information> infoList = new List<Information>();
Information data = new Information();
firstName = resultEntry.Properties["givenname"].Value.ToString();
lastName = resultEntry.Properties["sn"].Value.ToString();
fullName = firstName + " " + lastName;
//data.CWID = resultEntry.Properties["username"].Value.ToString();
data.FullName = fullName;
// data.Email = resultEntry.Properties["email"].Value.ToString();
infoList.Add(data);

For storing items into a session:
Session["MyInformation"] = data;
receiving data out of a session
List<information> data = (List<information>)Session["MyInformation"];
But beware: Sessions ought to be forgotten.
One might consider viewstate but beware here to: viewstates do make a page slow. (easy testings in how big a html page gets when viewstate is added)
one last option might be to include cookies for getting a longer hold on the items.
Write a cookie: http://msdn.microsoft.com/en-us/library/78c837bd(v=vs.100).aspx
Read a cookie : http://msdn.microsoft.com/en-us/library/bd70eh18(v=vs.100).aspx
another option is to hold the data in database => this however means more traffic.
(also a small hint on the sessions, place them in a seperate static class so you can get them through the whole project instead of one page
public static class MySessions
{
public static List<Information> MyData
{
get{
//EDIT in the GET
if(HttpContext.Current.Session["MyInformation"] != null)
return (List<information>)HttpContext.Current.Session["MyInformation"];
else
{
HttpContext.Current.Session["MyInformation"] = new List<Information>();
return new List<Information>();
}
}
set{HttpContext.Current.Session["MyInformation"] = value;}
}
}
EDIT:
use the class as follows: (it's a static class, by entering the classname followed by the property, you can call for it instead of first instantiating the class.
//Set the value from Somewhere
MySessions.MyData = new List<Information>();
//get the values from somewhere
var myInfo = MySessions.MyData;

Depending on the length of the duration of "saving":
Use ViewState - if you want the list to be empty on a page load (not postback). (i.e. ViewState["data"] = infoList)
Use Session - if you want to manually empty the list based on some condition.

Related

How to use variable static list when multi user access

this variable works fine if used by one user, but when used by two or more users then the "static" variable will be read by the next user, the first user instance when filling the gridview there are 5 rows of data and I try to access through other browser when entering the page, gridview on the second user already filled 5 rows of data in input by the first user. then how the solution to this problem? please see my code and give me an solutions. thanks.
static List<ServicesModels> _gridPackageDetail = new List<ServicesModels>();
private void AddListAction(string alfa, string beta)
{
ServicesModels data = new ServicesModels()
{
id_service_detail = Guid.NewGuid(),
scope_name = alfa,
detail_name= beta
};
_gridPackageDetail.Add(data);
}
public ActionResult GridPackageDetail()
{
ViewBag.DataListPackage = _gridPackageDetail.OrderBy(a => a.scope_name).ToList();
return PartialView();
}
my code in mvc3 controller.
The code is working fine, because this is what intended by "static", to have the same data for multi users. In your case you need to create a list or dictionary or multi-dimensional array (any data structure you are comfortABLE with) and save the data per use in it, and then retrieve the data when needed based on the user id.
static List<ServicesModels> _gridPackageDetail = new List<ServicesModels>();
private void AddListAction(string alfa, string beta)
{
ServicesModels data = new ServicesModels()
{
id_service_detail = Guid.NewGuid(),
scope_name = alfa,
detail_name= beta,
user_id = getTheID()// Get the id of the user
};
_gridPackageDetail.Add(data);
}
public ActionResult GridPackageDetail()
{
ViewBag.DataListPackage = _gridPackageDetail.OrderBy(a => a.scope_name && user_id ==getTheID()).ToList();
return PartialView();
}
replace getTheID() by your way of getting the id of the user.
This is used if you want to keep the data of all users. else you should remove the static keyword.

Appending chat history and insert it into the same file

I have a case that I need to log the chat history (I am capable of doing this already) and I need it to be logged in a text file (able to log it already).
The problem is the file is being accessed all over again so I need to somewhere store the filename of the file somewhere else, right now I have this code:
public async Task LogAsync(IActivity activity)
{
var conversation = "";
var convActivity = "";
var ctr = 0;
conversation = $"From: {activity.From.Name}\r\n To: {activity.Recipient.Name}\r\n Message: {activity.AsMessageActivity()?.Attachments}\r\n ";
fileName = "test";
await LogActivity(fileName, conversation);
}
The LogActivity is the one handling the append of the file. So what I need is I want the unique fileName to be instantiated once while appending the file all over again or rather while continuously accessing this method.
Or is there a way to log the chat history of bot once like if a Context.Done was called or before it?
Or the inefficient way I am thinking of was making use of .From.Name and .Recipient.Name
So the result will be:
if (activity.From.Name.ToLower().ToString() == "user")
{
name.Value = $"{activity.From.Name.ToString()}";
conversation = $"From: {activity.From.Name}\r\n To: {activity.Recipient.Name}\n Message: {activity.AsMessageActivity()?.Text}\n";
}
else
{
name.Value = $"{activity.Recipient.Name.ToString()}";
conversation = $"From: {activity.From.Name}\r\n To: {activity.Recipient.Name}\r\n Message: {activity.AsMessageActivity()?.Text}\r\n ";
}
await LogActivity(name.Value, conversation);
If I understand correctly, you just want to persist a value throughout a conversation; in this case a filename.
If that's correct, then you can store it in PrivateConversationData which lives in thecontext.
For example:
context.PrivateConversationData.SetValue<string>("log_filename", "log-name-here.txt");
For an example, check here: https://www.robinosborne.co.uk/2016/08/08/persisting-data-within-a-conversation-with-botframeworks-dialogs/
For a full example about persisting the whole conversation, this might also help: https://www.robinosborne.co.uk/2016/11/22/transcribing-messages-in-botframework/
Okay, rposbo's answer also works if you have your own logger (that's what I observed, or maybe if you can implement it the other way around, you can use it, it's up to you) that will persist on each every conversation you have with your bot, see the link he provided on how to persist the whole conversation. As for my end, I used dictionary to store the filename. So down below is what I did
public string _Name { get { return name; } }
string name;
public static Dictionary<string, string> fileName = new Dictionary<string, string>();
public void SetFileName(string _fileName)
{
var isCached = fileName.TryGetValue("filename", out name);
if (!isCached)
{
name = $"{_fileName}_{DateTime.Now.Ticks}";
fileName.Add("filename", name);
}
}
Btw, can I accept two answers? since rposbo's answer also works, but it just doesn't fit for me.

Can I save the contents of an ObservableCollection so that the list is still intact when I restart my app?

What I want to do is have the user add items to the list. Then when they add an item I need the list to save, so that when the user closes the app and opens it again, the list they've created is still there.
Right now, I can add items to my list, but as soon as i close the app they will be gone.
private static ObservableCollection<ViewModels.ZoneViewModel> Zones = new ObservableCollection<ViewModels.ZoneViewModel>();
public void PopulateListView(string image, string name, string address)
{
if (name != "" && address != "")
{
Zones.Add(new ViewModels.ZoneViewModel { Image = image, Name = name, Address = address });
Application.Current.Properties["zoneslist"] = Zones;
}
}
protected override void OnAppearing()
{
if (Application.Current.Properties.ContainsKey("zoneslist"))
{
// Put the contents of the "zoneslist" key into a variable as a string.
var savedZones = Application.Current.Properties["zoneslist"] as ObservableCollection<ViewModels.ZoneViewModel>;
// Set the listviews' itemssource to the savedzones list.
zonesList.ItemsSource = savedZones;
}
}
Here's the code I use right now, I thought this could work to save it but that doesn't work.
EDIT: So I've tried what #Alessandro Calario suggested and after using json serialization the listview just gives me a ton of empty list items(even though i only added one). But an item is added and is saved, even when the app is closed. Progress, at least, but I'm not quite there yet. Anyone know a solution?
my code:
public void PopulateListView(string image, string name, string address)
{
if (name != "" && address != "")
{
Zones.Add(new ViewModels.ZoneViewModel { Image = image, Name = name, Address = address });
//Serialize to json string
var json = JsonConvert.SerializeObject(Zones);
Application.Current.Properties["zoneslist"] = json;
}
}
protected override void OnAppearing()
{
if (Application.Current.Properties.ContainsKey("zoneslist"))
{
// Put the contents of the "zoneslist" key into a variable as a string.
var savedZones = Application.Current.Properties["zoneslist"] as string; //ObservableCollection<ViewModels.ZoneViewModel>
JsonConvert.DeserializeObject<ObservableCollection<ViewModels.ZoneViewModel>>(savedZones);
// Set the listviews' itemssource to the savedzones list.
zonesList.ItemsSource = savedZones;
}
}
I think you can Serialize your List of Objects to a json String and save it to Application Properties
If using 3rd parties libraries is not a thing for your project I highly recommend you to use Akavache. This is an Async, persistent key-value store.
Once setup is very simple to use.
//To Insert your object
IObservable<Unit> InsertObject<T>(string key, T value, DateTimeOffset? absoluteExpiration = null);
//To Get your object
IObservable<T> GetObject<T>(string key);
where T can be your whole list.
Of course it's a little more than this but trust me just a little. Read the full documentation and hope it fits your needs.
The Application Properties only stores primitive types.
Note: the Properties dictionary can only serialize primitive types for
storage. Attempting to store other types (such as List can
fail silently).
Source: https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/application-class/
Either set it up so you are using the properties as a primitive storage, or go for another local storage mechanism such as Sqlite (a good guide here: https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/databases/)

NetSuite custom record search through suiteTalk using C#

We are having an issue with searching a custom record through SuiteTalk. Below is a sample of what we are calling. The issue we are having is in trying to set up the search using the internalId of the record. The issue here lies in in our initial development account the internal id of this custom record is 482 but when we deployed it through the our bundle the record was assigned with the internal Id of 314. It would stand to reason that this internal id is not static in a site per site install so we wondered what property to set up to reference the custom record. When we made the record we assigned its “scriptId’ to be 'customrecord_myCustomRecord' but through suitetalk we do not have a “scriptId”. What is the best way for us to allow for this code to work in all environments and not a specific one? And if so, could you give an example of how it might be used.
Code (C#) that we are attempting to make the call from. We are using the 2013.2 endpoints at this time.
private SearchResult NetSuite_getPackageContentsCustomRecord(string sParentRef)
{
List<object> PackageSearchResults = new List<object>();
CustomRecord custRec = new CustomRecord();
CustomRecordSearch customRecordSearch = new CustomRecordSearch();
SearchMultiSelectCustomField searchFilter1 = new SearchMultiSelectCustomField();
searchFilter1.internalId = "customrecord_myCustomRecord_sublist";
searchFilter1.#operator = SearchMultiSelectFieldOperator.anyOf;
searchFilter1.operatorSpecified = true;
ListOrRecordRef lRecordRef = new ListOrRecordRef();
lRecordRef.internalId = sParentRef;
searchFilter1.searchValue = new ListOrRecordRef[] { lRecordRef };
CustomRecordSearchBasic customRecordBasic = new CustomRecordSearchBasic();
customRecordBasic.recType = new RecordRef();
customRecordBasic.recType.internalId = "314"; // "482"; //THIS LINE IS GIVING US THE TROUBLE
//customRecordBasic.recType.name = "customrecord_myCustomRecord";
customRecordBasic.customFieldList = new SearchCustomField[] { searchFilter1 };
customRecordSearch.basic = customRecordBasic;
// Search for the customer entity
SearchResult results = _service.search(customRecordSearch);
return results;
}
I searched all over for a solution to avoid hardcoding internalId's. Even NetSuite support failed to give me a solution. Finally I stumbled upon a solution in NetSuite's knowledgebase, getCustomizationId.
This returns the internalId, scriptId and name for all customRecord's (or customRecordType's in NetSuite terms! Which is what made it hard to find.)
public string GetCustomizationId(string scriptId)
{
// Perform getCustomizationId on custom record type
CustomizationType ct = new CustomizationType();
ct.getCustomizationTypeSpecified = true;
ct.getCustomizationType = GetCustomizationType.customRecordType;
// Retrieve active custom record type IDs. The includeInactives param is set to false.
GetCustomizationIdResult getCustIdResult = _service.getCustomizationId(ct, false);
foreach (var customizationRef in getCustIdResult.customizationRefList)
{
if (customizationRef.scriptId == scriptId) return customizationRef.internalId;
}
return null;
}
you can make the internalid as an external property so that you can change it according to environment.
The internalId will be changed only when you install first time into an environment. when you deploy it into that environment, the internalid will not change with the future deployments unless you choose Add/Rename option during deployment.

How can I keep my variable all the time without global variables?

I have two GridViews. I've got method GetGeneralDiagnosis which returns a list of all diagnosis:
CODE DIAGNOSIS
F50 Eating disorders
F51 Nonorganic sleep disorders
and method GetSpecificDiagnosis which returns more specific list:
CODE DIAGNOSIS
F50.0 Anorexia nervosa
F50.1 Atypical anorexia nervosa
F51.0 Nonorganic insomnia
F51.1 Nonorganic hypersomnia
Now I've got method which bind SPECIFIC DIAGNOSIS to second GridView according to GENERAL DIAGNOSIS from first GridView.
protected void gvGeneralDiagnosis_SelectedIndexChanged(object sender, EventArgs e)
{
string generalDiagnosis = gvGeneralDiagnosis.DataKeys[gvGeneralDiagnosis.SelectedIndex].Values["ICD10Code"].ToString();
var ICD10 = Visit.GetSpecificDiagnosis(); // here I'm getting data from database
gvSpecificDiagnosis.DataSource = ICD10.Where(i => i.ICD10Code.Contains(generalDiagnosis)).Select(i => new { i.ICD10Name, i.ICD10Code });
gvSpecificDiagnosis.DataBind();
}
I don't want to connect to database each time selected index is changed.
How can i get my list var ICD10 = Visit.GetSpecificDiagnosis() only once? I heard that global variables are very bad idea, so how can I do that in another way?
You can use a private member variable. This one "lives" as long as the class containing it lives. Wrap it with a property to access it and automatically read it from the database, if necessary.
private TypeOfICD10 _icd10;
private TypeOfICD10 ICD10
{
get
{
if (_icd10 == null) { // Get from database.
_icd10 = Visit.GetSpecificDiagnosis();
}
return _icd10;
}
}
Now you can use it like this and it will be read from the db only at the first call
protected void gvGeneralDiagnosis_SelectedIndexChanged(object sender, EventArgs e)
{
string generalDiagnosis = gvGeneralDiagnosis.DataKeys[gvGeneralDiagnosis.SelectedIndex].Values["ICD10Name"].ToString();
gvSpecificDiagnosis.DataSource = ICD10
.Where(i => i.ICD10Code.Contains(generalDiagnosis))
.Select(i => new { i.ICD10Name, i.ICD10Code });
gvSpecificDiagnosis.DataBind();
}
You can have your Visit class cache the returned data.
When GetSpecificDiagnosis is called, it will check whether this data was already retrieved from the database, and return it if it was. If it wasn't, it'll retrieve it from the database and save it to its cache.
One thing you should pay attention to is whether this data is static (i.e. never changes throughout the application's lifetime) or is it dynamic. In the first case, you won't have to do any special handling, but if it's the latter, you'll have to invalidate the cache one the information in the database has changed.
I recommend you to have a look here to see how to get started with caching in ASP.NET.
I don't know much about the Visist class from your question but why not cache ICD10 this way you will be using the cached object and the Database call will made only if the Cache Key ICD10 has a value of null
Example :
if(Cache["ICD10"] == null)
{
var ICD10 = Visit.GetSpecificDiagnosis();
Cache["ICD10"] = ICD10;
}
else
{
var ICD10 = Cache["ICD10"];
}

Categories

Resources