I can't sort this weird issue out and I have tried anything and everything I can think of.
I got 5 pages, everyone of them passing variables with navigation this way:
Pass:
NavigationSerice.Navigate(new Uri("/myPage.xaml?key=" + myVariable, UriKind.Relative));
Retrieve:
If (NavigationContext.QueryString.ContainsKey(myKey))
{
String retrievedVariable = NavigationContext.QueryString["myKey"].toString();
}
I open a list on many pages and one of the pages automatically deletes an item from the list actualProject (actualProject is a variable for a string list). Then, when I go so far back that I reach a specific page - the app throws an exception. Why? I have no idea.
The code that deletes the item:
// Remove the active subject from the availible subjects
unlinkedSubjects.Remove(actualSubject);
unlinkedsubjectsListBox.ItemsSource = null;
unlinkedsubjectsListBox.ItemsSource = unlinkedSubjects;
Then the page that throws the exception's OnNavigatedTo event:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("key"))
{
actualProject = NavigationContext.QueryString["key"];
try
{
//Read subjectList from IsolatedStorage
subjectList = readSetting(actualProject) != null ? (List<String>)readSetting(actualProject) : new List<String>();
//Put the subjectList into the subjectListBox
subjectListBox.ItemsSource = subjectList;
//Set the subjectsPageTitle to the "actualProject" value, to display the name of the current open project at the top of the screen
subjectsPageTitle.Text = actualProject;
}
catch (Exception)
{
if (language.Equals("en."))
{
// Language is set to english
MessageBox.Show("Couldn't open the project, please try again or please report the error to Accelerated Code - details on the about page");
}
else if (language.Equals("no."))
{
// Language is set to norwegian
MessageBox.Show("Kunne ikke åpne prosjektet, vennligst prøv igjen eller rapporter problemet til Accelerated Code - du finner detaljer på om-siden");
}
}
}
}
Exception:
_exception {System.ArgumentException: Value does not fall within the expected range.} System.Exception {System.ArgumentException}
My theory:
The app kind of loads the currently opened and modified List. Is that possible? No idea.
So there are a number of ways to pass data between pages.
The way you have chosen is the least suggested.
You can use the PhoneApplicationService.Current dictionary but this is messy also if you have a ton of variables, doesn't persist after app shut down and could be simplified.
I wrote a free DLL that kept this exact scenario in mind called EZ_iso.
You can find it here
Basically what you would do to use it is this.
[DataContractAttribute]
public class YourPageVars{
[DataMember]
public Boolean Value1 = false;
[DataMember]
public String Value2 = "And so on";
[DataMember]
public List<String> MultipleValues;
}
Once you have your class setup you can pass it easily between pages
YourPageVars vars = new YourPageVars { /*Set all your values*/ };
//Now we save it
EZ_iso.IsolatedStorageAccess.SaveFile("PageVars",vars);
That's it! Now you can navigate and retrieve the file.
YourPageVars vars = (YourPageVars)EZ_iso.IsolatedStorageAccess.GetFile("PageVars",typeof(YorPageVars));
This is nice because you can use it for more than navigation. You can use it for anything that would require Isolated storage. This data is serialized to the device now so even if the app shuts down it will remain. You can of course always delete the file if you choose as well.
Please make sure to refer to the documentation for any exceptions you have. If you still need help feel free to hit me up on twitter #Anth0nyRussell or amr#AnthonyRussell.info
Related
I was hoping to get some insight on the error that are produced by the system. I am using a already built message system that I got some time ago and it works but sometimes on the forms I will get errors that I do not understand. For instance on a Create I have a try / catch block that produces a message if it has successfully Executed. I have tried to search for these errors in my project and it does not come up with anything. Even if it was in meta data a search should find it.
I use System.Text.StringBuilder sb = new System.Text.StringBuilder(); for the message and the code looks like this:
public ActionResult Create(Vendors model)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
try
{
if (ModelState.IsValid)
{
var userId = User.Identity.GetUserId();
//var getdata = ExtendedViewModels.VendorToEntity(model);
model.VendorId = Guid.NewGuid();
model.CreatedDate = System.DateTime.Now;
model.CreatedBy = User.Identity.Name;
model.Status = true;
db.Vendors.Add(model);
db.SaveChanges();
sb.Append("Submitted");
return Content(sb.ToString());
}
else
{
foreach (var key in this.ViewData.ModelState.Keys)
{
foreach (var err in this.ViewData.ModelState[key].Errors)
{
sb.Append(err.ErrorMessage + "<br/>");
}
}
}
}
catch (Exception ex)
{
sb.Append("Error :" + ex.Message);
}
return Content(sb.ToString());
}
When this returns or closes the Modal it produces a message or if there is an error it will produce that so you can fix it like a Required field. If everything is okay it will produce from this:
#Html.StarkAjaxFormSubmiter("frmVendors", "tbVendors", true, "Action Successfully Executed")
This is a green box that shows up as "Action Successfully Executed". If something is wrong a red box shows up and you get a message. In my case I am getting a red box that says Submitted Read Warnings Alerts This is how it is spelled. I doubt this is a error that comes from ASP.Net it looks more like a custom message, I dont know what it means and I cannot find it anywhere. Regardless, it does create the record in the db. The other error I have gotten shows Something is went wrong [object, object] Not only do I want to find out what these mean, I also want to clean them up and give a proper message that makes sense. Does anyone have any ideas as to how to correct this? Could they be encypted in the custom package that was written for this? That is why I cannot find them. I have also viewed the package and did not find anything for this.
This is from Meta data:
//
// Parameters:
// stark:
//
// FormId:
// Enter Here Form ID LIKE So you have to pass = frmCreate
//
// DataTableId:
// Which DataTable You have update after submit provide that ID
//
// IsCloseAfterSubmit:
// Do you want to opened popup close after submit , So pass=true or false any
//
// SuccessMessage:
// Give any Success message
public static MvcHtmlString StarkAjaxFormSubmiter(this HtmlHelper stark, string FormId, string DataTableId, bool IsCloseAfterSubmit, string SuccessMessage);
//
// Parameters:
// stark:
//
// FormId:
// Enter Here Form ID LIKE So you have to pass = frmCreate
//
// DataTableId:
// Which DataTable You have update after submit provide that ID
//
// IsCloseAfterSubmit:
// Do you want to opened popup close after submit , So pass=true or false any
//
// SuccessMessage:
// Give any Success message
//
// AfterSuccessCode:
// Add other JQuery code if you want
public static MvcHtmlString StarkAjaxFormSubmiter(this HtmlHelper stark, string FormId, string DataTableId, bool IsCloseAfterSubmit, string SuccessMessage, string AfterSuccessCode);
Thanks for our help
UPDATE:
I did some searching on the web and found a program called JetBrains dotPeek. I decompiled the dll and sure enough the messages are in there. So I should be able to change them and recompile it and add if I want, to it.
I was not able to edit the decompiled dll. So I decided to just create a class in the main project and copy the the code to that class. Changing what I needed. Where my trouble was, was with misspellings. The dll used Sumitted as the sb.Append("Sumitted") I changed that in the controller to be Submitted. So the dll did not find "Sumitted" in the action, and in the dll class there is an If statement that faults to error if not found - which was listed as Read Warnings Error. I changed that and fixed all the misspellings. I also got rid of the Something is went wrong and changed it to something more meaningful. I will continue to add to this to give more meaningful messages. It helps to know what the error is, instead of [object], [object]. I dont know if this will help others, maybe if they have downloaded the same code I have and have issues.
I'm working on a simple portfolio project. I would like to show images on a webpage that logged in users can edit. My problem is in the [HttpPost] Edit, more specifically this part:
if (ModelState.IsValid)
{
//updating current info
inDb = ModelFactory<ArtSCEn>.GetModel(db, artSCEn.ArtSCEnID);
inDb.LastModified = DateTime.Now;
inDb.TechUsed = artSCEn.TechUsed;
inDb.DateOfCreation = artSCEn.DateOfCreation;
inDb.Description = artSCEn.Description;
inDb.ArtSC.LastModified = DateTime.Now;
//validating img
if (Validator.ValidateImage(img))
{
inDb.ImageString = Image.JsonSerialzeImage(img);
}
else
{
//return to the UI becuase we NEED a valid pic
return View(artSCEn);
}
db.Entry(inDb).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
//[PROBLEMATIC PART STARTS HERE]
//updating the pic on the server
//getting the string info
string userArtImgFolder = Server.MapPath($"~/Content/Images/Artistic/{inDb.ArtSC.PersonID}");
string imgNameOnServer = Path.Combine(
userArtImgFolder,
$"{inDb.ArtSC.PersonID}_{inDb.ArtSC.ArtSCID}_{inDb.ArtSCEnID}{Path.GetExtension(img.FileName)}");
//deleting previous pic
System.IO.File.Delete(imgNameOnServer);
//creating a new pic
Image.ResizePropotionatelyAndSave(img, Path.Combine(
userArtImgFolder,
$"{inDb.ArtSC.PersonID}_{inDb.ArtSC.ArtSCID}_{inDb.ArtSCEnID}{Path.GetExtension(img.FileName)}"));
return RedirectToAction("Edit", "Art", new { id = inDb.ArtSCID });
}
When I get back the new picture and I want to delete the previous, System.IO.File.Delete() always triggers an exception that it cannot access the resource, because someone else is holding onto it. Any idea what that might be?
Maybe it's something simple, I'm new to ASP, but just can't figure it out.
UPDATE
Following on the suggestions in the comments section, I checked the processes with a tool called Process Monitor and it seems that indeed IIS is locking the resource:
This one appears 2 more times in the logs, by the way.
Judging by the fact that the operation is CreateFileMapping, I guess it has to do with either Server.MapPath() or Path.Combine(), however, the Server is an IDisposable (being derived from Controller), so can that be the one I should deal with?
Also, the resource I'm trying to delete is an image used on the website, which might be a problem, but that section of the website is not shown during this process.
I found the solution building on the comment of #Diablo.
The IIS was indeed holding on to the resource, but Server.MapPath() or any of that code had nothing to do with it: it was the Edit view my page returning the data to. With the help of this SO answer, it turns out I was careless with a BitMap that I used without a using statement in the view to get some image stats. I updated the helper function with the following code:
public static float GetImageWidthFromPath(string imgAbsolutPath, int offset)
{
float width = 0;
using (Bitmap b = new Bitmap(imgAbsolutPath))
{
width = b.Width - offset;
}
return width;
}
Now IIS does not hold on to the resource and I can delete the file.
I'm making an educational game (Windows 10 UWP, C# + XAML) and I need to store user information (in particular, their current score) and retrieve it when they start the app again. I've found a way to do this (see code below) but I have no idea if this is a normal solution to this problem. I'm currently creating a txt file and storing and retrieving data in/from it. Are there more common, or simpler ways to do this?
Here's what I'm currently doing:
Create the file:
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.CreateFileAsync("nameOfTextFile.txt", CreationCollisionOption.OpenIfExists); //other options are ReplaceExisting
Open the file:
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.GetFileAsync("nameOfTextFile.txt");
Write text to the file:
await FileIO.WriteTextAsync(sampleFile, "Put the added text here");
Read text from the file:
string someVariableName = await FileIO.ReadTextAsync(sampleFile);
-Thanks in advance for any help!!
While the file-based approach is valid, there are easier ways, at least for simple data: You can use roaming (or local) settings. Roaming settings are roamed between devices, as long as their size don't exceed 64K, and would carry the score from the user's desktop to the user's phone, for example. Local settings stay on the machine.
Settings are easy to use:
IPropertySet propertySet = ApplicationData.Current.RoamingSettings.Values;
// Get previous score (or 0 if none)
int score = (int)(propertySet["Score"] ?? 0);
// ...play game...
// Set updated score:
propertySet["Score"] = score;
The way I go about doing projects and settings like this is creating a propery setting in Visual Studio, then Setting and Getting the setting / Value.
You can access this by going to the application properties.
This allows access to read,write, and save information / onload restore information.
Some Informational Links:
https://msdn.microsoft.com/en-us/library/bb397755(v=vs.110).aspx
and (Suggested)
https://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
OK, so here goes an example of using a class to store your settings in.
There are many, many more ways you could do this. Too many to list.
Create a settings class:
public class YourSettingsClass
{
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserScore { get; set; }
}
Create an AppSettings helper
public AppSettings
{
private static YourSettingsClass _settings = new YourSettingsClass();
public static string UserFirstName
{
get { return _settings.UserFirstName; }
set { _settings.UserFirstName = value; }
}
public static string UserLastName
{
get { return _settings.UserLastName; }
set { _settings.UserLastName = value; }
}
public static string UserScore
{
get { return _settings.UserScore; }
set { _settings.UserScore = value; }
}
public static void SaveSettings()
{
// Now, use your "settingsfile.xml" (or whatever you're saving as)
// to write your settings to from your _settings static field object.
// I'll let you have a play as to how you want to do this...
}
public static void LoadSettings()
{
YourSettingsClass tempSettingsClass = new YourSettingsClass();
// Now, use your "settingsfile.xml" (or whatever you've saved it as)
// to load in your settings and assign to your tempSettingsClass variable.
// I'll let you have a play as to how you want to do this...
// Assign the settings from your loaded object.
_settings = tempSettingsClass;
}
}
Now, from any other class, you can call AppSettings.LoadSettings(). You could do this on App Startup, or on-demand.
When you've loaded the settings in, just reference AppSettings.UserFirstName or whatever property you want to either get the value or set the value.
When you're ready to, you can then save the settings back to the XML file on disk, through AppSettings.SaveSettings().
I've purposely omitted the code for loading and saving from the storage, and for se/deserializing class objects as I haven't got any UWP components on this PC and I've done this all from memory so I don't want to put anything in to throw you off.
Plus it's a little more learning (even trial/error) for you to do.
Lastly
In the getters for your AppSettings static properties you could also do a null or string.IsNullOrWhiteSpace check for the _settings' property in question, and call the LoadSettings() method if so.
This would save you having to manually call it in-code elsewhere.
Useful links
XmlSerializer and how to use the Serialize method
All about what you can do with the FileIO.WriteTextAsync
Not an article, but a similar question: UWP C# Read & Write XML File
I really hope this helps, somewhat.
Good luck!
I'm trying to save two Lists of objects in the phone ApplicationSettings, but I'm stuck at a strange issue (But it's probably me making a silly mistake somewhere).
If I only save one of the lists, it works as supposed - It'll save it, and reload it when app is launched next time.
But if I try to save 2 lists, none of them seem to be saved correctly. No errors or anything, just "blankness".
See code below.
//My save method
public void Gem()
{
var settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains(INDTASTNINGER_LIST))
{
settings[INDTASTNINGER_LIST] = _indtastningsListe;
}
else
settings.Add(INDTASTNINGER_LIST, _indtastningsListe);
if (settings.Contains(INDTASTNINGER_LIST2))
{
settings[INDTASTNINGER_LIST2] = _indtastningsListe2;
}
else
settings.Add(INDTASTNINGER_LIST2, _indtastningsListe2);
settings.Save();
}
//Constructor supposed to load settings
public Indtastninger()
{
var settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains(INDTASTNINGER_LIST))
{
_indtastningsListe = null;
_indtastningsListe = (List<Indtastning>)settings[INDTASTNINGER_LIST];
}
if (settings.Contains(INDTASTNINGER_LIST2))
{
_indtastningsListe2 = null;
_indtastningsListe2 = (List<Indtastning>)settings[INDTASTNINGER_LIST2];
}
}
What am I doing wrong?
If I comment out the part with "list2" stuff, the first one will be saved/retrieved perfectly.
I have faced the same issue some time ago, the problem is that you only can save on the IsolatedStorage objects that are XML serializables.
if you save other object, it will work even with the debugger but when the app is restarted, all the saved data is lost.
I am writing an app (something like Notepad) in C#. I'm using Properties.Settings class to save user preferences. It was working fine until suddenly when it started showing this exception message anytime I try to run it.
Configuration system failed to initialize
I noticed that the error originated from this part of the code:
private void TextPad_Load(object sender, EventArgs e)
{
rtbText.WordWrap = Properties.Settings.Default.WordWrap;
rtbText.Font = Properties.Settings.Default.DefFont;
rtbText.ForeColor = Properties.Settings.Default.ForeColor;
rtbText.BackColor = Properties.Settings.Default.BackColor;
if (Properties.Settings.Default.ShowLast)
{
OpenLocalFile(Properties.Settings.Default.LastFile);
}
// There are other lines which are not relevant to this question
}
I moved the supposedly lines to the form constructor immediately after InitializeComponent(); but I still got the same error.
Actually the compiler is telling the error originates from this in Settings.Designer.cs:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool WordWrap {
get {
return ((bool)(this["WordWrap"]));
}
set {
this["WordWrap"] = value;
}
If I remove rtbText.WordWrap = Properties.Settings.Default.WordWrap; from TextPad_Load, it shows
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Consolas, 9.75pt")]
public global::System.Drawing.Font DefFont {
get {
return ((global::System.Drawing.Font)(this["DefFont"]));
}
set {
this["DefFont"] = value;
}
The only solution now is either to remove those lines from TextPad_Load (which makes the idea loading user preferences useless) or starting a new project (which I have done, anyway). Can someone please explain what the exception message means and maybe I can get a solution (in case I run into it again)? Microsoft VS Help is not giving me anything tangible.
Thanks
It might help to throw away your existing .config files.
After changes in the Properties.Settings the old file might not be valid any more (changed names, or removed items no longer recognized).
Note that user scoped settings are stored in (drive):\Users(usr)\AppData\Local\Microsoft...something