Debug Mode - LINQ NullReferenceException on Collection Constructor - linq

I think I've found a bug in Visual Studio when you drag-and-drop the break-point to a different branch and you're using a certain type of LINQ query. If you place a breakpoint on the "if (x)" below and drag the executing line to the else branch, the code will fail on the initialisation/constructor for the "test2" collection.
I've used this "double from" syntax in LINQ before to do joins and I assume it's a accepted practice - not sure if there's a term for it.
Anyway can anyone else confirm this strange debug behaviour?
public class TestEntity
{
public int TestID { get; set; }
public string Test { get; set; }
}
public class Test2Entity
{
public int Test2ID { get; set; }
public string Test2 { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
bool x = Calc();
if (x) //breakpoint here
{
int y = 1;
}
else
{
System.Collections.ObjectModel.Collection<TestEntity> test = new System.Collections.ObjectModel.Collection<TestEntity>();
System.Collections.ObjectModel.Collection<Test2Entity> test2 = new System.Collections.ObjectModel.Collection<Test2Entity>(); // fails here
var z = from t in test
from t2 in test2
select t.TestID;
}
}
private bool Calc()
{
return true;
}

Related

Adding Left Border line in itextsharp

I was facing issue to work on rowspan but with some code in C#, I was able to achieve that. Currently I have the data what I needed.
How can I draw left border line for the first column so that it looks correct.
here is what I have now.
I need to add left border line.
here is my code:
{
ReportTableCell cell = null;
// prevent null values from crashing the system (always a good idea)
if (text == null)
{
text = string.Empty;
}
// else already valid
ReportTable.CreateReportTableCell(text, out cell);
cell.RowSpan = row_span;
cell.ColumnSpan = column_span;
cell.Style.WrapText = true;
cell.Style.BorderWidth = border_width;
// cell.Style.BorderColor = CellBorderColor.Gray;
if ( repeated)
{
// cell.Style.Border = BOTTOM_BORDER;
cell.Style.BorderWidth = border_width;
}
else
{
cell.Style.BorderWidth = 0;
repeated = true;
}
cell.Style.Font.FontStyle = font_style;
cell.Style.Font.FontSize = font_size;
cell.Style.BackgroundColor = background_color;
cell.Style.IsColumnHeader = is_column_header;
cell.Style.HorizontalAlignment = horizontal_alignment;
if (is_column_header)
{
cell.Style.VerticalAlignment = VerticalCellAlignment.Middle;
}
else
{
cell.Style.VerticalAlignment = VerticalCellAlignment.Top;
}
repeated = true;
return cell;
}
based on the condition i.e.
if ( repeated){}
I am removing border, which I know it has removed border around 4 corners, how can i append an extra line only for the left side.
UPDATE : 1
after using the code as below :
if ( repeated)
{
cell.Style.BorderWidth = border_width;
}
else
{
cell.Style.BorderWidth = 0;
cell.Style.Border = BOTTOM_BORDER | LEFT_BORDER;
repeated = true;
}
changed nothing!.
Here is the base class of the report.
public class ReportTableCell
{
public static readonly int ALL_BORDER;
public static readonly int BOTTOM_BORDER;
public static readonly int LEFT_BORDER;
public static readonly int NO_BORDER;
public static readonly int RIGHT_BORDER;
public static readonly int TOP_BORDER;
public bool AllowBlanks { get; set; }
public int ColumnSpan { get; set; }
public ReportFont Font { get; set; }
public int RowSpan { get; set; }
public TableCellStyle Style { get; set; }
public ReportTable Table { get; set; }
public object Value { get; set; }
public void AddImage(string FileName);
}
UPDATE : 2
I have changed the code as you suggested but , I just have to add single border line to the last. this is what i achieved till now :

How to send complex objects in GET to WEB API 2

Let's say that you have the following code
public class MyClass {
public double Latitude {get; set;}
public double Longitude {get; set;}
}
public class Criteria
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public MyClass MyProp {get; set;}
}
[HttpGet]
public Criteria Get([FromUri] Criteria c)
{
return c;
}
I'd like to know if someone is aware of a library that could transform any object into query string that is understood by a WEB API 2 Controller.
Here is an example of what I'd like
SerializeToQueryString(new Criteria{StartDate=DateTime.Today, EndDate = DateTime.Today.AddDays(1), MyProp = new MyProp{Latitude=1, Longitude=3}});
=> "startDate=2015-10-13&endDate=2015-10-14&myProp.latitude=1&myProp.longitude=3"
A full example with httpClient might look like :
new HttpClient("http://localhost").GetAsync("/tmp?"+SerializeToQueryString(new Criteria{StartDate=DateTime.Today, EndDate = DateTime.Today.AddDays(1), MyProp = new MyProp{Latitude=1, Longitude=3}})).Result;
At the moment, I use a version (taken from a question I do not find again, maybe How do I serialize an object into query-string format? ...).
The problem is that it is not working for anything else than simple properties.
For example, calling ToString on a Date will not give something that is parseable by WEB API 2 controller...
private string SerializeToQueryString<T>(T aObject)
{
var query = HttpUtility.ParseQueryString(string.Empty);
var fields = typeof(T).GetProperties();
foreach (var field in fields)
{
string key = field.Name;
var value = field.GetValue(aObject);
if (value != null)
query[key] = value.ToString();
}
return query.ToString();
}
"Transform any object to a query string" seems to imply there's a standard format for this, and there just isn't. So you would need to pick one or roll your own. JSON seems like the obvious choice due to the availability of great libraries.
Since it seems no one has dealt with the problem before, here is the solution I use in my project :
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Web;
namespace App
{
public class QueryStringSerializer
{
public static string SerializeToQueryString(object aObject)
{
return SerializeToQueryString(aObject, "").ToString();
}
private static NameValueCollection SerializeToQueryString(object aObject, string prefix)
{
//!\ doing this to get back a HttpValueCollection which is an internal class
//we want a HttpValueCollection because toString on this class is what we want in the public method
//cf http://stackoverflow.com/a/17096289/1545567
var query = HttpUtility.ParseQueryString(String.Empty);
var fields = aObject.GetType().GetProperties();
foreach (var field in fields)
{
string key = string.IsNullOrEmpty(prefix) ? field.Name : prefix + "." + field.Name;
var value = field.GetValue(aObject);
if (value != null)
{
var propertyType = GetUnderlyingPropertyType(field.PropertyType);
if (IsSupportedType(propertyType))
{
query.Add(key, ToString(value));
}
else if (value is IEnumerable)
{
var enumerableValue = (IEnumerable) value;
foreach (var enumerableValueElement in enumerableValue)
{
if (IsSupportedType(GetUnderlyingPropertyType(enumerableValueElement.GetType())))
{
query.Add(key, ToString(enumerableValueElement));
}
else
{
//it seems that WEB API 2 Controllers are unable to deserialize collections of complex objects...
throw new Exception("can not use IEnumerable<T> where T is a class because it is not understood server side");
}
}
}
else
{
var subquery = SerializeToQueryString(value, key);
query.Add(subquery);
}
}
}
return query;
}
private static Type GetUnderlyingPropertyType(Type propType)
{
var nullablePropertyType = Nullable.GetUnderlyingType(propType);
return nullablePropertyType ?? propType;
}
private static bool IsSupportedType(Type propertyType)
{
return SUPPORTED_TYPES.Contains(propertyType) || propertyType.IsEnum;
}
private static readonly Type[] SUPPORTED_TYPES = new[]
{
typeof(DateTime),
typeof(string),
typeof(int),
typeof(long),
typeof(float),
typeof(double)
};
private static string ToString(object value)
{
if (value is DateTime)
{
var dateValue = (DateTime) value;
if (dateValue.Hour == 0 && dateValue.Minute == 0 && dateValue.Second == 0)
{
return dateValue.ToString("yyyy-MM-dd");
}
else
{
return dateValue.ToString("yyyy-MM-dd HH:mm:ss");
}
}
else if (value is float)
{
return ((float) value).ToString(CultureInfo.InvariantCulture);
}
else if (value is double)
{
return ((double)value).ToString(CultureInfo.InvariantCulture);
}
else /*int, long, string, ENUM*/
{
return value.ToString();
}
}
}
}
Here is the unit test to demonstrate :
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Framework.WebApi.Core.Tests
{
[TestClass]
public class QueryStringSerializerTest
{
public class EasyObject
{
public string MyString { get; set; }
public int? MyInt { get; set; }
public long? MyLong { get; set; }
public float? MyFloat { get; set; }
public double? MyDouble { get; set; }
}
[TestMethod]
public void TestEasyObject()
{
var queryString = QueryStringSerializer.SerializeToQueryString(new EasyObject(){MyString = "string", MyInt = 1, MyLong = 1L, MyFloat = 1.5F, MyDouble = 1.4});
Assert.IsTrue(queryString.Contains("MyString=string"));
Assert.IsTrue(queryString.Contains("MyInt=1"));
Assert.IsTrue(queryString.Contains("MyLong=1"));
Assert.IsTrue(queryString.Contains("MyFloat=1.5"));
Assert.IsTrue(queryString.Contains("MyDouble=1.4"));
}
[TestMethod]
public void TestEasyObjectNullable()
{
var queryString = QueryStringSerializer.SerializeToQueryString(new EasyObject() { });
Assert.IsTrue(queryString == "");
}
[TestMethod]
public void TestUrlEncoding()
{
var queryString = QueryStringSerializer.SerializeToQueryString(new EasyObject() { MyString = "&=/;+" });
Assert.IsTrue(queryString.Contains("MyString=%26%3d%2f%3b%2b"));
}
public class DateObject
{
public DateTime MyDate { get; set; }
}
[TestMethod]
public void TestDate()
{
var d = DateTime.ParseExact("2010-10-13", "yyyy-MM-dd", CultureInfo.InvariantCulture);
var queryString = QueryStringSerializer.SerializeToQueryString(new DateObject() { MyDate = d });
Assert.IsTrue(queryString.Contains("MyDate=2010-10-13"));
}
[TestMethod]
public void TestDateTime()
{
var d = DateTime.ParseExact("2010-10-13 20:00", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
var queryString = QueryStringSerializer.SerializeToQueryString(new DateObject() { MyDate = d });
Assert.IsTrue(queryString.Contains("MyDate=2010-10-13+20%3a00%3a00"));
}
public class InnerComplexObject
{
public double Lat { get; set; }
public double Lon { get; set; }
}
public class ComplexObject
{
public InnerComplexObject Inner { get; set; }
}
[TestMethod]
public void TestComplexObject()
{
var queryString = QueryStringSerializer.SerializeToQueryString(new ComplexObject() { Inner = new InnerComplexObject() {Lat = 50, Lon = 2} });
Assert.IsTrue(queryString.Contains("Inner.Lat=50"));
Assert.IsTrue(queryString.Contains("Inner.Lon=2"));
}
public class EnumerableObject
{
public IEnumerable<int> InnerInts { get; set; }
}
[TestMethod]
public void TestEnumerableObject()
{
var queryString = QueryStringSerializer.SerializeToQueryString(new EnumerableObject() {
InnerInts = new[] { 1,2 }
});
Assert.IsTrue(queryString.Contains("InnerInts=1"));
Assert.IsTrue(queryString.Contains("InnerInts=2"));
}
public class ComplexEnumerableObject
{
public IEnumerable<InnerComplexObject> Inners { get; set; }
}
[TestMethod]
public void TestComplexEnumerableObject()
{
try
{
QueryStringSerializer.SerializeToQueryString(new ComplexEnumerableObject()
{
Inners = new[]
{
new InnerComplexObject() {Lat = 50, Lon = 2},
new InnerComplexObject() {Lat = 51, Lon = 3},
}
});
Assert.Fail("we should refuse something that will not be understand by the server");
}
catch (Exception e)
{
Assert.AreEqual("can not use IEnumerable<T> where T is a class because it is not understood server side", e.Message);
}
}
public enum TheEnum : int
{
One = 1,
Two = 2
}
public class EnumObject
{
public TheEnum? MyEnum { get; set; }
}
[TestMethod]
public void TestEnum()
{
var queryString = QueryStringSerializer.SerializeToQueryString(new EnumObject() { MyEnum = TheEnum.Two});
Assert.IsTrue(queryString.Contains("MyEnum=Two"));
}
}
}
I'd like to thank all the participants even if this is not something that you should usually do in a Q&A format :)

SQLite.Net Update generating error "it has no PK"

I'm using Lync syntax in a PCL using Xamarin.
public class settings
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string user_name { get; set; }
public string password { get; set; }
public string server { get; set; }
}
void CreateTables()
{
database.CreateTable<settings>();
}
void Insert()
{
settings s = new settings();
s.server = "<none>"
s.user_name = "";
s.password = "";
database.Insert(s)
}
void Update()
{
settings s = database.Table<settings>().FirstOrDefault();
s.server = server_address.Text;
s.user_name = user_name.Text;
s.password = pass.Text;
database.Update(s)
}
I get "Cannot update settings: it has no PK" when updating, but inserting works fine. I'm using Xamarin in a PCL referencing SQLite.net. I'm new to SQlite and Xamarin, so please be verbose when asking for more detail.
UPDATE - RESOLVED
The class is in the same namespace as the place I create an instance of the database object. Simply adding the "Sqlite" to my attribute fixed the issue which is really strange.
[SQLite.PrimaryKey, SQLite.AutoIncrement]
I have been stocked for a week now on this problem and even the above solution is not working for me...
I think that the Id does not increments automatically, that's why it says :cannot update ...
What actually works for me is incrementing the PK (Id) manually...as follows.
persons.Id++;
At the moment of verifying and inserting data into the database, I just added the above code and it updated successfully.
private async void Register_Student(object sender, EventArgs e){... ...
if(!string.Equals(newPassword.Text, rePassword.Text)){
warningLabel.Text = "Enter same pwd"; ...
}
else{
persons.Id++; //solution that worked for me at insertion level
persons.UserName = newUsername.Text; //Text entered by the user
}...
}
Thanks...

Trying to string.Join an IList and outputting the results to console

Using "string.Join(",", test);" works but for some reason I get an output of:
"Ilistprac.Location, Ilistprac.Location, Ilistprac.Location"
I tried ToString, Convert.ToString, etc and I still get that output.
All the IList interfaces are implemented with the IEnurmerable too (just not listed here unless someone wants me to).
class IList2
{
static void Main(string[] args)
{
string sSite = "test";
string sBldg = "test32";
string sSite1 = "test";
string sSite2 = "test";
Locations test = new Locations();
Location loc = new Location();
test.Add(sSite, sBldg)
test.Add(sSite1)
test.Add(sSite2)
string printitout = string.Join(",", test); //having issues outputting whats on the list
}
}
string printitout = string.Join(",", test.ToArray<Location>);
public class Location
{
public Location()
{
}
private string _site = string.Empty;
public string Site
{
get { return _site; }
set { _site = value; }
}
}
public class Locations : IList<Location>
{
List<Location> _locs = new List<Location>();
public Locations() { }
public void Add(string sSite)
{
Location loc = new Location();
loc.Site = sSite;
loc.Bldg = sBldg;
_locs.Add(loc);
}
private string _bldg = string.Empty;
public string Bldg
{
get { return _bldg; }
set { _bldg = value; }
}
}
You need to supply a useful ToString implementation for Location as Join is calling that for each element. The default implementation will just return the name of the type. See documentation.
So if you have a type like
class SomeType
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
public SomeType(string first, string last)
{
FirstName = first;
LastName = last;
}
public override string ToString()
{
return string.Format("{0}, {1}", LastName, FirstName);
}
}
You need to specify how that should be represented as a string. If you do that, you can use string.Join like this to produce the output below.
var names = new List<SomeType> {
new SomeType("Homer", "Simpson"),
new SomeType("Marge", "Simpson")
};
Console.WriteLine(string.Join("\n", names));
Output:
Simpson, Homer
Simpson, Marge
You have to override ToString() inc your Location class to provide some meaningful output if you want to keep your current approach, E.g.:
public override string ToString()
{
return Site;
}

WP7 Mock Microsoft.Devices.Sensors.Compass when using the emulator

I'd like to be able to simulate the compass sensor when running a Windows Phone 7.1 in the emulator.
At this stage I don't particularly care what data the compass returns. Just that I can run against something when using the emulator to test the code in question.
I'm aware that I could deploy to my dev unlocked phone to test compass functionality but I've found the connection via the Zune software to drop out frequently.
Update
I've looked into creating my own wrapper class that could simulate the compass when running a debug build and the compass isn't otherwise supported.
The Microsoft.Devices.Sensors.CompassReading struct has me a bit stumpted. Because it is a struct where the properties can only be set internally I can't inherit from it to provide my own values back. I looked at using reflection to brute force some values in but Silverlight doesn't appear to allow it.
as you already noticed I had a similar problem. when I mocked the compass sensor, I also had difficulties because you cannot inherite from the existing classes and write your own logic. Therefore I wrote my own compass interface which is the only compass functionality used by my application. Then there are two implementations, one wrapper to the WP7 compass functionalities and my mock compass.
I can show you some code, but not before weekend as I'm not at my delevopment machine atm.
Edit:
You already got it but for other people who have the same problem I'll add my code. As I already said, I wrote an interface and two implementations, one for the phone and a mock implementation.
Compass Interface
public interface ICompass
{
#region Methods
void Start();
void Stop();
#endregion
#region Properties
CompassData CurrentValue { get; }
bool IsDataValid { get; }
TimeSpan TimeBetweenUpdates { get; set; }
#endregion
#region Events
event EventHandler<CalibrationEventArgs> Calibrate;
event EventHandler<CompassDataChangedEventArgs> CurrentValueChanged;
#endregion
}
Used data classes and event args
public class CompassData
{
public CompassData(double headingAccurancy, double magneticHeading, Vector3 magnetometerReading, DateTimeOffset timestamp, double trueHeading)
{
HeadingAccuracy = headingAccurancy;
MagneticHeading = magneticHeading;
MagnetometerReading = magnetometerReading;
Timestamp = timestamp;
TrueHeading = trueHeading;
}
public CompassData(CompassReading compassReading)
{
HeadingAccuracy = compassReading.HeadingAccuracy;
MagneticHeading = compassReading.MagneticHeading;
MagnetometerReading = compassReading.MagnetometerReading;
Timestamp = compassReading.Timestamp;
TrueHeading = compassReading.TrueHeading;
}
#region Properties
public double HeadingAccuracy { get; private set; }
public double MagneticHeading { get; private set; }
public Vector3 MagnetometerReading { get; private set; }
public DateTimeOffset Timestamp { get; private set; }
public double TrueHeading { get; private set; }
#endregion
}
public class CompassDataChangedEventArgs : EventArgs
{
public CompassDataChangedEventArgs(CompassData compassData)
{
CompassData = compassData;
}
public CompassData CompassData { get; private set; }
}
WP7 implementation
public class DeviceCompass : ICompass
{
private Compass _compass;
#region Implementation of ICompass
public void Start()
{
if(_compass == null)
{
_compass = new Compass {TimeBetweenUpdates = TimeBetweenUpdates};
// get TimeBetweenUpdates because the device could have change it to another value
TimeBetweenUpdates = _compass.TimeBetweenUpdates;
// attach to events
_compass.CurrentValueChanged += CompassCurrentValueChanged;
_compass.Calibrate += CompassCalibrate;
}
_compass.Start();
}
public void Stop()
{
if(_compass != null)
{
_compass.Stop();
}
}
public CompassData CurrentValue
{
get { return _compass != null ? new CompassData(_compass.CurrentValue) : default(CompassData); }
}
public bool IsDataValid
{
get { return _compass != null ? _compass.IsDataValid : false; }
}
public TimeSpan TimeBetweenUpdates { get; set; }
public event EventHandler<CalibrationEventArgs> Calibrate;
public event EventHandler<CompassDataChangedEventArgs> CurrentValueChanged;
#endregion
#region Private methods
private void CompassCalibrate(object sender, CalibrationEventArgs e)
{
EventHandler<CalibrationEventArgs> calibrate = Calibrate;
if (calibrate != null)
{
calibrate(sender, e);
}
}
private void CompassCurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e)
{
EventHandler<CompassDataChangedEventArgs> currentValueChanged = CurrentValueChanged;
if (currentValueChanged != null)
{
currentValueChanged(sender, new CompassDataChangedEventArgs(new CompassData(e.SensorReading)));
}
}
#endregion
}
Mock implementation
public class MockCompass : ICompass
{
private readonly Timer _timer;
private CompassData _currentValue;
private bool _isDataValid;
private TimeSpan _timeBetweenUpdates;
private bool _isStarted;
private readonly Random _random;
public MockCompass()
{
_random = new Random();
_timer = new Timer(TimerEllapsed, null, Timeout.Infinite, Timeout.Infinite);
_timeBetweenUpdates = new TimeSpan();
_currentValue = new CompassData(0, 0, new Vector3(), new DateTimeOffset(), 0);
}
#region Implementation of ICompass
public void Start()
{
_timer.Change(0, (int)TimeBetweenUpdates.TotalMilliseconds);
_isStarted = true;
}
public void Stop()
{
_isStarted = false;
_timer.Change(Timeout.Infinite, Timeout.Infinite);
_isDataValid = false;
}
public CompassData CurrentValue
{
get { return _currentValue; }
}
public bool IsDataValid
{
get { return _isDataValid; }
}
public TimeSpan TimeBetweenUpdates
{
get { return _timeBetweenUpdates; }
set
{
_timeBetweenUpdates = value;
if (_isStarted)
{
_timer.Change(0, (int) TimeBetweenUpdates.TotalMilliseconds);
}
}
}
public event EventHandler<CalibrationEventArgs> Calibrate;
public event EventHandler<CompassDataChangedEventArgs> CurrentValueChanged;
#endregion
#region Private methods
private void TimerEllapsed(object state)
{
_currentValue = new CompassData(_random.NextDouble()*5,
(_currentValue.MagneticHeading + 0.1)%360,
_currentValue.MagnetometerReading,
new DateTimeOffset(DateTime.UtcNow),
(_currentValue.TrueHeading + 0.1)%360);
_isDataValid = true;
EventHandler<CompassDataChangedEventArgs> currentValueChanged = CurrentValueChanged;
if(currentValueChanged != null)
{
currentValueChanged(this, new CompassDataChangedEventArgs(_currentValue));
}
}
#endregion
}

Resources