String property behaves really weird - c#

I have a settings class like this:
public class Settings
{
string resourcePath;
public string ResourcePath {
get {
return resourcePath + "/";
}
set {
resourcePath = value;
}
}
string texturePath;
public string TexturePath {
get {
string a = resourcePath + "/"; // This is just some debug stuff I did trying to find out wtf is going on
string b = texturePath + "/";
return a + b; // Breakpointing here shows that it is "Content/Textures/"
}
set {
texturePath = value;
}
}
public Settings ()
{
resourcePath = "Content";
texturePath = "Textures";
}
public static Settings CurrentSettings = new Settings();
}
Then I try to get the TexturePath from it, like this:
string path = Settings.CurrentSettings.TexturePath + file;
The string returned by the property is "Content//Content/Textures//"
What am I missing here? Why does it do that? With my knowledge it should return Content/Textures/

Use Path.Combine to work with path.
string path = Path.Combine(Settings.CurrentSettings.TexturePath,file);
and no need to add "/" to your properties.
public string ResourcePath {
get {
return resourcePath;
}
set {
resourcePath = value;
}
}

You might not be balancing the / between the getter and the setter. And you probably are getting some property and then setting another with it - resulting in too many /'s.

You haven't shown the code that produces the results you reported but the following code is highly suspect:
string resourcePath;
public string ResourcePath {
get {
return resourcePath + "/";
}
set {
resourcePath = value;
}
}
It always appends a forward slash on the getter but never removes it in the setter. So the following code:
x.ResourcePath = "abc";
x.ResourcePath = x.ResourcePath + "/def";
x.ResourcePath = x.ResourcePath + "/ghi";
Would set ResourcePath to "abc//def//ghi".
I suspect you are running into something like that.

Related

Injecting theme name into front end Best approach

At the min I am replacing _content in the source elements of my cshtml razor to inject the theme name my users are selecting in the admin this works.
But It requires me to place a tag helper on every element this happens.
At Present I am doing
[HtmlTargetElement(Attributes = AppendVersionAttributeName)]
public class AppendVersionTagHelper : TagHelper
{
private const string AppendVersionAttributeName = "cella-append-version";
private readonly IConfiguration _config;
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.RemoveAll(AppendVersionAttributeName);
if (!AppendVersion)
{
if (output.Attributes.ContainsName("href"))
{
var href = output.Attributes["href"].Value.ToString();
output.Attributes.SetAttribute("href", AppendVersionToUrl(href));
}
}
if (!AppendVersion)
{
if (output.Attributes.ContainsName("src"))
{
var src = output.Attributes["src"].Value.ToString();
output.Attributes.SetAttribute("src", AppendVersionToUrl(src));
}
}
if (output.Attributes.ContainsName("href"))
{
var href = output.Attributes["href"].Value.ToString();
output.Attributes.SetAttribute("href", AppendThemeNameToUrl(href));
}
if (output.Attributes.ContainsName("src"))
{
var src = output.Attributes["src"].Value.ToString();
var replace = AppendThemeNameToUrl(src);
output.Attributes.SetAttribute("src", replace);
}
if (output.Attributes.ContainsName("xlink:href"))
{
var src = output.Attributes["xlink:href"].Value.ToString();
var replace = AppDomainNameToImage(src);
output.Attributes.SetAttribute("xlink:href", replace);
}
private string AppDomainNameToImage(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
return string.Empty;
}
var theme = Constants.DomainName + #"/" + _config[Constants.ThemFolderNameConfigKey] + #"/" + _config["Theme"];
url = url.Replace("_DomainName", theme);
return url;
}
private string AppendThemeNameToUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
return string.Empty;
}
var theme = _config[Constants.ThemFolderNameConfigKey] + #"/"+ _config["Theme"];
url = url.Replace("_content", theme);
return url;
}
private string AppendVersionToUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
return string.Empty;
}
var version = _config["Global.AssetVersion"];
return url.Contains("?") ? $"{url}&v={version}" : $"{url}?v={version}";
}
}
The function above called
private string AppendThemeNameToUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
return string.Empty;
}
var theme = _config[Constants.ThemFolderNameConfigKey] + #"/"+ _config["Theme"];
url = url.Replace("_content", theme);
return url;
}
}
Then I call the tag helper like so
<link rel="stylesheet" cella-append-version="false" href="~/_content/vendor/bootstrap/css/bootstrap.min.css">
My only concern is this is making an impact on how fast the razor engine returns from the tag helper to present to the user is there a neater way to inject the theme name dynamically to the front end

How to Ignore class property from Json Serialization

I am creating a webservice using asp.net 4.0.
I have created a asmx file and creating a User.cs Class. It has 8 Properties.
I have return a service with json format.
If the userlogin is true i need to return all the properties of user.cs, if it's fail i need to return only 2 property.
How to achieve it.
User login is true. It will return all
{"message":"valid user","BranchId":1,"BranchName":"My branch Name","Id":1,"Name":"admin","Password":"admin","RoleId":1,"Status":1}
User login is failed i need to retun only message and Status. but it will return all like as foloows
{"message":"username or password is invalid","BranchId":0,"BranchName":null,"Id":0,"Name":null,"Password":null,"RoleId":0,"Status":0}
I have google it and get the following Link. How to use it based on my login status condition.
If i have used [ScriptIgnore] in my property it will ignore property both case. I need to ignore property when login failed.
My properties like this
// Properties
public int BranchId
{
get { return _BranchId; }
set { if (_BranchId != value) { _BranchId = value; } }
}
public string BranchName
{
get { return _BranchName; }
set { _BranchName = value; }
}
private String _message;
public String message
{
get { return _message; }
set { _message = value; }
}
My webservice
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void appLogin(String userName, String passWord)
{
Admin_AppUserBLL objusr = Admin_AppUserBLL.GetAdmin_AppUserBLL(userName);
string strResponse = "";
if (objusr != null)
{
if (objusr.Password == passWord)
{
objusr.message = "valid username";
strResponse = new JavaScriptSerializer().Serialize(objusr);
}
}
else
{
objusr = new Admin_AppUserBLL();
objusr.message = "username or password is invalid";
strResponse = new JavaScriptSerializer().Serialize(objusr);
}
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-length", strResponse.Length.ToString());
Context.Response.Flush();
Context.Response.Write(strResponse);
}
Add following attribute on your property and also make it nullable by using "?"
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "BranchId")]
public int? BranchId{ get; set; }
It will ignore if value will be null and also json does not contain these peoperties.
Add reference in Newtonsoft
using Newtonsoft.Json;
while serialize the object
string strResponse = JsonConvert.SerializeObject(objusr, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
it will avoid null value property

Best way for a switch statement for multiple if-else

I am trying to convert the lot of 'if else' to switch stements
Need pointer for a optimal switch cases, some code structure as below.
Code:
Public void ImageTest(String format, string path)
{
//Other Code
//if-Else part
try
{
if (strImageFormat.Equals("BMP"))
{
if (Convert.ToString(dataRow["IsEmployee"]).ToUpper() == "TRUE")
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".BMP");
}
else
{
ImagePath = string.Format("{0}{1}", fileNamelabel, ".BMP");
}
}
else if (strImageFormat.Equals("GIF"))
{
if (Convert.ToString(dataRow["IsEmployee"]).ToUpper() == "TRUE")
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".GIF");
}
else
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".GIF");
}
}
else if (strImageFormat.Equals("JPEG"))
{
if (Convert.ToString(dataRow["IsEmployee"]).ToUpper() == "TRUE")
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".JPEG");
}
else
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".JPEG");
}
}
else if (strImageFormat.Equals("PDF"))
{
if (Convert.ToString(dataRow["IsEmployee"]).ToUpper() == "TRUE")
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".PDF");
}
else
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".PDF");
}
}
}
catch(Exception ex)
{
}
}
I would rather not use too many switch statements and store the value in a bool then use conditional operator inside a case:
bool _condition = Convert.ToString(dataRow["IsEmployee"]);
switch(strImageFormat)
{
case "JPG":
ImagePath = _condition ? string.Format("{0}{1}", fileNameUpper, ".JPEG") : ImagePath = string.Format("{0}{1}", fileNamelabel, ".JPEG") ;
break;
case "GIF":
ImagePath = _condition ? string.Format("{0}{1}", fileNameUpper, ".GIF") : ImagePath = string.Format("{0}{1}", fileNamelabel, ".GIF") ;
break;
.
.
.
.
.
.
default:
// DO SOMETHING
}
It looks that the code
if (Convert.ToString(dataRow["IsEmployee"]).ToUpper() == "TRUE")
{
ImagePath = string.Format("{0}{1}", fileNameUpper, ".GIF");
}
else
{
// fileNamelabel expected, not fileNameUpper
ImagePath = string.Format("{0}{1}", fileNameUpper, ".GIF");
}
is either redundant or just copy-pasted. Providing that it's copy-pasted:
if (Convert.ToString(dataRow["IsEmployee"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
ImagePath = string.Format("{0}.{1}", fileNameUpper, strImageFormat);
else
ImagePath = string.Format("{0}.{1}", fileNamelabel, strImageFormat);
Note dot in the changed format: {0}.{1}.
I'd use a factory pattern for that in C#. That makes your code much more flexible, and since switches of strings are converted to a dictionary in C# anyways, it doesn't matter much in terms of performance.
For details on implementation, I've posted an implementation not so long ago on Naming convention for GoF Factory? .
Just another idea without need of switch statement.
bool isEmployee = Convert.ToString(dataRow["IsEmployee"]).ToUpper() == "TRUE";
ImagePath = string.Format("{0}.{1}", isEmployee ? fileNameUpper : fileNamelabel, strImageFormat);
I think that you shouldn't use a switch case instead of ifs.
you should solve it the right way which means to use polymorphism.
have a look at the design pattern http://www.dofactory.com/net/factory-method-design-pattern
have a look on the following initial skeleton:
public static class TestEliminateSwitch
{
public static string GetImagePath()
{
var formatFactory = new FormatFactory();
var instance = formatFactory.GetFomatClass("PDF");
return instance.GetImagePath("TRUE");
}
}
public class FormatFactory
{
public FormatBase GetFomatClass(string formatName)
{
string className = typeof (FormatBase).FullName.Replace("Base", formatName);
return Assembly.GetExecutingAssembly()
.CreateInstance(className) as FormatBase;
}
}
public abstract class FormatBase
{
public string fileNameUpper = string.Empty;
public string fileNamelabel = string.Empty;
public virtual string GetImagePath(string IsEmployee)
{
return string.Format("{0}{1}", IsEmployee.ToUpper() == "TRUE" ? fileNameUpper : fileNamelabel, GetFileExtention());
}
public abstract string GetFileExtention();
}
class FormatPDF : FormatBase
{
public override string GetFileExtention()
{
return ".PDF";
}
}
class FormatGIF : FormatBase
{
public override string GetFileExtention()
{
return ".GIF";
}
}

Storing objects in IsolatedStorageSettings

I have an object I want to store in the IsolatedStorageSettings, which I wan't to reuse when the application restarts.
My problem lies in that the code I have written for some reason does not remember the object when trying to access the key upon restarting it.
namespace MyNameSpace
{
public class WindowsPhoneSettings
{
private const string SelectedSiteKey = "SelectedSite";
private IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;
private T RetrieveSetting<T>(string settingKey)
{
object settingValue;
if (isolatedStore.TryGetValue(settingKey, out settingValue))
{
return (T)settingValue;
}
return default(T);
}
public bool AddOrUpdateValue(string Key, Object value)
{
bool valueChanged = false;
if (isolatedStore.Contains(Key))
{
if (isolatedStore[Key] != value)
{
isolatedStore[Key] = value;
valueChanged = true;
}
}
else
{
isolatedStore.Add(Key, value);
valueChanged = true;
}
return valueChanged;
}
public MobileSiteDataModel SelectedSite
{
get
{
return RetrieveSetting<MobileSiteDataModel>(SelectedSiteKey);
}
set
{
AddOrUpdateValue(SelectedSiteKey, value);
isolatedStore.Save();
}
}
}
}
I then instantiate WindowsPhoneSettings in App.xaml.cs and make a public getter and setter for it. To be able to access it in the whole application. Debugging this shows that the right object gets stored in the isolated store, but when closing the app and reopening it isolated store seems to be empty. I have tried this on both the emulator and a real device. As you can see I do call the save method when setting the object.
What am I doing wrong here?
I ended up saving the settings to a file in the isolated storage as IsolatedStorageSettings never seemed to work.
So my code ended up like this:
public class PhoneSettings
{
private const string SettingsDir = "settingsDir";
private const string SettingsFile = "settings.xml";
public void SetSettings(Settings settings)
{
SaveSettingToFile<Settings>(SettingsDir, SettingsFile, settings);
}
public Settings GetSettings()
{
return RetrieveSettingFromFile<Settings>(SettingsDir, SettingsFile);
}
private T RetrieveSettingFromFile<T>(string dir, string file) where T : class
{
IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication();
if (isolatedFileStore.DirectoryExists(dir))
{
try
{
using (var stream = new IsolatedStorageFileStream(System.IO.Path.Combine(dir, file), FileMode.Open, isolatedFileStore))
{
return (T)SerializationHelper.DeserializeData<T>(stream);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Could not retrieve file " + dir + "\\" + file + ". With Exception: " + ex.Message);
}
}
return null;
}
private void SaveSettingToFile<T>(string dir, string file, T data)
{
IsolatedStorageFile isolatedFileStore = IsolatedStorageFile.GetUserStoreForApplication();
if (!isolatedFileStore.DirectoryExists(dir))
isolatedFileStore.CreateDirectory(dir);
try
{
string fn = System.IO.Path.Combine(dir, file);
if (isolatedFileStore.FileExists(fn)) isolatedFileStore.DeleteFile(fn); //mostly harmless, used because isolatedFileStore is stupid :D
using (var stream = new IsolatedStorageFileStream(fn, FileMode.CreateNew, FileAccess.ReadWrite, isolatedFileStore))
{
SerializationHelper.SerializeData<T>(data, stream);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Could not save file " + dir + "\\" + file + ". With Exception: " + ex.Message);
}
}
}
And a settings class just containing the stuff I want to save. This could be:
class Settings
{
private string name;
private int id;
public string Name
{
get { return name; }
set { name = value; }
}
public int Id
{
get { return id; }
set { id = value; }
}
}
EDIT: Sample of how SerializationHelper could be implemented
public static class SerializationHelper
{
public static void SerializeData<T>(this T obj, Stream streamObject)
{
if (obj == null || streamObject == null)
return;
var ser = new DataContractJsonSerializer(typeof(T));
ser.WriteObject(streamObject, obj);
}
public static T DeserializeData<T>(Stream streamObject)
{
if (streamObject == null)
return default(T);
var ser = new DataContractJsonSerializer(typeof(T));
return (T)ser.ReadObject(streamObject);
}
}
Objects stored in IsolatedStorageSettings are serialised using the DataContractSerializer and so must be serializable. Ensure they can be or serialize (and deserialize) them yourself before adding to (and after removing from) ISS.
If the items aren't there when trying to retrieve then it may be that they couldn't be added in the first place (due to a serialization issue).
Here is the code I use to save an object to isolated storage and to load an object from isolated storage -
private void saveToIsolatedStorage(string keyname, object value)
{
IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;
isolatedStore.Remove(keyname);
isolatedStore.Add(keyname, value);
isolatedStore.Save();
}
private bool loadObject(string keyname, out object result)
{
IsolatedStorageSettings isolatedStore = IsolatedStorageSettings.ApplicationSettings;
result = null;
try
{
result = isolatedStore[keyname];
}
catch
{
return false;
}
return true;
}
Here is code I use to call the above -
private void SaveToIsolatedStorage()
{
saveToIsolatedStorage("GameData", GameData);
}
private void LoadFromIsolatedStorage()
{
Object temp;
if (loadObject("GameData", out temp))
{
GameData = (CGameData)temp;
}
else
{
GameData.Reset();
}
}
Note that the objects I save and restore like this are small and serializable. If my object contains a 2 dimensional array or some other object which is not serializable then I perform my own serialization and deserialization before using iso storage.
What if you changed RetrieveSetting<T> to this:
private T RetrieveSetting<T>(string settingKey)
{
T settingValue;
if(isolatedStore.TryGetValue(settingKey, out settingValue))
{
return (T)settingValue;
}
return default(T);
}
Notice that the object being fetched is being declared as type T instead of object.

itunes listening to

within windows live messenger, it is possible to share the song you are currently listening to. what would i need to do to get this working within c# like libarys etc cannot find the correct documentation on google.
You'll need to use the iTunes SDK to interact with iTunes from .NET. So there's your Google search term. :)
Here's a start:
http://blogs.msdn.com/b/noahc/archive/2006/07/06/automating-itunes-with-c-in-net.aspx
http://blogs.msdn.com/b/dancre/archive/2004/05/08/128645.aspx
Here is a script for LinqPad in C# which does as requested. (see LinqPad.com)
Bonus! Artwork view.
It looks like this:
<Query Kind="Program">
<Namespace>iTunesLib</Namespace>
<Namespace>System.Security.Cryptography</Namespace>
</Query>
void Main()
{
var track = new iTunesApp().CurrentTrack;
if (track == null)
"nothing playing".Dump();
else
new Viewer(track,true).Dump();
}
public class Viewer
{
const string PREFIX = "itlps-";
private IITFileOrCDTrack store;
private bool materialize;
public string album { get { return store.Album; } }
public string band { get { return store.Artist; } }
public string song { get { return store.Name; } }
public string desc { get { return store.Description; } }
public int? artCnt { get {
if (store.Artwork == null) return null;
else return store.Artwork.Count; }
}
public IEnumerable<ImageViewer> art { get {
if (materialize)
{
foreach(var artT in store.Artwork)
{
var art = artT as IITArtwork;
string ext = ".tmp";
switch(art.Format)
{
case ITArtworkFormat.ITArtworkFormatBMP:
ext = ".BMP";
break;
case ITArtworkFormat.ITArtworkFormatJPEG:
ext = ".JPG";
break;
case ITArtworkFormat.ITArtworkFormatPNG:
ext = ".PNG";
break;
}
string path = Path.Combine(Path.GetTempPath(),PREFIX+Path.GetRandomFileName()+ext);
art.SaveArtworkToFile(path);
yield return new ImageViewer(path);
}
}
yield break; }
}
public Viewer(IITFileOrCDTrack t,bool materializeArt = false)
{
store = t;
materialize = materializeArt;
}
public Viewer(IITTrack t,bool materializeArt = false)
{
store = t as IITFileOrCDTrack;
materialize = materializeArt;
}
}
public class ImageViewer
{
public string hash { get { return _hash.Value; } }
static private string _path { get; set; }
public object image { get { return _image.Value; } }
static private SHA1Managed sha = new SHA1Managed();
private Lazy<object> _image = new Lazy<object>(() => {return Util.Image(_path);});
private Lazy<string> _hash = new Lazy<string>(() =>
{
string hash = string.Empty;
using (FileStream stream = File.OpenRead(_path))
{
byte [] checksum = sha.ComputeHash(stream);
hash = BitConverter.ToString(checksum).Replace("-", string.Empty);
}
return hash;
});
public ImageViewer(string path)
{
_path = path;
}
}
last i checked this functionality is included out of the box all you need is to have itunes and windows live messenger installed and activate "what im listening to" and it shows this in your messenger status. if you are looking to create a bot that messages this out to a contact that is a different story tho that you will need to write a script for

Categories