Symptom:
You see the following log appear in your application log, sometimes it has CAPI2 or other stuff in there.
Failed extract of third-party root list from auto update cab at: (http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab) with error: A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file.
Fix:
Please head straight to Microsoft KB
http://support.microsoft.com/kb/2328240
It has a "Fix It" installer to assist the fix of this issue.
Answers to Software Questions the Experts Would Not Answer. Microsoft.NET, Java, Spring, Hibernate, JavaScript, C#, SQL Server as well as Mac, Solaris, Linux, CISCO IOS and related now include some Automotive IT! You could be having the same problem for hours like me!
Thursday, November 28, 2013
Sunday, October 27, 2013
Fix for ffmpeg Resulting Movie is Flipped Vertically or Horizontally
Symptom:
I had to assemble a movie clip using ffmpeg from individual JPEG frames. In my situation I wanted to make both .ogg and .mp4 medical cine clips that can be shown directly on HTML5 web browsers.
The movie makes fine but the only issue is that the movie images are all vertically flipped.
I still do not know why the images are encoded flipped since when I view individual image using Windows Preview or other JPEG viewers, I do not get the orientation issue. It is likely though these have missing Exif header which does have orientation information that's usually supplied from cameras.
At any rate, this can actually be corrected easily.
Fix:
ffmpeg contains filters and you can do a very complex filter operations. One of the operations is flipping.
By supplying
-vf "hflip"
I can horizontally flip all frames in the movie.
-vf "vflip" does the vertical flip
and
-vf "hflip, vflip" can do both.
I had to assemble a movie clip using ffmpeg from individual JPEG frames. In my situation I wanted to make both .ogg and .mp4 medical cine clips that can be shown directly on HTML5 web browsers.
The movie makes fine but the only issue is that the movie images are all vertically flipped.
I still do not know why the images are encoded flipped since when I view individual image using Windows Preview or other JPEG viewers, I do not get the orientation issue. It is likely though these have missing Exif header which does have orientation information that's usually supplied from cameras.
At any rate, this can actually be corrected easily.
Fix:
ffmpeg contains filters and you can do a very complex filter operations. One of the operations is flipping.
By supplying
-vf "hflip"
I can horizontally flip all frames in the movie.
-vf "vflip" does the vertical flip
and
-vf "hflip, vflip" can do both.
Thursday, August 22, 2013
LINQDataSource Fix: No applicable method 'StartsWith' exists in type 'String' OR No applicable method 'Contains' exists
Symptom:
No applicable method 'Contains' exists in type 'String'
Root Cause:
Many people are very confused about this behavior and come to the conclusion to execute some special LINQ call. Apparently it has nothing to do with missing procedure but it's just the Text or control fields set up not correctly.
This is because the Control's ConvertEmptyStringToNull (for example TextBox) property needs to be adjusted from true to false. Without it, when nothing is typed into the field, it will go out as a null object and then it cannot find the method.
Please note that it appears that this change has to be made to all of the fields in the query.
Fix:
Then, you will find where to change ConvertEmptyStringToNull configuration.
Or, you can edit the configuration straight in the page's source like this;
- You have created a LinqDataSoruce control on the Visual Studio ASP.NET web page.
- You have set up fields to be supplied from TextBox control (may be others.)
- You have customized the query to use StartsWith or Contains in the Query and the following type of puzzling error appears.
No applicable method 'Contains' exists in type 'String'
Root Cause:
Many people are very confused about this behavior and come to the conclusion to execute some special LINQ call. Apparently it has nothing to do with missing procedure but it's just the Text or control fields set up not correctly.
This is because the Control's ConvertEmptyStringToNull (for example TextBox) property needs to be adjusted from true to false. Without it, when nothing is typed into the field, it will go out as a null object and then it cannot find the method.
Please note that it appears that this change has to be made to all of the fields in the query.
Fix:
- In your LinqDataSource "Where.." editor dialog box, select the (TextBox control(s)).
- Next find "Show Advanced Properties" link. Click this.
Then, you will find where to change ConvertEmptyStringToNull configuration.
Or, you can edit the configuration straight in the page's source like this;
LinqToSQL: How To do a equivalent of Like '%' "Match Everything"
Question:
How can I do a equivalent of LIKE '%' in SQL with LinqToSql?
Answer:
Simply pass an empty string "" to Contains function.
For example,
var patients = from p in ctx.Patients where PatientsName.Contains("");
How can I do a equivalent of LIKE '%' in SQL with LinqToSql?
Answer:
Simply pass an empty string "" to Contains function.
For example,
var patients = from p in ctx.Patients where PatientsName.Contains("");
Thursday, July 18, 2013
IIS 7 Page Caching May Cause Your Dynamic Page Not To Execute
I just ran into an interesting situation, which a dynamic page did not update at all even though the web call succeeded. This really puzzled us for a bit of time this afternoon, fortunately I realized what was actually happening and solved the problem. The point of this article is that if you did not have any idea what is happening under the hood, it would have puzzled you even the longest time and even make you go down the wrong path.
So, first what I was trying to do.
I wrote a very simple ASP.NET REST type application to log errors and such and the logging message came only in the URL. I tested it and worked fine.
What has happened though is that once it was put in production my colleague has noted that if the identical log message was sent repeatedly and subsequently, it stopped logging the second message and the later ones.
The program is really simple, it just parsed the URL and anything after ?m= parameter it logged that information to an SQL database along with the time the request came in. For example ?m="Process X called"
The root cause of this was that if a same message was sent then the URL would have been identical the second time. Now IIS caching mechanism thinks that since this is the same URL, it would not execute the actual ASP.NET program, but just show the page that was already generated. So in effect it did not log subsequent messages. Initially we though the SQL server has some mechanism that would prevent the same message from being logged, though that' would be totally absurd.
Then I thought that this must be due to some sort of cache optimization on the server side.
Sure enough, we have confirmed that this is actually the case, as unique messages do log, and since as soon as we added ?t= in the URL in which a sequence number incremented and then every message logged OK.
Now I have confirmed that the Server Side Page Caching is a feature in IIS and that it can be controlled in many ways. This behavior is also enabled by default.
Knowing this behavior exists will help you understand why some page update do not happen as you expect. This is especially true for dynamically generated pages.
For further information on this topic, searching for IIS Cache on your favorite search engine or on the MSDN web site.
So, first what I was trying to do.
I wrote a very simple ASP.NET REST type application to log errors and such and the logging message came only in the URL. I tested it and worked fine.
What has happened though is that once it was put in production my colleague has noted that if the identical log message was sent repeatedly and subsequently, it stopped logging the second message and the later ones.
The program is really simple, it just parsed the URL and anything after ?m= parameter it logged that information to an SQL database along with the time the request came in. For example ?m="Process X called"
The root cause of this was that if a same message was sent then the URL would have been identical the second time. Now IIS caching mechanism thinks that since this is the same URL, it would not execute the actual ASP.NET program, but just show the page that was already generated. So in effect it did not log subsequent messages. Initially we though the SQL server has some mechanism that would prevent the same message from being logged, though that' would be totally absurd.
Then I thought that this must be due to some sort of cache optimization on the server side.
Sure enough, we have confirmed that this is actually the case, as unique messages do log, and since as soon as we added ?t=
Now I have confirmed that the Server Side Page Caching is a feature in IIS and that it can be controlled in many ways. This behavior is also enabled by default.
Knowing this behavior exists will help you understand why some page update do not happen as you expect. This is especially true for dynamically generated pages.
For further information on this topic, searching for IIS Cache on your favorite search engine or on the MSDN web site.
Wednesday, June 12, 2013
Windows Visual Studio WebControl Under IE 7 Emulation Does Not Load JSON
Symptom:
Under the IE7 emulation mode of the Visual Studio WebControl, JSON does not load. You receive 'JSON' is undefined error.
Root Cause:
JSON is not natively supported in IE7.
Workaround:
You can include JSON2 from https://github.com/douglascrockford/JSON-js/blob/master/json2.js in your script set and this will make JSON to work.
Under the IE7 emulation mode of the Visual Studio WebControl, JSON does not load. You receive 'JSON' is undefined error.
Root Cause:
JSON is not natively supported in IE7.
Workaround:
You can include JSON2 from https://github.com/douglascrockford/JSON-js/blob/master/json2.js in your script set and this will make JSON to work.
Windows Visual Studio WebControl Does Not Load the Latest JavaScript Version
Symptom
You have enabled the JavaScript capability on the WebControl using my previous artcile (read now). However, the JavaScript version stays with, for example, version 13 instead of version 17, that's standard on IE 9.
Root Cause
This appears to be due to some extra stuff in !DOCTYPE attribute of a page. By default Visual Studio 2010 new Web Forms page will add the following
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
It is most likely that xhtml1-transitional.dtd is affecting the browser behavior but I am not going to verify that (you can.)
Fix
If you keep the !DOCTYPE only to just to say , in other words remove the rest of the junk in the DOCTYPE, then the JavaScript version will go up to the latest version.
The HTML5 standard requires that the DOCTYPE to only have html as its attribute.
You have enabled the JavaScript capability on the WebControl using my previous artcile (read now). However, the JavaScript version stays with, for example, version 13 instead of version 17, that's standard on IE 9.
Root Cause
This appears to be due to some extra stuff in !DOCTYPE attribute of a page. By default Visual Studio 2010 new Web Forms page will add the following
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
It is most likely that xhtml1-transitional.dtd is affecting the browser behavior but I am not going to verify that (you can.)
Fix
If you keep the !DOCTYPE only to just to say , in other words remove the rest of the junk in the DOCTYPE, then the JavaScript version will go up to the latest version.
The HTML5 standard requires that the DOCTYPE to only have html as its attribute.
Tuesday, June 11, 2013
Windows VisualStuduio WebBrowser Control Does Not Run JavaScript
Symptom:
You have dragged in the Web Browser Control into your Windows desktop application. Then you tried to open a page that contains JavaScript. You immediately get messages like "JSON" not found, or other sorts of script error.
You have already checked to see if JavaScript. Enable property is available but there is not that you can see.
Root Cause:
Please know the following facts;
You have dragged in the Web Browser Control into your Windows desktop application. Then you tried to open a page that contains JavaScript. You immediately get messages like "JSON" not found, or other sorts of script error.
You have already checked to see if JavaScript. Enable property is available but there is not that you can see.
Root Cause:
Please know the following facts;
- By default the WebBrowser control does not support JavaScript, and also it runs in IE 7 compatibility mode.
- The WebBrowser control is nothing but the same version if IE running on your desktop. So if your system only has the IE 8 then it will only run up to the feature of IE 8.
- It is not true that you change the your IE's security mode the Javascript will run. Reason for this is that the security model is tied to the name of the program set up in the registry. The same settings actually control iexplore.exe as well.
- If you are running a program via Visual Studio in debugging mode, the name of the program is different from the EXE that it produces.
- Because the program name changes depending on how you are running it, I suggest that you automate the program name detection using the following code snippet.
The following code snippet allows you to configure the registry settings so that the web browser control will assume a proper IE mode of operation. This is by default set to IE 7.0 without JavaScript. The following example sets the IE to IE 9 emulation mode and also detects a program name you are running as.
using Microsoft.Win32; // DO NOT FORGET TO INCLUDE THIS ON TOP OF YOUR PROGRAM
private static void SetIE9Feature()
{
try
{
UInt32 FeatureCode = 9000; // for IE9, use 8000 for IE8 and 7000 for IE7 etc.
var asm = System.Reflection.Assembly.GetExecutingAssembly();
var rootKey = Registry.LocalMachine;
var sk = rootKey.OpenSubKey(@"SOFTWARE", true);
var mk = sk.OpenSubKey(@"Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BEHAVIORS", true);
if (mk != null)
{
var p = System.AppDomain.CurrentDomain.FriendlyName;
mk.SetValue(p, FeatureCode, RegistryValueKind.DWord);
}
var mk2 = sk.OpenSubKey(@"Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
true);
if (mk2 != null)
{
var p = System.AppDomain.CurrentDomain.FriendlyName;
mk2.SetValue(p, FeatureCode, RegistryValueKind.DWord);
}
var m = String.Format(@"Great! Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BEHAVIORS and " +
"FEATURE_BROWSER_EMULATION modes went OK to mode {0}. Please restart the " +
" application for this to take effect.",
FeatureCode);
MessageBox.Show(m);
}
catch(Exception ex)
{
var m = String.Format(@"Sorry, it's a NO GO for setting Microsoft\Internet " +
"Explorer\Main\FeatureControl\FEATURE_BEHAVIORS and FEATURE_BROWSER_EMULATION modes. "+
"Did you run as Administrator? {0}",
ex.ToString());
MessageBox.Show(m);
}
}
Thursday, May 09, 2013
Getting a Single Value Out of XMLElement.InnerText
Symptom:
Suppose you have the following XML (and succesfully navigated down to the first element in the line below using something like Eelement.Select(@"//element"); etc.
<element>a <element>b </element> </element>If your mind is like mine, you probably thought that
- Element.Value would give you "a". Element.Value actually won't give you anything.
- Element.InnerText would give you "a". That is not true either, it will give you "ab" since it returns all of the text of the children.
How do you extract the string "a" out of this.
First off the answer (2) is more correct one. But we forget that everything in XML are linked nodes. Therefore the Text part which comprises of "a" is technically a child node of the first element.
Tuesday, April 30, 2013
MacOS - Why It Has Became So Non-Intuitive
So I was one of the earliest people to own Apple ][ and anything they made afterwards including the Newton. I have been and I am a big fan of Apple products. But lately, I am getting to start to think, it is no longer not as intuitive as I thought it should be.
Case in point.
How can you quickly change the audio input and output.
The typical Apple Support Forum answer that, if you post it, would be that it should either be too ovbious to you, or another good one is "why would you want to do that?"
Well it so happens that in my setup, there are many input devices that are connected to my Mac. Sometimes I want input from my musical instruments and sometimes I want to input from my headset with a mic for conference calls. Sometimes I want the output to go to my stuido monitors and sometimes I want to listen to the audio with my headphones or any combinations thereof.
On Windows, things have become more consistent lately. Whatever extra stuff I need to do, just click the right mouse button.
Well, on my Mac, a click the right mouse button (and yes I am using the Magic Pad by using two-finger gesture) on top of the volume control on the menu bar does nothing.
Instead, I had to remember to Option then click. And it requires some searching to find this out. Problematically there is nothing that interfere with right-mouse click on the audio icon on the menu bar.
So why on the Finder option click does not provide a menu?
On Windows, if you right click the "speaker" icon on the taskbar tray, it comes up with various options for audio along with "Properties" in which you can do more stuff. I feel that on Windows it has became much more consistent over the years.
I am willing to bet that if Microsoft had said that you would need to press the ALT key to get to these audio options, I know Apple fans would make a good fun out of it. And that's exactly the situation going with the Mac OS.
Apple fans, please make more demand out of them to keep it the systems most intuitive system rather than just be in so much love with it and stop protecting it just as soon as someone post anything a bit negative about its products. Things are changing rapidly and I do not want to go back to the Emilio days again.
Case in point.
How can you quickly change the audio input and output.
The typical Apple Support Forum answer that, if you post it, would be that it should either be too ovbious to you, or another good one is "why would you want to do that?"
Well it so happens that in my setup, there are many input devices that are connected to my Mac. Sometimes I want input from my musical instruments and sometimes I want to input from my headset with a mic for conference calls. Sometimes I want the output to go to my stuido monitors and sometimes I want to listen to the audio with my headphones or any combinations thereof.
On Windows, things have become more consistent lately. Whatever extra stuff I need to do, just click the right mouse button.
Well, on my Mac, a click the right mouse button (and yes I am using the Magic Pad by using two-finger gesture) on top of the volume control on the menu bar does nothing.
Instead, I had to remember to Option then click. And it requires some searching to find this out. Problematically there is nothing that interfere with right-mouse click on the audio icon on the menu bar.
So why on the Finder option click does not provide a menu?
On Windows, if you right click the "speaker" icon on the taskbar tray, it comes up with various options for audio along with "Properties" in which you can do more stuff. I feel that on Windows it has became much more consistent over the years.
I am willing to bet that if Microsoft had said that you would need to press the ALT key to get to these audio options, I know Apple fans would make a good fun out of it. And that's exactly the situation going with the Mac OS.
Apple fans, please make more demand out of them to keep it the systems most intuitive system rather than just be in so much love with it and stop protecting it just as soon as someone post anything a bit negative about its products. Things are changing rapidly and I do not want to go back to the Emilio days again.
Thursday, March 28, 2013
jQuery Ajax POST to REST WCF Returns a Bad (Status 400) Request
Problem,
I recently have started to implement a RESTful interface using the WCF in ASP.NET. The advantage of using the WCF is that on the C# side (can be a VB or even F#), the coding can be done in C# without much worries, and we can take advantage of the built-in (de)serialization in JSON format, which is very common dealing with JavaScript.
In my situation, the client side is a JQuery running in a standard web browser. And that's where the problem begun.
A "GET" method worked quite easily, but the POST method did not work initially, and it is a rather complex issue especially with Web.Config endpoint behaviors and such.
Some Points to Check
First, most examples on the web, including the ones in the JQuery document pages, are not always correct for encoding a JSON data. The following example is the correct one that worked. All I needed was a pair of single quote surrounding the JSON data itself, and that was the key.
var p = '{ "c" : "Hello", "dt" : "2013-03-27" }';
Above structure reflects this in C#
[DataContract (Name="PostEchoData")]
public class PostEchoData
{
[DataMember (Name="c")]
public string c
{
get;
set;
}
[DataMember (Name="dt")]
public string dt
{
get;
set;
}
Second, it looks like you need to use the $.ajax interface, instead of $.post because WCF side needs the content type of application/json and charset of utf-8 and decides to de-serialize the data. Without this information you will very likely get the Error status 400. So it is essential that JSON ContentType must be specified when uploading the POST data.
You can use the following calling framework when POSTing a JSON object to WCF from your JavaScript.
Since the $.post does not (seem to) allow the explicit contentType specification, this is the reason you need to go to $.ajax call.
var x = $.ajax(
{
type: "POST",
contentType: "application/json; charset=utf-8",
url: url,
data: p,
dataType: "json",
success: asuccess
} );
Finally, there are many things you need to modify your Web.Config but there are a lot of posts about this on StackOverflow or places of that nature so I will let you figure that out.
These are probably very novice errors, nevertheless, there are a lot of posts on this on the network, so I am sure this information will help someone down the line.
P.S.: It's JSON and not JaSON!
Note: I have recently found out that you can do this much easier with the Microsoft Web API framework. This is a configuration hell and I will not recommend it.
I recently have started to implement a RESTful interface using the WCF in ASP.NET. The advantage of using the WCF is that on the C# side (can be a VB or even F#), the coding can be done in C# without much worries, and we can take advantage of the built-in (de)serialization in JSON format, which is very common dealing with JavaScript.
In my situation, the client side is a JQuery running in a standard web browser. And that's where the problem begun.
A "GET" method worked quite easily, but the POST method did not work initially, and it is a rather complex issue especially with Web.Config endpoint behaviors and such.
Some Points to Check
First, most examples on the web, including the ones in the JQuery document pages, are not always correct for encoding a JSON data. The following example is the correct one that worked. All I needed was a pair of single quote surrounding the JSON data itself, and that was the key.
var p = '{ "c" : "Hello", "dt" : "2013-03-27" }';
Above structure reflects this in C#
[DataContract (Name="PostEchoData")]
public class PostEchoData
{
[DataMember (Name="c")]
public string c
{
get;
set;
}
[DataMember (Name="dt")]
public string dt
{
get;
set;
}
Second, it looks like you need to use the $.ajax interface, instead of $.post because WCF side needs the content type of application/json and charset of utf-8 and decides to de-serialize the data. Without this information you will very likely get the Error status 400. So it is essential that JSON ContentType must be specified when uploading the POST data.
You can use the following calling framework when POSTing a JSON object to WCF from your JavaScript.
Since the $.post does not (seem to) allow the explicit contentType specification, this is the reason you need to go to $.ajax call.
var x = $.ajax(
{
type: "POST",
contentType: "application/json; charset=utf-8",
url: url,
data: p,
dataType: "json",
success: asuccess
} );
Finally, there are many things you need to modify your Web.Config but there are a lot of posts about this on StackOverflow or places of that nature so I will let you figure that out.
These are probably very novice errors, nevertheless, there are a lot of posts on this on the network, so I am sure this information will help someone down the line.
P.S.: It's JSON and not JaSON!
Wednesday, March 13, 2013
LinqDataSource Bound Grid View and RowDataBound Handling
Scenario
You have bound a LinqDataSource to DataGridView.
Now you want to dynamically modify the contents of grids using RawDataBound event based on the row data, for example flag a field as RED when there is an overdue account, but you do not know how to get to the data contained in Row.DataItem
You will quickly find that DataItem is a member of DynamicClass for which there is no public property to methods to get to the data. You will also find that your debugger can display the information, and it just a row from a LINQ select statement.
Solution
A very small amount of Reflection is needed to do this work. Suppose that you had a column in the table in the LinqDataSource with the name of "CustomerGuidKey". Here is how to get at it.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
var item = e.Row.DataItem;
if (item == null) return;
var t = item.GetType();
PropertyInfo p = t.GetProperty("CustomerGuidKey");
var v = (Guid) p.GetValue(item, null);
.....
Be sure to include the namespace "System.Reflection" in your code.
You have bound a LinqDataSource to DataGridView.
Now you want to dynamically modify the contents of grids using RawDataBound event based on the row data, for example flag a field as RED when there is an overdue account, but you do not know how to get to the data contained in Row.DataItem
You will quickly find that DataItem is a member of DynamicClass for which there is no public property to methods to get to the data. You will also find that your debugger can display the information, and it just a row from a LINQ select statement.
Solution
A very small amount of Reflection is needed to do this work. Suppose that you had a column in the table in the LinqDataSource with the name of "CustomerGuidKey". Here is how to get at it.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
var item = e.Row.DataItem;
if (item == null) return;
var t = item.GetType();
PropertyInfo p = t.GetProperty("CustomerGuidKey");
var v = (Guid) p.GetValue(item, null);
.....
Be sure to include the namespace "System.Reflection" in your code.
Wednesday, January 30, 2013
Visual Studio Debugger Slow To Start Up Due To Symbol Loads
Symptom:
Suddenly when you are debugging your application the application startup on your Visual Studio begins to crawl down to 20-30 seconds or even longer, as it starts loading symbols from all over the places for Microsoft's .NET Framework library and GACs etc.
Possible (But May Not Be Exact) Cause:
You or someone in the team have accidentally enabled Symbol loading from All Modules.
Try If Above Applies
Try this to see if it makes any difference.
On your Visual Studio, go to Debug and then Select Option and Settings...
On the left panel go down to where it says Symbols under the Debug section.
Select "Only Specified Modules" and you do not need to specify any modules at all if you are only interested in debugging modules that are in your own project.
Suddenly when you are debugging your application the application startup on your Visual Studio begins to crawl down to 20-30 seconds or even longer, as it starts loading symbols from all over the places for Microsoft's .NET Framework library and GACs etc.
Possible (But May Not Be Exact) Cause:
You or someone in the team have accidentally enabled Symbol loading from All Modules.
Try If Above Applies
Try this to see if it makes any difference.
On your Visual Studio, go to Debug and then Select Option and Settings...
On the left panel go down to where it says Symbols under the Debug section.
Select "Only Specified Modules" and you do not need to specify any modules at all if you are only interested in debugging modules that are in your own project.
Saturday, January 05, 2013
Dynamically Extracting SQL Fields in LinqToSQL Data Object
Problem:
I had a situation in which I get a SQL record using LinqToSQL then dynamically extract a value continued in the returned record by the field name. For example, suppose you have a SQL Table that contains columns like "Description" or "Indication" and the caller would want to know what's contained in these field individually, also dynamically (so that in the future if a column is added, the code do not need to change.)
If you look at these database record objects that LinqToSQL generates, there is no "by-name" functions.
Solution:
As it turns out you can essentially "parse" break-down a C# object descriptions into arrays called MethodInfo and FieldInfo using System.Reflection. Once we know this the rest of of the idea is easy; just find the matching method or field names the user requests and dynamically access either the fields or methods.
In LinqToSQL database "row" class objects, the column values are implemented as {get; set; } methods, so instead of extracting the FieldInfo, you need to extract MethodInfo for the column field, and you get two methods get_ and set_. So if my Study table contains Description then the method to get the Description value in the column is _get_Description.
My code example below returns the value contained in the field. In order to make it easier for the user, I make the field name matching to be non-case sensitive by ToLower() the names.
I had a situation in which I get a SQL record using LinqToSQL then dynamically extract a value continued in the returned record by the field name. For example, suppose you have a SQL Table that contains columns like "Description" or "Indication" and the caller would want to know what's contained in these field individually, also dynamically (so that in the future if a column is added, the code do not need to change.)
If you look at these database record objects that LinqToSQL generates, there is no "by-name" functions.
Solution:
As it turns out you can essentially "parse" break-down a C# object descriptions into arrays called MethodInfo and FieldInfo using System.Reflection. Once we know this the rest of of the idea is easy; just find the matching method or field names the user requests and dynamically access either the fields or methods.
In LinqToSQL database "row" class objects, the column values are implemented as {get; set; } methods, so instead of extracting the FieldInfo, you need to extract MethodInfo for the column field, and you get two methods get_ and set_. So if my Study table contains Description then the method to get the Description value in the column is _get_Description.
My code example below returns the value contained in the field. In order to make it easier for the user, I make the field name matching to be non-case sensitive by ToLower() the names.
private string FindStudyField(string Field, Guid? StudyGuidKey) { if (StudyGuidKey == null) return ""; using (var ctx = MyLINQtoSQL.ContextFactory.NewMyDataConext()) { var studies = from s in ctx.Studies orderby s.StudyDateTime descending where s.StudyGuidKey == StudyGuidKey select s; if (studies.Count() == 0) return ""; /* * The following piece of code uses Reflection to get values "dynamically" * out of a LINQ data row object. In this case a Study record from a study table. * LINQ values are implemented as {get; set;} methods, so we will need to * get them out as methods. This means that the field name needs to be * appended with a 'get_' to derive the proper method name that corresponds * with the SQL field name. * */ Field = "get_" + Field.Trim().ToLower(); try { Study study = studies.First(); Type studyType = typeof(Study); MethodInfo[] studyFields = studyType.GetMethods(BindingFlags.Public | BindingFlags.Instance); for (int i = 0; i < studyFields.Length; i++) { var fn = studyFields[i].Name.ToLower(); if (fn != Field) continue; var v = studyFields[i].Invoke(study, null).ToString(); return ""; } } catch (Exception ex) { return ""; } } return ""; }
Subscribe to:
Posts (Atom)