Using DynamicObject to simulate DependencyProperties - c#

I'm looking to create something akin to one of the features of VS or Blend whereby when one selects multiple objects, the property grid shows the value for any property that is shared by all objects and shows nothing for properties that differ between the objects.
I've managed to implement this behaviour for CLR properties using a dynamic object:
_knownProperties is just a list of properties which have previously been requested
_collection is an IEnumerable instance
public override bool TryGetMember( GetMemberBinder binder, out object result ) {
Debug.WriteLine( "Getting " + binder.Name + "..." );
if (!_knownProperties.Contains( binder.Name ))
_knownProperties.Add( binder.Name );
IEnumerator it = _collection.GetEnumerator();
if (!it.MoveNext()) {
result = null;
Debug.WriteLine( "No elements in collection" );
return true;
}
Type t = it.Current.GetType();
PropertyInfo pinf = t.GetProperty( binder.Name );
if (pinf == null) {
result = null;
Debug.WriteLine( "Property doesn't exist." );
return true;
}
result = pinf.GetValue( it.Current, null );
if (result == null) {
Debug.WriteLine( "Null result" );
return true;
}
while (it.MoveNext())
if (!result.Equals( it.Current.GetType().GetProperty( binder.Name ).GetValue( it.Current, null ) )) {
result = null;
Debug.WriteLine( "Null result" );
return true;
}
Debug.WriteLine( "Result: " + result.ToString() );
return true;
}
I'm accessing these properties via WPF Bindings.
Can anyone think of a way to implement this for DependencyProperties? If I attempt to bind to an attached property on the object, I get an ArgumentNullException in the property system (where the object that is null can't possibly be null according to the source I have)
{Binding Selection.SomeClrProperty,...} works fine (Selection is one of the dynamic objects, SomeClrProperty is a property on every element of the collection.
{Binding Selection.(SomeClass.SomeAttachedProperty),...} Fires an error in the property system
The Exception:
System.ArgumentNullException was unhandled
Message=Key cannot be null.
Parameter name: key
Source=System
ParamName=key
StackTrace:
at System.Collections.Specialized.HybridDictionary.get_Item(Object key)
at System.ComponentModel.PropertyChangedEventManager.PrivateAddListener(INotifyPropertyChanged source, IWeakEventListener listener, String propertyName)
at System.ComponentModel.PropertyChangedEventManager.AddListener(INotifyPropertyChanged source, IWeakEventListener listener, String propertyName)
at MS.Internal.Data.PropertyPathWorker.ReplaceItem(Int32 k, Object newO, Object parent)
at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
at MS.Internal.Data.ClrBindingWorker.AttachDataItem()
at System.Windows.Data.BindingExpression.Activate(Object item)
...

Use OneTime bindings to prevent WPF from trying to put a listener on the attached property:
{Binding Selection.(SomeClass.SomeAttachedProperty), Mode=OneTime, ...}

Related

Nullable enabled, but 'Value cannot be null' [duplicate]

I don't know why I get this kind of error. It happens sometimes, and I suspicious of my code that still have thread running while I close my Application. So when I open again it happens.
Value cannot be null.
Parameter name: source
StackTree :
   at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
   at Susenas2015.ViewModels.Kuesioner.VMVsen15_KVal.SettingValidationAndRange(List`1 listTextBox, List`1 listCheckBox, TabControl tabControl) in d:\handita\Office\Project\Susenas 2015\Aplikasi Template Survei\Susenas2015\ViewModels\Kuesioner\VMVsen15_KVal.cs:line 430
   at Susenas2015.ViewModels.Kuesioner.VMVsen15_KVal.vSen15_K_Loaded(Object sender, RoutedEventArgs e) in d:\handita\Office\Project\Susenas 2015\Aplikasi Template Survei\Susenas2015\ViewModels\Kuesioner\VMVsen15_KVal.cs:line 846
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
   at System.Windows.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wpa`
My code here it is
private void SettingValidationAndRange(List<TextBox> listTextBox, List<CheckBox> listCheckBox, TabControl tabControl)
{
List<string> listNotDeclare = new List<string>();
foreach (var textB in listTextBox)
{
if (textB.Tag != null)
break;
Metadata metadata = ListMetadataKor.Where(
x => "text" + x.Field == textB.Name // this line 430
).FirstOrDefault();
if (metadata == null)
{
if (!string.IsNullOrEmpty(textB.Name))
listNotDeclare.Add(textB.Name);
}
else
{
metadata.TabControl = tabControl;
textB.Tag = metadata;
}
textB.AddEvents();
textB.AutomateFocus();
}
if (listNotDeclare.Count > 0)
{
Clipboard.SetText(string.Join(",", listNotDeclare.ToArray()));
Dialog.Info("Ada beberapa Metadata tidak ditemukan data sudah dicopy ke clipboard");
}
}
When I start my application for my first time, it doesn't get any error. It happens when I open in 2nd or more. And if I open my application it would stuck in that code.
How I can solve this? I'm pretty sure that my Property ListMetadataKor is not null
And ListMetadataKor is instance of List<Metadata> object that I have created. It happens only in rare cases. And I don't know to solve it
UPDATE
This is my code in image
I fill ListMetadataKor with this code
BWHelper.Run((s, e) =>
{
DataTable dataMetaDataKOR = ExcelHelper.GetDataTableFromExcel(
AppConstants.FILE_METADATA, AppConstants.SHEET_METADATA_KOR
);
DataTable dataKonsistensiKOR = ExcelHelper.GetDataTableFromExcel(
AppConstants.FILE_METADATA, AppConstants.SHEET_KONSISTENSI_KOR
);
listKonsistensiKor = Tools.ToolConvert.GetKonsistensi(dataKonsistensiKOR);
listMetadataKor = Tools.ToolConvert.GetMetadata(dataMetaDataKOR);
foreach (Metadata metadata in listMetadataKor)
{
metadata.Range.ProsesRange();
}
}, (s, e) =>
{
try
{
kor = new VSEN15_K() { Title = "Validasi Susenas - KOR" };
kor.DataContext = new VMVsen15_KVal(rtSusenas.MasterRT, kor, this, listKonsistensiKor, listMetadataKor);
kor.PreviewKeyDown += EventsCollection.EnterAsTabPreviewKeyDown;
vmHome.HideLoading();
UpdateMetaDataEntriKOR(RTSusenas.MasterRT);
kor.ShowDialog();
}
catch (Exception Ex)
{
vmHome.HideLoading();
Dialog.Error(Ex);
}
});
And then I throw the variable through constructor of my class
public VMVsen15_KVal(
MasterRT masterRT,
VSEN15_K vSen15_K,
IDaftarSusenas vmDaftarRTSusenas,
List<Konsistensi> listKonsistensiKor,
List<Metadata> listMetadataKor
)
{
ListArtDetail = new ObservableCollection<ARTDetailVal>();
this.ListKonsistensiKor = listKonsistensiKor;
this.ListMetadataKor = listMetadataKor;
My tools konsistensi like this
public static List<Konsistensi> GetKonsistensi(DataTable dataTable)
{
List<Konsistensi> listMetadata = new List<Konsistensi>();
for (int i = 0; i < dataTable.Rows.Count; i++)
{
Konsistensi k = new Konsistensi();
object[] required = new object[] { DBNull.Value, "" };
k.Field = dataTable.Rows[i][FIELD].ToString();
if (string.IsNullOrWhiteSpace(k.Field)) continue;
k.Message = dataTable.Rows[i][MESSAGE].ToString();
var obj = dataTable.Rows[i][ORDER];
k.Order = !required.Contains(dataTable.Rows[i][ORDER]) ? Convert.ToInt32(dataTable.Rows[i][ORDER]) : (int?)null;
k.Page = !required.Contains(dataTable.Rows[i][PAGE]) ? Convert.ToInt32(dataTable.Rows[i][PAGE]) : (int?)null;
k.Perlakuan = dataTable.Rows[i][PERLAKUAN].ToString();
k.RelFields = dataTable.Rows[i][RELFIELDS].ToString();
k.Rule = dataTable.Rows[i][RULE].ToString();
if (dataTable.Rows[i][LEVEL].ToString().ToUpper() == ("ART"))
k.LevelKonsistensi = LevelKonsistensi.ART;
else if (dataTable.Rows[i][LEVEL].ToString().ToUpper() == ("RT"))
k.LevelKonsistensi = LevelKonsistensi.RT;
else if (dataTable.Rows[i][LEVEL].ToString().ToUpper() == ("RTWARNING"))
k.LevelKonsistensi = LevelKonsistensi.RTWarning;
else if (dataTable.Rows[i][LEVEL].ToString().ToUpper().Contains("ARTWARNING"))
k.LevelKonsistensi = LevelKonsistensi.ARTWarning;
else
k.LevelKonsistensi = LevelKonsistensi.Lain;
//k.LevelKonsistensi = dataTable.Rows[i][LEVEL].ToString().Contains("ART") ? LevelKonsistensi.ART : LevelKonsistensi.RT;
if (k.IsEmpty())
continue;
listMetadata.Add(k);
}
return listMetadata;
}
Error message clearly says that source parameter is null. Source is the enumerable you are enumerating. In your case it is ListMetadataKor object. And its definitely null at the time you are filtering it second time. Make sure you never assign null to this list. Just check all references to this list in your code and look for assignments.
Value cannot be null.
Parameter name: source
Above error comes in situation when you are querying the collection which is null.
For demonstration below code will result in such an exception.
Console.WriteLine("Hello World");
IEnumerable<int> list = null;
list.Where(d => d ==4).FirstOrDefault();
Here is the output of the above code.
Hello World
Run-time exception (line 11): Value cannot be null.
Parameter name: source
Stack Trace:
[System.ArgumentNullException: Value cannot be null.
Parameter name: source] at Program.Main(): line 11
In your case ListMetadataKor is null.
Here is the fiddle if you want to play around.
When you call a Linq statement like this:
// x = new List<string>();
var count = x.Count(s => s.StartsWith("x"));
You are actually using an extension method in the System.Linq namespace, so what the compiler translates this into is:
var count = Enumerable.Count(x, s => s.StartsWith("x"));
So the error you are getting above is because the first parameter, source (which would be x in the sample above) is null.
System.ArgumentNullException: Value cannot be null. Parameter name:
value
This error message is not very helpful!
You can get this error in many different ways. The error may not always be with the parameter name: value. It could be whatever parameter name is being passed into a function.
As a generic way to solve this, look at the stack trace or call stack:
Test method GetApiModel threw exception:
System.ArgumentNullException: Value cannot be null.
Parameter name: value
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
You can see that the parameter name value is the first parameter for DeserializeObject. This lead me to check my AutoMapper mapping where we are deserializing a JSON string. That string is null in my database.
You can change the code to check for null.
my problem was with spelling It was case sensitive! Few of the columns were sorting properly and rest were throwing this error!

Generic type func-eval using ICorDebugEval

I'm making a managed .NET debugger using MDBG sample.
MDBG has no support for property getters evaluation, which I'm trying to add. Please, consider following class structure:
public abstract class Base<T>{
public string SomeProp {get;set;}
}
public class A : Base<int>{
}
At some point of time I'm creating an instance of A and stopping at a breakpoint to evaluate it's state.
In my debugger's watch window I introduce "this.SomeProp", that should perform a func-eval of get_SomeProp method on this object and return a null value for given case.
The first issue I've encountered was the fact, that get_SomeProp was defined on the base class, so I had to run through all TypeDefs/TypeRefs/TypeSpecs in the class hierarchy to find the function.
But after it was found, calling
ICorDebugEval.CallFunction(function.CorFunction, new[] {#object.CorValue});
resulted in: TypeLoadException: The generic type was used with the wrong number of generic arguments in assembly.
As I've realized it happens because non-generic function is defined in a generic class (Base), so when I'm evaluating it I should also indicate class's generic params.
This could be done using
ICorDebugEval2.CallParameterizedFunction(function.CorFunction,
genericArguments,
functionArguments);
The problem is that I have no idea how to extract types of class generic parameters, having only function that I want to evaluate and instance on which I want to evaluate it.
Here is some code I'm currently using:
private MDbgValue EvaluatePropertyGetter(MDbgFrame scope, MDbgValue #object, string propertyName) {
var propertyGetter = $"get_{propertyName}";
var function = ResolveFunctionName(
scope.Function.Module.CorModule.Name,
#object.TypeName,
propertyGetter,
scope.Thread.CorThread.AppDomain);
if (function == null) {
throw new MDbgValueException("Function '" + propertyGetter + "' not found.");
}
var eval = Threads.Active.CorThread.CreateEval();
var typeToken = function.CorFunction.Class.Token;
var type = function.Module.Importer.GetType(typeToken); //checked that type containing function is generic
if (type.IsGenericType) {
//------------->need to get class'es generic param types<------------
var genericType1 = this.ResolveType("System.Object"); // just a stub
eval.CallParameterizedFunction(function.CorFunction, new CorType[] {genericType1}, new[] {#object.CorValue});
}
else {
eval.CallFunction(function.CorFunction, new[] {#object.CorValue});
}
Go().WaitOne();
if (!(StopReason is EvalCompleteStopReason)) {
// we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason
Console.WriteLine("Func-eval not fully completed and debuggee has stopped");
Console.WriteLine("Result of funceval won't be printed when finished.");
}
else {
eval = (StopReason as EvalCompleteStopReason).Eval;
Debug.Assert(eval != null);
var cv = eval.Result;
if (cv != null) {
var mv = new MDbgValue(this, cv);
return mv;
}
}
return null;
}
Any suggestion/advice is greatly appreciated!
Regards,
Solution
Thanks to #Brian Reichle outstanding answer I came up with this solution:
if (type.IsGenericType) {
//getting Type's Generic parameters
var typeParams = GetGenericArgs(#object.CorValue.ExactType, function.CorFunction.Class.Token);
eval.CallParameterizedFunction(function.CorFunction, typeParams.ToArray(), new[] {#object.CorValue});
}
And the function itself:
private List<CorType> GetGenericArgs(CorType corType, int classTk) {
if (corType == null)
return null;
List<CorType> list = new List<CorType>();
var param =corType.TypeParameters;
var args = GetGenericArgs(corType.Base, classTk);
if (classTk == corType.Class.Token) {
list.AddRange(param.Cast<CorType>());
}
if (args != null) {
list.AddRange(args);}
return list;
}
You can use ICorDebugValue2::GetExactType on the value object representing an instance of A to get the ICorDebugType for type A, ICorDebugType::GetBase() to get its base class (Base<int>) and ICorDebugType::EnumerateTypeParameters on the base type to get it's type arguments.

How to identify Property Custom Type in Listener?

We use a custom type (IUserType) in some properties mapping to encrypt the data in the database, and we use listeners (IPostUpdateEventListener, IPostDeleteEventListener, IPostInsertEventListener) to log changes in some entities, its all base in entity Attributes to decide if log is necessary or not. The problem is encrypted properties are logged without encryption.
Is there a way, with the IEntityPersister or other source, to identify witch property is encrypted (uses our custom type) or not?
private string GetValue(ISession session, object[] stateArray, int index, IEntityPersister persister)
{
try
{
return stateArray[index] == null || stateArray[index].ToString() == string.Empty
? "< No value >"
: stateArray[index].ToString();
}
catch (Exception e)
{
Trace.Write(string.Format("Error \"{0}[{1}]\": {2}", persister.EntityName, persister.PropertyTypes[index],
e));
return "< No value >";
}
}
...
public void OnPostInsert(PostInsertEvent #event)
{
var res = GetValue(session, #event.State, i, #event.Persister);
...
Firo solution worked:
...
if (Persistor.PropertyTypes[i] is CustomType && (Persistor.PropertyTypes[i] as CustomType).UserType is MyUserType)
return "Encrypted";
...

How to resolve Value cannot be null. Parameter name: source in linq?

I don't know why I get this kind of error. It happens sometimes, and I suspicious of my code that still have thread running while I close my Application. So when I open again it happens.
Value cannot be null.
Parameter name: source
StackTree :
   at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
   at Susenas2015.ViewModels.Kuesioner.VMVsen15_KVal.SettingValidationAndRange(List`1 listTextBox, List`1 listCheckBox, TabControl tabControl) in d:\handita\Office\Project\Susenas 2015\Aplikasi Template Survei\Susenas2015\ViewModels\Kuesioner\VMVsen15_KVal.cs:line 430
   at Susenas2015.ViewModels.Kuesioner.VMVsen15_KVal.vSen15_K_Loaded(Object sender, RoutedEventArgs e) in d:\handita\Office\Project\Susenas 2015\Aplikasi Template Survei\Susenas2015\ViewModels\Kuesioner\VMVsen15_KVal.cs:line 846
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
   at System.Windows.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wpa`
My code here it is
private void SettingValidationAndRange(List<TextBox> listTextBox, List<CheckBox> listCheckBox, TabControl tabControl)
{
List<string> listNotDeclare = new List<string>();
foreach (var textB in listTextBox)
{
if (textB.Tag != null)
break;
Metadata metadata = ListMetadataKor.Where(
x => "text" + x.Field == textB.Name // this line 430
).FirstOrDefault();
if (metadata == null)
{
if (!string.IsNullOrEmpty(textB.Name))
listNotDeclare.Add(textB.Name);
}
else
{
metadata.TabControl = tabControl;
textB.Tag = metadata;
}
textB.AddEvents();
textB.AutomateFocus();
}
if (listNotDeclare.Count > 0)
{
Clipboard.SetText(string.Join(",", listNotDeclare.ToArray()));
Dialog.Info("Ada beberapa Metadata tidak ditemukan data sudah dicopy ke clipboard");
}
}
When I start my application for my first time, it doesn't get any error. It happens when I open in 2nd or more. And if I open my application it would stuck in that code.
How I can solve this? I'm pretty sure that my Property ListMetadataKor is not null
And ListMetadataKor is instance of List<Metadata> object that I have created. It happens only in rare cases. And I don't know to solve it
UPDATE
This is my code in image
I fill ListMetadataKor with this code
BWHelper.Run((s, e) =>
{
DataTable dataMetaDataKOR = ExcelHelper.GetDataTableFromExcel(
AppConstants.FILE_METADATA, AppConstants.SHEET_METADATA_KOR
);
DataTable dataKonsistensiKOR = ExcelHelper.GetDataTableFromExcel(
AppConstants.FILE_METADATA, AppConstants.SHEET_KONSISTENSI_KOR
);
listKonsistensiKor = Tools.ToolConvert.GetKonsistensi(dataKonsistensiKOR);
listMetadataKor = Tools.ToolConvert.GetMetadata(dataMetaDataKOR);
foreach (Metadata metadata in listMetadataKor)
{
metadata.Range.ProsesRange();
}
}, (s, e) =>
{
try
{
kor = new VSEN15_K() { Title = "Validasi Susenas - KOR" };
kor.DataContext = new VMVsen15_KVal(rtSusenas.MasterRT, kor, this, listKonsistensiKor, listMetadataKor);
kor.PreviewKeyDown += EventsCollection.EnterAsTabPreviewKeyDown;
vmHome.HideLoading();
UpdateMetaDataEntriKOR(RTSusenas.MasterRT);
kor.ShowDialog();
}
catch (Exception Ex)
{
vmHome.HideLoading();
Dialog.Error(Ex);
}
});
And then I throw the variable through constructor of my class
public VMVsen15_KVal(
MasterRT masterRT,
VSEN15_K vSen15_K,
IDaftarSusenas vmDaftarRTSusenas,
List<Konsistensi> listKonsistensiKor,
List<Metadata> listMetadataKor
)
{
ListArtDetail = new ObservableCollection<ARTDetailVal>();
this.ListKonsistensiKor = listKonsistensiKor;
this.ListMetadataKor = listMetadataKor;
My tools konsistensi like this
public static List<Konsistensi> GetKonsistensi(DataTable dataTable)
{
List<Konsistensi> listMetadata = new List<Konsistensi>();
for (int i = 0; i < dataTable.Rows.Count; i++)
{
Konsistensi k = new Konsistensi();
object[] required = new object[] { DBNull.Value, "" };
k.Field = dataTable.Rows[i][FIELD].ToString();
if (string.IsNullOrWhiteSpace(k.Field)) continue;
k.Message = dataTable.Rows[i][MESSAGE].ToString();
var obj = dataTable.Rows[i][ORDER];
k.Order = !required.Contains(dataTable.Rows[i][ORDER]) ? Convert.ToInt32(dataTable.Rows[i][ORDER]) : (int?)null;
k.Page = !required.Contains(dataTable.Rows[i][PAGE]) ? Convert.ToInt32(dataTable.Rows[i][PAGE]) : (int?)null;
k.Perlakuan = dataTable.Rows[i][PERLAKUAN].ToString();
k.RelFields = dataTable.Rows[i][RELFIELDS].ToString();
k.Rule = dataTable.Rows[i][RULE].ToString();
if (dataTable.Rows[i][LEVEL].ToString().ToUpper() == ("ART"))
k.LevelKonsistensi = LevelKonsistensi.ART;
else if (dataTable.Rows[i][LEVEL].ToString().ToUpper() == ("RT"))
k.LevelKonsistensi = LevelKonsistensi.RT;
else if (dataTable.Rows[i][LEVEL].ToString().ToUpper() == ("RTWARNING"))
k.LevelKonsistensi = LevelKonsistensi.RTWarning;
else if (dataTable.Rows[i][LEVEL].ToString().ToUpper().Contains("ARTWARNING"))
k.LevelKonsistensi = LevelKonsistensi.ARTWarning;
else
k.LevelKonsistensi = LevelKonsistensi.Lain;
//k.LevelKonsistensi = dataTable.Rows[i][LEVEL].ToString().Contains("ART") ? LevelKonsistensi.ART : LevelKonsistensi.RT;
if (k.IsEmpty())
continue;
listMetadata.Add(k);
}
return listMetadata;
}
Error message clearly says that source parameter is null. Source is the enumerable you are enumerating. In your case it is ListMetadataKor object. And its definitely null at the time you are filtering it second time. Make sure you never assign null to this list. Just check all references to this list in your code and look for assignments.
Value cannot be null.
Parameter name: source
Above error comes in situation when you are querying the collection which is null.
For demonstration below code will result in such an exception.
Console.WriteLine("Hello World");
IEnumerable<int> list = null;
list.Where(d => d ==4).FirstOrDefault();
Here is the output of the above code.
Hello World
Run-time exception (line 11): Value cannot be null.
Parameter name: source
Stack Trace:
[System.ArgumentNullException: Value cannot be null.
Parameter name: source] at Program.Main(): line 11
In your case ListMetadataKor is null.
Here is the fiddle if you want to play around.
When you call a Linq statement like this:
// x = new List<string>();
var count = x.Count(s => s.StartsWith("x"));
You are actually using an extension method in the System.Linq namespace, so what the compiler translates this into is:
var count = Enumerable.Count(x, s => s.StartsWith("x"));
So the error you are getting above is because the first parameter, source (which would be x in the sample above) is null.
System.ArgumentNullException: Value cannot be null. Parameter name:
value
This error message is not very helpful!
You can get this error in many different ways. The error may not always be with the parameter name: value. It could be whatever parameter name is being passed into a function.
As a generic way to solve this, look at the stack trace or call stack:
Test method GetApiModel threw exception:
System.ArgumentNullException: Value cannot be null.
Parameter name: value
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
You can see that the parameter name value is the first parameter for DeserializeObject. This lead me to check my AutoMapper mapping where we are deserializing a JSON string. That string is null in my database.
You can change the code to check for null.
my problem was with spelling It was case sensitive! Few of the columns were sorting properly and rest were throwing this error!

Postsharp get intercepted method return type

How can I get the return type of the intercepted method? I am writing a method level caching mechanism and I want to use postsharp to intercept the method calls. However,I need to be able to cast my stored object to the original method type.
public override void OnEntry(MethodExecutionArgs InterceptedItem)
{
if (_instance==null)
_instance = new CouchbaseClient();
string Key = GetCacheKey(InterceptedItem);
var CacheItem = _instance.Get(Key);
if (CacheItem != null)
{
// The value was found in cache. Don't execute the method. Return immediately.
//string StringType = (String)_instance.Get(Key+"Type");
JavaScriptSerializer jss = new JavaScriptSerializer();
InterceptedItem.ReturnValue = jss.Deserialize<Object>(CacheItem.ToString());
//Type Type = Type.GetType(StringType);
InterceptedItem.ReturnValue = (Object)InterceptedItem.ReturnValue;
// jss.Deserialize(CacheItem.ToString(), Type.GetType(StringType));
InterceptedItem.FlowBehavior = FlowBehavior.Return;
}
else
{
// The value was NOT found in cache. Continue with method execution, but store
// the cache key so that we don't have to compute it in OnSuccess.
InterceptedItem.MethodExecutionTag = Key;
}
}
Instead of using
InterceptedItem.ReturnValue = jss.Deserialize<Object>(CacheItem.ToString());
You could use the following code that allows to specify the type of the object at runtime (a generic type argument is determined at design time):
var mthInfo = InterceptedItem.Method as MethodInfo;
if (mthInfo != null)
InterceptedItem.ReturnValue = jss.Deserialize(CacheItem.ToString(), mthInfo.ReturnType);
else
InterceptedItem.ReturnValue = null;
You can retrieve a MethodBase object using the Method property of MethodExecutionArgs. However, as MethodBase is also used for methods without a return type (e.g. in case of a ConstructorInfo) you need to cast it to a MethodInfo in order to be able to access the return type.

Categories

Resources