|
|
I've got an application up and running, using remoting.
Things generally seem to work, but there seem to be problems with returning ArrayLists from the remote object.
I have some small helper classes to use in passing around data, and if I add any of these to an ArrayList, and then try to return the ArrayList, I get a RemotingException on the client side. Returning an empty ArrayList, or one that contains only .NET builtin types works though.
Is there something special I need to do to allow classes I've defined to be returned in the ArrayList?
|
|
|
|
|
Your class has to be attributed Serializable, just like if you were going to serialize it to an XML file.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
Brilliant, thanks. A few little [Serializable] tags, and everything works now.
|
|
|
|
|
Greetings!
I'm trying to connect to a database and read certain fields from it. I'm unable to read any fields from it and would appreciate your help debugging/fixing the problem.
Here is what I have:
1. A file that acts has the database interface code:
<br />
public class AppDatabaseInterface<br />
{<br />
<br />
private string m_cstrDefaultdbDir = "C:\\";<br />
<br />
private const string m_cstrDBFileName = "DefaultDatabase.mdb";<br />
<br />
private System.Data.OleDb.OleDbConnection m_dbConn;<br />
<br />
public AppDatabaseInterface()<br />
{<br />
System.Reflection.Assembly assm =<br />
System.Reflection.Assembly.GetAssembly(System.Type.GetType("AppDatabase.AppDatabaseInterface"));<br />
m_cstrDefaultdbDir = System.IO.Path.GetDirectoryName(assm.CodeBase.ToString());<br />
m_cstrDefaultdbDir = m_cstrDefaultdbDir.Remove(0, 6);
<br />
OpenDatabase();<br />
}<br />
<br />
<br />
private void OpenDatabase()<br />
{<br />
lock (this)<br />
{<br />
if (m_dbConn == null)<br />
{<br />
m_dbConn = new OleDbConnection();<br />
}<br />
else<br />
{<br />
if (m_dbConn.State != ConnectionState.Closed)<br />
{<br />
m_dbConn.Close();<br />
}<br />
}<br />
<br />
try<br />
{<br />
m_dbConn.ConnectionString = string.Format(<br />
@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}\{1};",<br />
m_cstrDefaultdbDir, m_cstrDBFileName);<br />
}<br />
catch<br />
{<br />
Console.WriteLine("Could not open database");<br />
}<br />
m_dbConn.Open();<br />
<br />
}<br />
}<br />
2. The actual UI form
<br />
public partial class frmAppDatabase: Form<br />
{<br />
AppDatabaseInterface m_database;<br />
<br />
public frmSpeakerDatabase()<br />
{<br />
InitializeComponent();<br />
<br />
m_database = new AppDatabaseInterface();<br />
<br />
string[] strSpeakerMakes = m_database.Makes;<br />
<br />
for (int i = 0; i < strSpeakerMakes.Length; i++)<br />
{<br />
cbSpeakerMakes.Items.Add(strSpeakerMakes[i]);<br />
}<br />
}<br />
What I want this portion of the code to do is to fill in the combobox with the various items from the specified field in the database. However, I see nothing.
The Access file is in the \bin\debug directory of the project.
Could you please advice me as to what is wrong?
Thanks!
|
|
|
|
|
TheBlindWatchmaker wrote: However, I see nothing.
You see nothing? Not even the error message?
You are trying to use the property "Makes", but you have not created any property with that name. What do you expect to happen?
---
b { font-weight: normal; }
|
|
|
|
|
Oops! My mistake!
Here's the "Makes" method in the AppDatabaseInterface.cs file
<br />
public string[] Models(string make)<br />
{<br />
{<br />
OleDbDataReader dbr = null;<br />
ArrayList Models = new ArrayList();<br />
<br />
OleDbCommand cmd = new OleDbCommand(string.Format("SELECT * FROM {0};", "Speakers"), m_dbConn);<br />
dbr = cmd.ExecuteReader();<br />
<br />
while (dbr.Read())<br />
{<br />
<br />
string dbMake = "";<br />
string model= "";<br />
for (int it = 0; it < dbr.FieldCount; it++)<br />
{<br />
string strField = dbr.GetName(it);<br />
if (strField == "MAKE")<br />
{<br />
dbMake = (string)dbr.GetValue(it);<br />
}<br />
if (strField == "MODEL")<br />
{<br />
model = (string)dbr.GetValue(it);<br />
}<br />
}<br />
if (dbMake == make)<br />
Models.Add(model);<br />
<br />
}<br />
string[] strModels = new string[Models.Count];<br />
int i = 0;<br />
foreach (object o in Models)<br />
{<br />
strModels[i++] = (string)o;<br />
}<br />
return strModels;<br />
}<br />
}<br />
Thanks!
|
|
|
|
|
TheBlindWatchmaker wrote: Here's the "Makes" method in the AppDatabaseInterface.cs file
No, it isn't.
---
b { font-weight: normal; }
|
|
|
|
|
Damnit! I'm really inept today! Apologies, apologies!
This might be it!
<br />
public string[] Makes<br />
{<br />
get<br />
{<br />
OleDbDataReader dbr = null;<br />
ArrayList Makes = new ArrayList();<br />
<br />
OleDbCommand cmd = new OleDbCommand(string.Format("SELECT * FROM {0};", "Speakers"), m_dbConn);<br />
dbr = cmd.ExecuteReader();<br />
<br />
while (dbr.Read())<br />
{<br />
for (int it = 0; it < dbr.FieldCount; it++)<br />
{<br />
string strField = dbr.GetName(it);<br />
if (strField == "MAKE")<br />
{<br />
string make = (string)dbr.GetValue(it);<br />
bool found = false;<br />
foreach (object o in Makes)<br />
{<br />
if ((string)o == make)<br />
{<br />
found = true;<br />
break;<br />
}<br />
}<br />
if (found)<br />
Makes.Add(make);<br />
break;<br />
}<br />
<br />
}<br />
<br />
}<br />
string[] strMakes = new string[Makes.Count];<br />
int i= 0;<br />
foreach (object o in Makes)<br />
{<br />
strMakes[i++] = (string)o;<br />
}<br />
return strMakes;<br />
}<br />
}<br />
|
|
|
|
|
I see. The method does exactly what it should, and returns an empty array.
You only add to the ArrayList duplicates of values that already exist in the list, but as you start with an empty list, there are never any duplicates, so it will always remain empty.
I guess that your intention was to add the values that aren't duplicates?
In that case, why don't you just get the unique values from the database in the first place? And if you specify what field you want instead of using "select *", you don't have to loop through the fields looking for the one you want.
---
b { font-weight: normal; }
|
|
|
|
|
Hi Guffa,
The Makes field has, say, 10 speakers from Mfr1, 10 from Mfr2 etc. I want the combo box to show Mfr1, Mfr2 and so on.
How would you suggest I do this?
Thanks for your time!
|
|
|
|
|
Select only the field containing the data that you want, and use the distinct keyword to get only one of each value.
---
b { font-weight: normal; }
|
|
|
|
|
Hi,
I'm trying to write as a small project a custom file explorer in C# however I've hit a rather annoying problem... When a file is > 260 characters long (yeah, I know people shouldn't have files that long, but they do) it'll throw the PathTooLongException fine, but what do you do next?
I was hoping I'd be able to catch that exception and at the same time still get the file size and other information I need to display but no such luck.
Is there any work-around's to fix this, or would the only acceptable solution be to write a custom library that properly wraps the Win32 API functions which are able to get the sizes/other information of > 260 char files? If so does anyone know an open-source library already made to do this, or will I need to make one?
Thanks!
|
|
|
|
|
I'm able to set unsafe mode in a console application by checking the checkbox in "Project Properties -> Build -> Allow unsafe code" however that option isn't available in a web service project.
So how can I set a web service project to unsafe mode?
Thanks.
-Goalie35
|
|
|
|
|
Is there a simple way to parse a string that contains escape character to the appropriate string, and vise versa?
For example, given the following string:
"hello\tthere"
should be parsed to:
"hello there"
and vs.
I need these methods because i let the user to enter escape chracters within the strings.
Thnaks!
|
|
|
|
|
*simple* solution....as you asked. If you know every one of your escape characters (say you only use 2 for illustrative purposes... '/t' and '/n') you can add each one of them to a string array. Then whenever you need to parse your input string, call inputString.Split(delimiterList) where delimiterList is your array of characters. That parses your text as you requested, but I don't think you really want what you asked. ...If you allow users to insert escape characters, why would you want to eliminate them whenever you parse the input string? I think what you are actually asking is for an algorithm to perform character substitution for a particular escape sequence. Am I right?
|
|
|
|
|
Escape characters are in your text when you enter the constant, but in the string itself, they become ( for example ) tabs and so on.
If you have a string which actually contains the \t, etc, then you need to use string.Replace to remove them, if that's what you need.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Please give a more illustrative example of what you are trying to accomplish. Are you saying that '\t' is supposed to represent a single whitespace character? In the original reply that I made, I assumed that 'hello' and 'there' were 2 seperate tokens created from parsing a string with a given delimiter. I think you really meant that you want to traverse the string and perform a character substitution based upon your defined escape sequences.
|
|
|
|
|
Hello
This is what you need:
string s1 = "hello\tthere".Replace("\\t", "\t");
string s2 = "hello\tthere".Replace("\t", "\\t");
Andriy Zhornyk, regards
|
|
|
|
|
The idea is to enable the user to enter string constants that contains escape character - eaxactly as we do when we edit our source code in VS.
For example, the user maybe enter the following text in some text box:
"Hello\there\nand\there. But \\this is a backslash and not a tab chracater"
So, when i get this string, .NET framework treats these sequences as is and not as escape character - this is the expected behavior.
If you add a breakpoint at the right point and watch this user input in the debugger you will see:
"Hello\\there\\nand\\there. But \\\\this is a backslash and not a tab chracater"
However, i was wondering if there is a simple way, that is method supplied by the framework that do the job of escape character substitution as well as the reverse job.
So when i get this string i do the following:
string result = SubstituteEscapes(userInput);
...and the result will contains the same string after the "\t" replaced by the tab character and the "\n" replaced by the new line character and the
"\\" will be replaced by a single "\".
and the reverse way should be:
string original = SubstituteSpecialCharacters(result);
...and the the tab, new line and backslash characters will be replaced with the appropriate escape sequences.
It is possible to search and replace those escapes even by using regualr expressions. But does the framework has a built in method for that?
Why?
You may ask your self why i need these methods?
Well i use a ProperttyGrid and ask the user what should be the seperator string between fields in the log file.
Beacause pressing tab move the focus to the next property in the grid, and also because copying and pasting tab is BAD solution to this problem, i want to give the user the possiblity to enter escapes.
Thanks, again!
|
|
|
|
|
Your users are sufficiently technical to understand the concept ?
So you actually want to parse for \t and replace it with a tab ? I imagine you need to use the string.Replace method to do this for all known special characters, including replacing \\ with \
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Well, they are.
However it seems up to this point that there is no such built in method, hence i am writing such method now.
The principle is a little more complicated than seraching and replacing, consider the \uxxxx unicode escapes, \xd[d][d][d] hexadecimal escapes (variable length up to 4 digits) etc.
At the moment i finish this method (soon) i post it.
|
|
|
|
|
First, thank you all for trying to help me, as i said, it seems that there is no built in method for escape sequences substitution.
Hence i set down and wrote the following method, hopefully with no bugs.
In the method i use scanning instead of serching and replacing as well as some bitwise operations in order to enhance performance.
The reverse method is much simpler to code.
Finally, here in Israel we celebrate a new year - so happy new year to you all.
Here is the method.
/// <summary>
/// Substitutes the escape characters in the specified string with their appropriate characters.
/// </summary>
/// <param name="str">The string.</param>
/// <returns>The string after the escape characters were replaced by the appropriate character.</returns>
/// <remarks>
/// If the method encounter invalid escape character, the backslash character is removed and
/// the character that comes right after it is copied with no change.
/// </remarks>
public static string SubstituteEscapes(string str)
{
StringBuilder sbResult = new StringBuilder();
bool bEscaped = false;
for(int i = 0; i < str.Length; i++)
{
char current = str[i];
if(bEscaped)
{
switch(current)
{
case '\'':
case '\"':
case '\\':
/* Merely append the current character. This is the default behavior */
sbResult.Append(current);
break;
case '0':
/* The '\0' (string terminator) character \u0000 */
sbResult.Append('\0');
break;
case 'a':
/* The bell (alarm) character \u0007*/
sbResult.Append('\a');
break;
case 'b':
/* The backspace character \u0008*/
sbResult.Append('\b');
break;
case 'f':
/* The form feed character \u000C*/
sbResult.Append('\f');
break;
case 'n':
/* The line feed character \u000A*/
sbResult.Append('\n');
break;
case 'r':
/* The carriage return character \u000D*/
sbResult.Append('\r');
break;
case 't':
/* The tab character \u0009*/
sbResult.Append('\t');
break;
case 'v':
/* The vertical tab character \u000B*/
sbResult.Append('\v');
break;
case 'u':
/* Unicode character (exactly four digits to read on) */
try
{
char ch = (char)int.Parse(str.Substring(i + 1, 4), NumberStyles.AllowHexSpecifier);
sbResult.Append(ch);
i += 4;
}
catch
{
sbResult.Append(current);
}
break;
case 'x':
/* hexadecimal (1 digit up to 4 digits to read on) */
int j = 0; /* cout how many digit were scanned */
int value = 0; /* hold the value */
do
{
try
{
int curr = int.Parse(str[i + j + 1].ToString(), NumberStyles.AllowHexSpecifier);
value = ((value << 4) | curr);
j++;
}
catch
{
break;
}
} while(j < 4);
if(j != 0)
{
sbResult.Append((char)value);
i += j;
}
else
{
sbResult.Append(current);
}
break;
default:
/* Unrecognized escape chracter */
sbResult.Append(current);
break;
}
bEscaped = false;
}
else
{
if(current == '\\')
{
bEscaped = true;
}
else
{
sbResult.Append(current);
}
}
}
return sbResult.ToString();
}
|
|
|
|
|
string WildCardPatern.UnEscape(string pattern)
"Converts a string that has escaped characters to a string that includes the escaped characters in their unescaped form. "
I've never tried it, but the description sounds like exactly what you want...
Ooops, looks like that's only available in .Net 3.0 (Winfx) - System.Management.Automation namespace ...
|
|
|
|
|
After wasting some time writing the method, Rob Graham give me a clue.
Rob Graham, you are right this method is in .NET 3.0, but there is another method with the same name:
Regex.Unescape
This function do the job.
BUT, this method is not error tolerant like my method;P.
So, if someone meant to use unescape and want to skip invalid escape sequences - my method does it.
Rob Graham - Thank you, again!
|
|
|
|