Making a Settings.txt File - How to load settings the right way? - wpf

I have an app I'm working on and it should save and load settings through an XML file (named Settings.txt)
Now, here's the code I use:
public class Settings
{
public bool Selected_64Bit { get; set; }
public bool Supported_64Bit { get; set; }
public bool FirstTime { get; set; }
}
static void SaveSettings(Settings settings)
{
var serializer = new XmlSerializer(typeof(Settings));
using (var stream = File.OpenWrite("settings.txt"))
{
serializer.Serialize(stream, settings);
}
}
static Settings LoadSettings()
{
if (!File.Exists("settings.txt"))
return new Settings();
var serializer = new XmlSerializer(typeof(Settings));
using (var stream = File.OpenRead("settings.txt"))
{
return (Settings)serializer.Deserialize(stream);
}
}
Now, I need to load the settings into a new Settings().
I found out that doing:
Settings [VAR] = new Settings()
will make a new Settings() with all false, but I want to LOAD the saved settings..
I'm confused and can't explain this to myself...
The final product should:
Check if settings.txt exists
If it does - LOAD SETTINGS into a new Settings called Setting (in my case).
If it doesn't - Make new settings and then save them.
I hope someone understood and can help me.
BTW - I'm not so good in C#, and I don't get the get\set thingy at all, as of return and other methods like that.. I know the basics and I'll be happy if I won't need more complicated techniques.
And if I must use more complicated techniques - please explain them deeply because I DO NOT KNOW.

As you have it set up, you'd need to do:
Settings mySettings = Settings.LoadSettings();
This will run your static LoadSettings method and return a Settings object.

As Matt already wrote
Settings mySettings = Settings.LoadSettings();
will do the job.
If you have a application you could use its settings as well. You get that settings by Properties.Settings.Default and in your project settings you can define some properties.

Related

Calling data from one class to another class - framework for JUnit

Please forgive me as I am still very new to the world of test automation. I have started out by using Selenium WebDriver with JUnit4, predominately on windows OS, although I have modified my scripts and ran them on Mac.
I want to be able to create a set of classes containing set data such as usernames, passwords, default url . Perhaps even calling them from an excel file, but for now Im happy to store the data in classes and then pass that data into other test classes. Im guessing this would be a framework of some sort.
Currently I am writing classes that all begin with something like:
public class ExampleSQATest{
public static Chromedriver chrome;
#BeforeClass
public static void launchBrowser(){
System.setProperty("webdriver.chrome.driver", "chromedriver/chromedriver.exe");
chrome = new ChromeDrievr();
}
#Test
public void aLogin(){
chrome.manage().window().maximize();
chrome.navigate().to("http://mydummywebsite.com");
new WebDriverWait(chrome, 10).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector
("input#UserName")));
WebElement username = chrome.findElementByCssSelector("input#UserName");
username.sendKeys("username");
WebElement password = chrome.findElementByCssSelector("input#Password");
password.sendKeys("password");
WebElement submit = chrome.findElementByCssSelector("input[type='submit']");
submit.click();
}
}
I will then proceed to write further test methods which requires entering data, but I'd like to be able to call this data from somewhere else that is already predefined.
Can anyone provide any suitable suggestions to investigate so I can learn. Something that is a guide or tutorial. Nothing too advanced, just something that helps me get started by advising me how to set a class of methods to be called by other classes and how it all links together as a framework.
Many thanks in advance.
One way to do this
public abstract class TestBase
{
private readonly INavigationManager navMgr;
private readonly IWindowNavigator windowNav;
private readonly ILoginManager loginMgr;
// All your stuff that is common for all the tests
protected TestBase()
{
this.navMgr = WebDriverManager.Get<INavigationManager>();
this.windowNav = WebDriverManager.Get<IWindowNavigator>();
this.loginMgr = WebDriverManager.Get<ILoginManager>();
}}
[TestFixture]
internal class QueriesTest : TestBase
{
private QueryTests queryTests;
[SetUp]
public void Setup()
{
this.queryTests = WebDriverManager.Get<QueryTests>();
// all the stuff you run specific before tests in this test class.
}
}
Assuming you have created test classes in webdriver-junit4, Use following two classes to call your test classes (Note-Import junit annotations)
1)Create test suite class as -
#RunWith(Suite.class)
#Suite.SuiteClasses({
YourTestClass1.class,
YourTestClass2.class,[you can add more tests you have created...]
})
public class TestSuiteJU {
}
2)Create class to call suite created above as-
public class TestExecution {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestSuiteJU .class);
}
}

DataContract doesn't work after publish into web site

I tried to solve by myself, but... Looks like I need help from people.
I have Business Silverlight application with WCF RIA and EntityFramework. Access to Database I get via LinqToEntites.
Common loading data from database I making by this:
return DbContext.Customers
This code returns full Customers table from DataBase. But sometimes I do not need to show all data. Easy way is use linq filters in client side by next code:
public LoadInfo()
{
...
var LO1 = PublicDomainContext.Load(PublicDomainContext.GetCustomersQuery());
LO1.Completed += LO1Completed;
...
}
private void LO1Completed(object sender, EventArgs eventArgs)
{
...
DatatViewGrid.ItemsSource = null;
DatatViewGrid.ItemsSource = loadOperation.Entities.Where(c=>c ...filtering...);
//or PublicDomainContext.Customers.Where(c=>c ...filtering...)
...
}
However this way has very and very important flaw: all data passing from server to client side via DomainService may be viewed by applications like Fiddler. So I need to come up with another way.
Task: filter recieving data in server side and return this data.
Way #1: LinqToEntites has a beautiful projection method:
//MSDN Example
var query =
contacts.SelectMany(
contact => orders.Where(order =>
(contact.ContactID == order.Contact.ContactID)
&& order.TotalDue < totalDue)
.Select(order => new
{
ContactID = contact.ContactID,
LastName = contact.LastName,
FirstName = contact.FirstName,
OrderID = order.SalesOrderID,
Total = order.TotalDue
}));
But, unfortunately, DomainServices cannot return undefined types, so this way won't work.
Way #2: I found next solution - make separate DTO classes (DataTransferObject). I just read some samples and made on the server side next class:
[DataContract]
public partial class CustomerDTO
{
[DataMember]
public int ISN { get; set; }
[DataMember]
public string FIO { get; set; }
[DataMember]
public string Listeners { get; set; }
}
And based this class I made a row of methods which return filtered data:
[OperationContract]
public List<CustomerDTO> Customers_Common()
{
return DbContext.Customers....Select(c => new CustomerDTO { ISN = c.ISN, FIO = c.FIO, Listeners = c.Listeners }).ToList();
}
And this works fine, all good...
But, there is strange problem: running application locally does not affect any troubles, but after publishing project on the Web Site, DomainService returns per each method HTTP 500 Error ("Not Found" exception). Of course, I cannot even LogIn into my application. DomainService is dead. If I delete last class and new methods from application and republish - all works fine, but without speacial filtering...
The Question: what I do wrong, why Service is dying with new classes, or tell me another way to solve my trouble. Please.
U P D A T E :
Hey, finally I solved this!
There is an answer: Dynamic query with WCF RIA Services
Your best shot is to find out what is causing the error. For that, override the OnError method on the DomainService like this:
protected override void OnError(DomainServiceErrorInfo errorInfo)
{
/* Log the error info to a file. Don't forget inner exceptions.
*/
base.OnError(errorInfo);
}
This is useful, because only two exceptions will be passed to the client, so if there are a lot of nested inner exceptions, you should still be able to see what actually causes the error.
In addition, you can inspect the error by attaching the debugger to the browser instance you are opening the site with. In VS2010 this is done by doing [Debug] -> [Attach to Process] in the menu-bar.

Parse JSON data within SQL Server Integration Services Package?

I'm trying to set up an SSIS job that will pull a JSON-encoded mailing list from MailChimp, compare it to a list of customers in our CRM database (SQL Server), and upload via JSON any new customers not already there. I can't seem to find anything on serializing/deserializing JSON within SSIS, other than writing a script task, and it seems that I can't import the .Net serialization libraries into a script. Any suggestions? Thanks in advance!
Couple things to address here:
First, your problem with adding new libraries in the scripting component. I assume you're using VS 2008 to do your SSIS development and want to use the .net 3.5 library to do this. You go to project, add reference and you don't see any of the dll's you need. This may be in part that you're using windows 7 and the compact 3.5 framework. .net 3.5.1 comes with Windows 7, you just have to enable it. Go to control panel, programs and features. In that screen you will see Turn Windows features on or off, click on that. In that window check Microsoft .NET Framework 3.5.1, this way take a few minutes to run. Once it finishes look for a directory similar to these C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v3.5\Profile\Client and C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5. Between these 2 directories, you will find any dll you will need for serialization/deserializtion of JSON. These can be added to your project by going to Project-->Add Reference-->Browse Tab, then navigate to the v3.5 directory and select the dlls you need(System.Web.Extensions.dll(v3.5.30729.5446)is used in this example).
To get JSON from a web service, deserialize it, and send the data to your CRM database, you will have to use a script component as a source in your data flow and add columns to your output buffer that will be used to hold the data coming from the JSON feed(on the Input and Output screen). In the code, you will need to override the CreateNewOutputRows method. Here is an example of how to do this:
Say Your JSON looked like this...[{"CN":"ALL","IN":"Test1","CO":0,"CA":0,"AB":0},{"CN":"ALL","IN":"Test2","CO":1,"CA":1,"AB":0}]
I would fist define a class to mirror this JSON feed attributes (and the columns you defined on the inputs and outputs screen) that will eventually hold these values once you deserialize...as such:
class WorkGroupMetric
{
public string CN { get; set; }
public string IN { get; set; }
public int CO { get; set; }
public int CA { get; set; }
public int AB { get; set; }
}
Now you need to call your web service and get the JSON feed using an HttpWebRequest and a Stream:
string wUrl = "YOUR WEB SERVICE URI";
string jsonString;
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(wUrl);
HttpWebResponse httpWResp = (HttpWebResponse)httpWReq.GetResponse();
Stream responseStream = httpWResp.GetResponseStream();
using (StreamReader reader = new StreamReader(responseStream))
{
jsonString = reader.ReadToEnd();
reader.Close();
}
Now we deserialize our json into an array of WorkGroupMetric
JavaScriptSerializer sr = new JavaScriptSerializer();
WorkGroupMetric[] jsonResponse = sr.Deserialize<WorkGroupMetric[]>(jsonString);
After deserializing, we can now output the rows to the output buffer:
foreach (var metric in jsonResponse)
{
Output0Buffer.AddRow();
Output0Buffer.CN = metric.CN;
Output0Buffer.IN = metric.IN;
Output0Buffer.CO = metric.CO;
Output0Buffer.CA = metric.CA;
Output0Buffer.AB = metric.AB;
}
Here is what all the code put together would look like(I have a step by step example here):
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Net;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
using System.Web.Script.Serialization;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
string wUrl = "YOUR WEB SERVICE URI";
try
{
WorkGroupMetric[] outPutMetrics = getWebServiceResult(wUrl);
foreach (var metric in outPutMetrics)
{
Output0Buffer.AddRow();
Output0Buffer.CN = metric.CN;
Output0Buffer.IN = metric.IN;
Output0Buffer.CO = metric.CO;
Output0Buffer.CA = metric.CA;
Output0Buffer.AB = metric.AB;
}
}
catch (Exception e)
{
failComponent(e.ToString());
}
}
private WorkGroupMetric[] getWebServiceResult(string wUrl)
{
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(wUrl);
HttpWebResponse httpWResp = (HttpWebResponse)httpWReq.GetResponse();
WorkGroupMetric[] jsonResponse = null;
try
{
if (httpWResp.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = httpWResp.GetResponseStream();
string jsonString;
using (StreamReader reader = new StreamReader(responseStream))
{
jsonString = reader.ReadToEnd();
reader.Close();
}
JavaScriptSerializer sr = new JavaScriptSerializer();
jsonResponse = sr.Deserialize<WorkGroupMetric[]>(jsonString);
}
else
{
failComponent(httpWResp.StatusCode.ToString());
}
}
catch (Exception e)
{
failComponent(e.ToString());
}
return jsonResponse;
}
private void failComponent(string errorMsg)
{
bool fail = false;
IDTSComponentMetaData100 compMetadata = this.ComponentMetaData;
compMetadata.FireError(1, "Error Getting Data From Webservice!", errorMsg, "", 0, out fail);
}
}
class WorkGroupMetric
{
public string CN { get; set; }
public string IN { get; set; }
public int CO { get; set; }
public int CA { get; set; }
public int AB { get; set; }
}
This can now be used as an input for a data destination (your CRM database). Once there you can use SQL to compare the data and find mismatches, send the data to another script component to serialize, and send any updates you need back to the web service.
OR
You can do everything in the script component and not output data to the output buffer. In this situation you would still need to deserialze the JSON, but put the data into some sort of collection. Then use the entity framework and LINQ to query your database and the collection. Determine what doesn't match, serialize it, and send that to the web service in the same script component.

Access to file to files a file in tomcat's conf folder

I would like to know if it's possible to access a file putted on the conf folder of tomcat.
Typically i will put configuration for multiple webapp , outside of the wars, in this file.
I want to use the classpath to be independent from the file system.
I used the lib folder in the past. It work great.
But it's a bit of a none sense using the lib folder to put conf file.
Can someone help me on this one?
I have seen lots of bad ways people do configuration in webapps that either makes it not really config (you have to do redeploy/release when you change config) or you have very little flexibility.
How I approach the problem is to use Spring for property placeholder but often times you need to bootstrap Spring or whatever you MVC stack before it loads with a property that says where to load config. I use a listener for that:
package com.evocatus.util;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SimpleContextListenerConfig /*extend ResourceBundle */ implements ServletContextListener{
private ServletContext servletContext;
#Override
public void contextInitialized(ServletContextEvent sce) {
servletContext = sce.getServletContext();
servletContext.setAttribute(getClass().getCanonicalName(), this);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
public static String getProperty(ServletContext sc, String propName, String defaultValue) {
SimpleContextListenerConfig config = getConfig(sc);
return config.getProperty(propName, defaultValue);
}
public static SimpleContextListenerConfig getConfig(ServletContext sc) {
SimpleContextListenerConfig config =
(SimpleContextListenerConfig) sc.getAttribute(SimpleContextListenerConfig.class.getCanonicalName());
return config;
}
public String getProperty(String propName, String defaultValue)
{
/*
* TODO cache properties
*/
String property = null;
if (property == null)
property = servletContext.getInitParameter(propName);
if (property == null)
System.getProperty(propName, null);
//TODO Get From resource bundle
if (property == null)
property = defaultValue;
return property;
}
}
https://gist.github.com/1083089
The properties will be pulled first from the servlet context, then system properties thus allowing you to override for certain webapps.
You can change the config for certian webapp either by changing web.xml (not recommended) or by creating a context.xml
You can use the static methods to get the config:
public static SimpleContextListenerConfig getConfig(ServletContext sc);

How do I cache images on the client for a WPF application?

We are developing a WPF desktop application that is displaying images that are currently being fetched over HTTP.
The images are already optimised for quality/size but there is an obvious wait each time that the image is fetched.
Is there a way to cache images on the client so that they aren't downloaded each time?
I know this question is very old, but I had to use caching recently in a WPF application and found that there is a much better option in .Net 3.5 with BitmapImage by setting UriCachePolicy, that will use system-level caching:
<Image.Source>
<BitmapImage UriCachePolicy="Revalidate"
UriSource="https://farm3.staticflickr.com/2345/2077570455_03891081db.jpg"/>
</Image.Source>
You can even set the value in the app.config to make all your app use a default value for caching:
<system.net>
<requestCaching defaultPolicyLevel="CacheIfAvailable"/>
</system.net>
You will find an explanation of the RequestCacheLevel values here: http://msdn.microsoft.com/en-us/library/system.net.cache.requestcachelevel(v=vs.110).aspx
This functionality understands HTTP/1.1 headers, so if you set Revalidate it uses If-Modified-Since header to avoid downloading it each time, but still checking if the image has been changed so you always have the correct one.
For people coming here via Google, I have packaged the original implementation that Simon Hartcher posted, refactored by Jeroen van Langen (along with the tweaks from Ivan Leonenko to make it bindable), into an Open Source NuGet package.
Please find the details here - http://floydpink.github.io/CachedImage/
i've read your blog, and that brought me to this (i think much easier) concept setup:
As you will noticed, i reused some of your code you shared, so i'll share mine back.
Create a new custom control called CachedImage.
public class CachedImage : Image
{
private string _imageUrl;
static CachedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CachedImage), new FrameworkPropertyMetadata(typeof(CachedImage)));
}
public string ImageUrl
{
get
{
return _imageUrl;
}
set
{
if (value != _imageUrl)
{
Source = new BitmapImage(new Uri(FileCache.FromUrl(value)));
_imageUrl = value;
}
}
}
}
Next i've made a FileCache class (so i have control on all caching not only images)
public class FileCache
{
public static string AppCacheDirectory { get; set; }
static FileCache()
{
// default cache directory, can be changed in de app.xaml.
AppCacheDirectory = String.Format("{0}/Cache/", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
}
public static string FromUrl(string url)
{
//Check to see if the directory in AppData has been created
if (!Directory.Exists(AppCacheDirectory))
{
//Create it
Directory.CreateDirectory(AppCacheDirectory);
}
//Cast the string into a Uri so we can access the image name without regex
var uri = new Uri(url);
var localFile = String.Format("{0}{1}", AppCacheDirectory, uri.Segments[uri.Segments.Length - 1]);
if (!File.Exists(localFile))
{
HttpHelper.GetAndSaveToFile(url, localFile);
}
//The full path of the image on the local computer
return localFile;
}
}
Also for downloading content I made a helper class:
public class HttpHelper
{
public static byte[] Get(string url)
{
WebRequest request = HttpWebRequest.Create(url);
WebResponse response = request.GetResponse();
return response.ReadToEnd();
}
public static void GetAndSaveToFile(string url, string filename)
{
using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
byte[] data = Get(url);
stream.Write(data, 0, data.Length);
}
}
}
The HttpHelper uses an extension on the WebResponse class for reading the result to an array
public static class WebResponse_extension
{
public static byte[] ReadToEnd(this WebResponse webresponse)
{
Stream responseStream = webresponse.GetResponseStream();
using (MemoryStream memoryStream = new MemoryStream((int)webresponse.ContentLength))
{
responseStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}
Now you got it complete, lets use it in xaml
<Grid>
<local:CachedImage ImageUrl="http://host/image.png" />
</Grid>
That's all, it's reusable and robust.
The only disadvance is, that the image is never downloaded again until you cleanup the cache directory.
The first time the image is downloaded from the web and saved in the cache directory.
Eventually the image is loaded from the cache and assign to the source of the parent class (Image).
Kind regards,
Jeroen van Langen.
I have solved this by creating a Binding Converter using the IValueConverter interface. Given that I tried to find a solid solution for this for at least a week, I figured I should share my solution for those with this problem in the future.
Here is my blog post: Image Caching for a WPF Desktop Application
If you're just trying to cache within the same run, then a local dictionary could function as a runtime cache.
If you're trying to cache between application runs, it gets trickier.
If this is a desktop application, just save the cached images locally in the user's application data folder.
If it's an XBAP application (WPF in Browser), you'll only be able to setup a local cache in the user's Isolated Storage, due to security.
Based on this I made custom control which:
can download images asynchronously and get them from cache if image
is thread safe
was downloaded has dependency property to which you can bind to
update images, providing new names in initial feed (don’t forget to maintain cache clean operation, e.g. you can parse your feed
and asynchronously delete images with no links in feed)
I made a blog post:, and here's the code:
public class CachedImage : Image
{
static CachedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CachedImage), new FrameworkPropertyMetadata(typeof(CachedImage)));
}
public readonly static DependencyProperty ImageUrlProperty = DependencyProperty.Register("ImageUrl", typeof(string), typeof(CachedImage), new PropertyMetadata("", ImageUrlPropertyChanged));
public string ImageUrl
{
get
{
return (string)GetValue(ImageUrlProperty);
}
set
{
SetValue(ImageUrlProperty, value);
}
}
private static readonly object SafeCopy = new object();
private static void ImageUrlPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var url = (String)e.NewValue;
if (String.IsNullOrEmpty(url))
return;
var uri = new Uri(url);
var localFile = String.Format(Path.Combine(Globals.CacheFolder, uri.Segments[uri.Segments.Length - 1]));
var tempFile = String.Format(Path.Combine(Globals.CacheFolder, Guid.NewGuid().ToString()));
if (File.Exists(localFile))
{
SetSource((CachedImage)obj, localFile);
}
else
{
var webClient = new WebClient();
webClient.DownloadFileCompleted += (sender, args) =>
{
if (args.Error != null)
{
File.Delete(tempFile);
return;
}
if (File.Exists(localFile))
return;
lock (SafeCopy)
{
File.Move(tempFile, localFile);
}
SetSource((CachedImage)obj, localFile);
};
webClient.DownloadFileAsync(uri, tempFile);
}
}
private static void SetSource(Image inst, String path)
{
inst.Source = new BitmapImage(new Uri(path));
}
}
Now you can bind to it:
<Cache:CachedImage ImageUrl="{Binding Icon}"/>
Just a update from Jeroen van Langen reply,
You can save a bunch of line
remove HttpHelper class and the WebResponse_extension
replace
HttpHelper.GetAndSaveToFile(url, localFile);
by
WebClient webClient = new WebClient();
webClient.DownloadFile(url, localFile);
This cachedImage works great, but..
Any advice on how I could use the same cached image type capability for ImageSource for an ImageBrush?
<Rectangle
Width="32"
Height="32"
Margin="2,1"
RadiusX="16"
RadiusY="16"
RenderOptions.BitmapScalingMode="HighQuality">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding Image}" />
</Rectangle.Fill>
</Rectangle>
Note there may be a better way to do rounded images (for say profile images)

Resources