Share This!

Friday, December 27, 2013

Windows 8 is Costing You Money

Your Money is Being Sucked Down a Hole
I have a client that I have designed a desktop app for.  It's a Winforms app designed in Visual Studio 2010 and uses the barely functional DataGridView object to edit data.  It's been working forever in Windows XP, Vista, and 7.  Though as stated, the DataGridView gives constant headaches.  Now the boss has upgraded his tablet to Win 8 and the app has stopped functioning once again, crashing while trying to automatically calculate column widths during a paint event.

This function of the DataGridView has been spotty at best even on the other versions of Windows, and I have had to code around problems with it before.  Basically, the thing is just a nightmare to configure and use. I constantly find myself writing 200 lines of code to get the damn thing to stop crashing, when in my humble opinion, the damned thing ought to just work out of the box.  Now, I can see there might be problems if I were trying to shoehorn grids into grids, or streaming media into 20,000 rows of data... but really I am doing nothing out of the ordinary here.

Now I have to stop ongoing development, and retrofit this whole app (at the client's expense) to an operating system that - say it with me - ought to just work out of the box!

Meanwhile the client is wondering if I am really all that sharp, because Microsoft muffed up their OS with backward compatibility problems.  Thanks, Microsoft!
...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Monday, December 16, 2013

Refresh All Views on SQL Server

Whenever you make a change to a table - say, to modify a column - you need to update all the views that depend on that column.  This script will find and update all your views. 

-- Back Up All Databases
-- by Bryan Valencia

--create temp table
declare @temp table(commands varchar(500), completed bit)

--load it with backup commands
insert into @temp (commands, completed)
(
    SELECT DISTINCT 'EXEC sp_refreshview ''' + name + '''',0
    FROM sys.objects AS so
    INNER JOIN sys.sql_expression_dependencies AS sed
        ON so.object_id = sed.referencing_id
    WHERE so.type = 'V'
    and is_schema_bound_reference = 0
)

--variable for the current command
declare @thisCommand varchar(500);

--loop through the table
while (select count(1) from @temp where completed=0)>0
begin
    --find the first row that has not already been executed
    select top 1 @thisCommand = commands from @temp where completed=0

    --show the command in the "mesage" output window.
    print @thisCommand

    --execute the command
    EXEC (@thisCommand);

    --flag this row as completed.
    update @temp set completed=1 where commands=@thisCommand
end

--show the user the rows that have been found.
select * from @temp


Of course if a view is now no longer correct, you'll see on your messages tab in SQL Server Management Studio.

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Friday, December 13, 2013

Integratederatederatedratedrated

This is not about Visual Studio.  In fact it's from 1982 when I was in tech school in Phoenix, Arizona.   We were using a Radio Shack Model 100 computer with 4K of RAM and a blazing fast cassette drive to store our programs.  Marc was using BASIC to create a simple keyboard-to-printer program so that he could type a page of text, edit, and print the text on the Epson dot matrix printer.

Basically he created an array to hold all the characters typed, and used that array to draw the text onscreen AND to print it when he was done. 

There was one small thing though.

The backspace character was a character like any other in the array, it (correctly) backed the cursor up on the screen, but did absolutely nothing to the printer. So Marc was typing a paper about integrated circuits, and his edits - which looked fine onscreen, printed out as Integratederatederatedratedrated Circuits.

The moral of this story is:  There's always more to a program than you thought up front.


...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, December 5, 2013

Selecting scalar values from a stored procedure

The easy and obvious answer is to use a function, not a procedure.   Then you can use it like any built-in T-SQL function.

select 1, dbo.Function() But alas, functions do not allow us to store (insert, update, delete) any data to the database and my stored procedure needs to do exactly that. 

In a moment of brilliant engineering, SQL Server does not allow the return value of a stored procedure to appear as a column in a query (select, insert, update, where clause),  so you can't just say...

select orderID, dbo.StoredProcedure() from... In my task, I had to insert the results of a stored procedure into a column in a table.  The code example I show below creates a temporary lookup table, and uses it later for a list of inserts.  try to follow this...

--creates a temp table for later use in joining (not shown)
declare @PickListNo table(OrderID varchar(20), PickListNo int, done bit);

--loads the temp table, except the column from the stored procedure
insert into @PickListNo (OrderID, done)
(
    Select distinct AOO.[order number], 0 from uploads.open_orders AOO
)

--vars the stored procedure needs
declare @A int
declare @NextVal int   

--while there are unprocessed rows...
while exists (select 1 from @PickListNo where PickListNo is null)
BEGIN
    --execute the procedure and capture the return value
    exec @A=dbo.NextPickListNo @NextVal OUTPUT
   
    --update one row in the table
    --I used Max(ID) to find a single row, but I might have used MIN, or Select top 1 as well.
    update @PickListNo set PicklistNo = @A where OrderID=(select MAX(orderID) from @PickListNo where PickListNo is null)
END
This use of the while loop is my way of cheating and not using cursors.  Cursors are nicely powerful but demand a lot of babysitting and resources (so I am told).

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Tuesday, December 3, 2013

Conditional Output with the ? Operator in C#

I needed to ensure that column data was trimmed to the correct lengths in a SQL insert.  Normally I would expect that this code...

string toobig="This string is exactly 37 characters.";
string nottoobig = "13 characters";


//attempt to trim both to 20

string s;
s = toobig.Substring(0, 20);
Console.WriteLine(s);

s = nottoobig.Substring(0, 20);
Console.WriteLine(s);

 ...would do the trick.

 Sadly, if you use substring with a length greater than your string, you don't get the whole string as you might expect, you get this.

System.ArgumentOutOfRangeException was unhandled
  Message=Index and length must refer to a location within the string.
Parameter name: length
  Source=mscorlib
  ParamName=length
So we need a way to trim a string only if it's needed, i.e. a conditional trim.  Normally this is written like this:

if (nottoobig.Length > 20) { s = nottoobig.Substring(0, 20); } else { s = nottoobig; };
This works, and so does this...

s = nottoobig.Substring(0, Math.Min(20, nottoobig.Length)); where we substring to the min of the actual length and the desired length.

But there is also this:

s = nottoobig.Length > 20 ? nottoobig.Substring(0, 20) : nottoobig; This works just like excel iif():
condition ? first_expression : second_expression;
Condition must be true or false. If true, the first_expression is used, if false, the second_expression is.


 

So I have written a clip() function that acts the way I expected substring() to:

        static void Main(string[] args)
        {
            string toobig = "This string is exactly 37 characters.";
            string nottoobig = "13 characters";
           
            //attempt to trim both to 20
            string s;
            s = clip(toobig,20);
            Console.WriteLine(s);

            s = clip(nottoobig, 20);
            Console.WriteLine(s);
        }

        private static string clip(string s, int max)
        {
            if (max < 0) max = 0;
            return s.Length > max ? s.Substring(0, max) : s;
        }



...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Wednesday, November 13, 2013

The type or namespace name 'OfficeOpenXml' could not be found

Error Message:
The type or namespace name 'OfficeOpenXml' could not be found (are you missing a using directive or an assembly reference?)

You need to change your app config to use .NET Framework 4 not .NET Framework 4 (Client Profile).

Project - <Project> Properties - Application tab

Target Framework

As it turns out, EPPlus needs the System.Web namespace, which is not in the client profile.



...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, October 31, 2013

Auto Close and why you want it OFF

So I was perusing my SQL Server Error Logs on my web server and found all my databases restarting. 

All night. 

Every 2 seconds.  

It turns out that the reason for this is that the database is set to automatically shut down whenever there are no more connections.  In a web environment, that means every single time there is a page hit.

We need to turn this off.  Now.

Open SQL Server Management Studio and log in.
From the Object Explorer select

  • Server
    • Databases
      • DatabaseName → Properties


Make sure Auto Close is set to False.


...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Monday, September 2, 2013

Labor Day

Isn't it great to live in a country where we can celebrate Labor by taking the day off work?

Thursday, August 29, 2013

MailMessage to Text

This simple class exposes a static method to take a MailMessage object and represent it as a block of text.  I ran into this because when an emailer program I wrote started getting error messages, the only thing I got in the error log was

Failure sending mail. 

 So - to track the problem, I wanted to quickly see what the mailmessage looked like and include it in my error notifications.

Here is the class

using System.Collections.Generic;
using System.Net.Mail;
using System.Text;

namespace mailmessage_to_text
{
    class MailtoText
    {
        private static string MailAddresstoString(MailAddress addy)
        {
            //"Russ Jansen" <RussJ@prosourceinc.com>
            string answer = "";
            if (addy != null)
            {
                if (string.IsNullOrEmpty(addy.DisplayName))
                {
                    answer = string.Format("<{0}>", addy.Address);
                }
                else
                {
                    answer = string.Format("\"{1}\" <{0}>", addy.Address, addy.DisplayName);
                }
            }
            return answer;
        }

        private static string MailAddressCollectionToString(MailAddressCollection mc)
        {
            List<string> addies = new List<string>();
            foreach (MailAddress addy in mc)
            {
                addies.Add(MailAddresstoString(addy));
            }
            return string.Join(", ", addies.ToArray());
        }

        /// <summary>
        /// Convert a MailMesage to a string
        /// </summary>
        /// <param name="msg">the MailMessage to convert</param>
        /// <returns>the MailMessage as a string</returns>
        public static string MessageToString(MailMessage msg)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("FROM: {0}", MailAddresstoString(msg.From)).AppendLine();
            sb.AppendFormat("TO: {0}", MailAddressCollectionToString(msg.To)).AppendLine();
            sb.AppendFormat("CC: {0}", MailAddressCollectionToString(msg.CC)).AppendLine();
            sb.AppendFormat("BCC: {0}", MailAddressCollectionToString(msg.Bcc)).AppendLine();
            sb.AppendFormat("SUBJECT: {0}", msg.Subject).AppendLine();
            sb.AppendFormat("BODY: {0}", msg.Body).AppendLine();

            foreach (Attachment att in msg.Attachments)
            {
                sb.AppendFormat("Attachment: {0}", att.Name);
            }

            return sb.ToString();
        }

    }
}
 This class exposes a single static function MessageToString() that will convert a MailMessage object to a readable string.  Perfect for logging or sending in a notification email.

The output looks like this:
FROM: "Bryan" <bryan@gmail.com>
TO: "Bob" <bob@gmail.com>, "Bill" <bill@gmail.com>, <some@yahoo.com>
CC: <bossman@cap.com>
BCC:
SUBJECT: New WebSite Contact
BODY: Blah has submitted the following on the CONCACT.ASPX page.
   Name: Ruby
   Email: Ruby@rails.com

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Friday, August 23, 2013

Visual Studio Grrr 1



This video illustrates the horrible gyrations you have to go through to create event handlers for components that are embedded into tables.  Clearly a fix is needed to the Visual Studio for Web interface, but they have added a feature that - while not a good solution - is at least a usable workaround.
...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, August 22, 2013

Dear Job Poster

Your recent job posting really gave me a good chuckle.  You want a "Programmer Analyst" - which is a junior programmer title - with the following:

Master's Degree or foreign equiv. in CS,Comp.Engng,Computer App.,or related field, plus 2 yrs of exp.in job offered,S/W consultant, engnr or related

an expert in...
HTML, DHTML, CSS, PHP, XML PERL, CORBA,  C, C++, and JAVA;

and then
Oracle, SQL, and MS Access

So, overall expert in DOS/Windows and Linux technologies.

I'm not sure why you think someone with a masters in CS will want a junior programmer job, or what you gained by shortening engineer to engnr.  I also don't know what you mean by SQL, there are MySQL, MSSQL, Sybase SQL Server - or do you just mean the general concept of the structured query language? 

This is what happens when HR people try to write job postings with no understanding of what any of it means.  In reality, this looks like a Java web programmer position.  I'm not sure why anyone with a masters degree would be interested in this for more than an afternoon, as this kind of work is very mundane and repetitive. 

I may be unemployed, but I do enjoy a good chuckle.

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Sunday, July 28, 2013

Executing an Unmanaged (COM) DLL from an ASP.NET web page.

 I had a regular old DLL that needed to accept parameters, and spit out a string as an answer.  It is a 64 bit DLL running on a 64 bit server under .NET Framework 4.5.

Here is a quick tutorial on how I got it to work.

First, I had to add this to my main <Configuration> section of my web.config


 <system.codedom>
  <compilers>
   <compiler
     language="c#;cs;csharp"
     extension=".cs"
     compilerOptions="/unsafe"
     type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </compilers>
 </system.codedom>



The /unsafe option is the big thing we needed here, as any call from managed code (.NET is all managed code) to unmanaged code, is considered unsafe.

Next, the dll must be wrapped in its own class.  So add a class to your web site.  Mine looks like this.
using System;
using System.Runtime.InteropServices;

namespace CodeGenerator
{

 internal class NativeMethods
 {
  [DllImport("kernel32.dll", SetLastError = true)]
  public static extern IntPtr LoadLibrary(string dllToLoad);

  [DllImport("kernel32.dll", SetLastError = true)]
  public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

  [DllImport("kernel32.dll")]
  public static extern bool FreeLibrary(IntPtr hModule);
 }

 public class unlocker
 {
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  private delegate IntPtr CreateCode2A(
   int level,
   string name,
   string encrypt_template,
   UInt32 hardwareID,
   UInt16 otherinfo1,
   UInt16 otherinfo2,
   UInt16 otherinfo3,
   UInt16 otherinfo4,
   UInt16 otherinfo5
   );


  public static unsafe string CreateUnlockingCode(string regname, string encrypt_template, string HardwareID, string pathtoDLL)
  {
   string unlockingcode = "";
   string sfp = HardwareID.Remove(4, 1);
   UInt32 lfingerprint = Convert.ToUInt32(sfp, 16);

   IntPtr pDll = NativeMethods.LoadLibrary(pathtoDLL);  //attempt to load the library
   int err1 = Marshal.GetLastWin32Error();
   try
   {
    IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "CreateCode2A");
    int err2 = Marshal.GetLastWin32Error();
    CreateCode2A createCode2 = (CreateCode2A)Marshal.GetDelegateForFunctionPointer(
      pAddressOfFunctionToCall,
      typeof(CreateCode2A));

    if (err1 == 0 && err2 == 0)
    {
     IntPtr unlockingcodeptr = createCode2(1, regname, encrypt_template, lfingerprint, 0, 0, 0, 0, 0);
     unlockingcode = Marshal.PtrToStringAnsi(unlockingcodeptr);
    }
    else
    {
     unlockingcode = string.Format("Error Codes: {0} and {1}", err1, err2);
    }
   }
   finally
   {
    bool result = NativeMethods.FreeLibrary(pDll);
   }
   return unlockingcode.ToString();
  }

 }
}

Now all we need is to call our CreateUnlockingCode function from the main page, which calls the DLL function, and marshals the result back to a C# string for us.


unlockingcode = CodeGenerator.unlocker.CreateUnlockingCode(regname, encrypt_template, fingerprint, pathtoDLL);

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Sunday, July 7, 2013

DLL HELL

I have a 64 bit COM DLL that generates unlocking codes for a client.  I cannot edit this DLL.  It works SOMETIMES.

[DllImport(@"codegen64.dll")]
 public static extern string CreateCode2(
  int level,
  string name,
  string encrypt_template,
  Int64 hardwareID,
  int otherinfo1,
  int otherinfo2,
  int otherinfo3,
  int otherinfo4,
  int otherinfo5
  );
 
There is the page global DLLImport function... and when I try to use it...

try
  {
    unlockingcode = CreateCode2(1, regname, encrypt_template, lfp, 0, 0, 0, 0, 0);
  }
  catch (Exception ex)
  {
    unlockingcode = "";
  }

I get this pop-up dialog on my IIS server...
[Window Title]
Visual Studio Just-In-Time Debugger

[Main Instruction]
An unhandled win32 exception occurred in w3wp.exe [11016].

The Just-In-Time debugger was launched without necessary security permissions. To debug this process, the Just-In-Time debugger must be run as an Administrator. Would you like to debug this process?

[^] Hide process details  [Yes, debug w3wp.exe] [No, cancel debugging]

[Expanded Information]
Process Name: w3wp.exe
User Name: NETWORK SERVICE

Trying to invoke the debugger gives...


NOTE: I have enclosed the call to the DLL in a TRY block and it still fails, killing my WHOLE WEBSITE.
There MUST be a way to load, use, and unload a single DLL in a web page SAFELY, so that I don't get these HORIBLE crashes.

I have a feeling that the DLL is failing to unload, as it seems to work once, then fail until I restart the app pool and web site.
BUT I don't really know because I CANT DEBUG THE PROBLEM.
Sorry for the yelling, but this is like the ninth time I have told the client this is fixed, only to have it recur EVERY TIME a client orders from the web site!
Oh, it should be noted that I have NEVER installed Visual Studio on this web server.
Also, it's IIS8
.NET framework 4
Windows Server Essentials 2012....

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Saturday, July 6, 2013

Quick Question about Speech Recognition

***From my Android Galaxy 2 with ZERO Training***
How come my android phone can understand everything that I say, yet windows 7 voice recognition can't get it after hours of training?


***From Windows (after many hours training)***
Up to my android phone can understand everything that I say, At 107 voice recognition can't get it after hours of training?

***I typed the rest.***
It seems to me that Microsoft should scrap the whole speech recognition project and just buy whatever Android did.   Because clearly they have failed.

To all my subscriber (yes there's only one), Use Windows Speech Recognition to comment below.

Monday, June 17, 2013

SQL Server: Friendly Time Differences

Ok, so I always like the Facebook smart date displays, like
posted by Bob Loblaw about 12 minutes ago
So I set about recreating this on my own sites in SQL Server.  Here is a fairly easy way to produce this kind of friendly time differences.

Select *
,iif(
datediff(DAY, errdate, getdate()) >0 ,
cast(datediff(DAY, errdate, getdate()) as varchar(90))+' days  ',
''
)+
iif(
datediff(HOUR, errdate, getdate()) >0 ,
cast(datediff(HOUR, errdate, getdate()) % 24 as varchar(90))+' hours  ',
''
)+
iif(
datediff(MINUTE, errdate, getdate()) >0 ,
cast(datediff(MINUTE, errdate, getdate()) % 60 as varchar(90))+' minutes  ',
''
)+
iif(
datediff(SECOND, errdate, getdate()) >0 ,
cast(datediff(SECOND, errdate, getdate()) % 60 as varchar(90))+' seconds ago.',
''
)
[friendlytime]
from errorlog
--where errdate > DATEADD(HOUR, -1, GETDATE())
order by errdate


This produces a nice, friendly time difference that is better than a list of raw dates for human interpretation.


errdatepageerrmessagefriendlytime
1961-06-17 11:07:21.820TESTTHIS IS A TEST ERROR MESSAGE18993 days  0 hours  20 minutes  36 seconds ago.
2010-06-17 11:06:05.470TESTTHIS IS A TEST ERROR MESSAGE1096 days  0 hours  21 minutes  52 seconds ago.
2012-06-17 11:04:41.123TESTTHIS IS A TEST ERRORMESSAGE365 days  0 hours  23 minutes  16 seconds ago.
2013-06-17 11:07:59.197TESTTHIS IS A TEST ERROR MESSAGE20 minutes  58 seconds ago.

Alternately, if you don't care to display all the way down to seconds when the time span is many days, you can nest it like this to only show the most relevant time gap.

iif(
datediff(DAY, errdate, getdate()) >0 ,
cast(datediff(DAY, errdate, getdate()) as varchar(90))+' days ago',
iif(
datediff(HOUR, errdate, getdate()) >0 ,
cast(datediff(HOUR, errdate, getdate()) as varchar(90))+' hours ago',
iif(
datediff(MINUTE, errdate, getdate()) >0 ,
cast(datediff(MINUTE, errdate, getdate()) as varchar(90))+' minutes ago',
iif(
datediff(SECOND, errdate, getdate()) >0 ,
cast(datediff(SECOND, errdate, getdate()) as varchar(90))+' seconds ago.',
'now'
)
)
)
) [friendlytime2]

This produces a result as follows:

18993 days ago
1096 days ago
365 days ago
38 minutes ago
...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Sunday, May 12, 2013

Best SQL Server Backup Script Evah

-- Back Up All Databases
-- by Bryan Valencia

--create temp table
declare @temp table(commands varchar(500), completed bit)

--load it with backup commands
insert into @temp (commands, completed)
(select
    'BACKUP DATABASE ['+name+
    '] TO  DISK = N''J:\Backups\'+name+
    '.bak'' WITH  COPY_ONLY, NOFORMAT, NOINIT,  NAME = N'''+name+
    '-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD,  STATS = 10',
    0
from
    master.sys.databases
where
    owner_sid <> 0x01 and state_desc='ONLINE'
)

--variable for the current command
declare @thisCommand varchar(500);

--loop through the table
while (select count(1) from @temp where completed=0)>0
begin
    --find the first row that has not already been executed
    select top 1 @thisCommand = commands from @temp where completed=0

    --show the command in the "mesage" output window.
    print @thisCommand

    --execute the command
    EXEC (@thisCommand);

    --flag this row as completed.
    update @temp set completed=1 where commands=@thisCommand
end

--show the user the rows that have been found.
select * from @temp


Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, April 25, 2013

Min (n) must be less than or equal to max (-1) in a Range object.

This happened to me when I would read an XML file into a Dataset, as follows:

string sort = "";
string where = string.Format("userID={0}", EmployeeID);
DataSet ds = new DataSet();
ds.ReadXml(XMLFilename);
DataRow[] rows = ds.Tables[0].Select(where, sort, DataViewRowState.CurrentRows);

The userID column is numeric, yet I found that I could make this error dissappear by single-quoting the parameter like this.

string where = string.Format("userID='{0}'", EmployeeID);

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Saturday, April 13, 2013

The "SendUsing" configuration value is invalid.

I am moving a asp classic app from Windows SBS 2003 IIS 7 to Windows Server 2012 IIS 8.
After spending all day figuring out a dozen different things, the site finds itself unable to send emails.  So I constructed a simple email sender to test it out.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <title> Email Test </title>
 </head>

 <body>
<%
    Set myMail=CreateObject("CDO.Message")
    myMail.Subject="Sending email with CDO"
    myMail.From="doNotReply@myserver.com"
    myMail.To="myemail@gmail.com"
    myMail.TextBody="This is a message."
    myMail.Send
    set myMail=nothing
%>

The message has been sent.
 </body>
</html>
 That's literally the whole thing.  it gives...

CDO.Message.1 error '80040220'
The "SendUsing" configuration value is invalid.
/cgi-bin/testemail.asp, line 14
So I googled.  First I changed the app pool user from ApplicationPoolIdentity to NetworkService, as many bloggers suggest.



No change.

Then I found some code that looks like this:

schema = "http://schemas.microsoft.com/cdo/configuration/"
  Set objFlds = objConf.Fields
  with objFlds
    .Item(schema & "sendusing") = 2
    .Item(schema & "smtpserver") = "smtp.gmail.com"
    .Item(schema & "smtpserverport") = 465
    .Item(schema & "smtpauthenticate") = 1
    .Item(schema & "sendusername") = "abc@def.com"
    .Item(schema & "sendpassword") = "qwerty"
    .Item(schema & "smtpusessl") = 1
    .Update
  End with
 and... no such luck.  Same Error.




...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Saturday, March 9, 2013

Setting Up WebDAV in IIS 8 for Site Publishing

This complete tutorial will tell you how to enable WebDav for publishing internet sites on your IIS8 server.

DONT.

Instead download FileZilla Server, install, and add an exception to your firewall.

I took 2 days trying to get WebDav to allow me to remote in and upload files to my site, and could not get past the "you are not authorized" message.

I had FileZilla running in 10 minutes. 


Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Tuesday, March 5, 2013

Propertybinding Combobox Values

 Ok, you have a search dialog box and you'd like to store the user's last choice for use the next time he launches your program.

So you go into "PropertyBinding" and there is no way to bind this value.


SelectedIndex and SelectedText are not in the list.  Text will not work if your box is a DropDownList, it will only work if your Combobox is a Dropdown.
So here's what you have to do.

First, from your project, Select Project and <projectname> Properties.
Then add a user scoped string setting for your Combobox.
Don't save the SelectedIndex as an integer, because whenever the list changes, you'll be restoring the wrong item in the list.

private void FindDropDownValue(ComboBox ddl, string value, int defaultvalue)
{
    int selectedListItem = ddl.Items.IndexOf(value);
    if (selectedListItem == -1)
    {
        selectedListItem = defaultvalue;
    }
    ddl.SelectedIndex = selectedListItem;
}

private void Load_Dropdowns()
{
//reload user settings
    FindDropDownValue(cbCustomer, Properties.Settings.Default.Quote_Customer, 0);
}
This will load the values from the user settings store.   I suggest calling Load_Dropdowns from your FORM_LOAD() method.

Now all we need is to save the settings on Form_Closing() of the form.

Private void SaveUserSettings()
{
    Properties.Settings.Default.Quote_Customer = cbCustomer.Text;
}

private void QuoteForm_FormClosing(object sender, FormClosingEventArgs e)
{
    SaveUserSettings();
}




Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Tuesday, February 12, 2013

Temp Tables in SQL Server

We all know you can create variables in SQL Server...
declare @customer varchar(20)
set @customer='a customer'

...but what if there is a need to store more complex data?
As it turns out, there is an easy way to accomplish that as well.

declare @csrlist Table(customer varchar(20), CSR varchar(25), counts int)

--get the counts of customer service reps orders for each customer.
insert into @csrlist (customer, csr, counts)
(
select distinct customer, Csr, COUNT(1) counts
from Purchase_Order
where Csr is not null
group by customer, csr

The resulting in-memory table can be inserted to, deleted from, updated, just like any real data table.
--find the CSR with the most orders for each customer
insert into @csrlist2 (customer, CSR)
    (select customer, Csr from @csrlist A where counts=(select MAX(counts) from @csrlist B where a.customer=b.customer))


Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

DropdownList: SelectedValue does nothing.

 I have a ComboBox set as a DropDownList, and the SelectedValue property, which ostensibly will find and select the selected value, does not.

cbSalesman.SelectedValue = salesman;  This is probably because you would need to give it not just a string to look for, but an actual object that is a member of the Items list.  That would require ugly gyrations along the lines of the following.
  1. get the string to look for
  2. get the index of that string in the dropdown (using Items.IndexOf)
  3. grab the item at that index
  4. feed it to the "SelectedValue" property.
Instead of all that, why not just do this.

cbSalesman.SelectedIndex = cbSalesman.Items.IndexOf(salesman);


...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Friday, January 18, 2013

DBNulls: the Bane of my Existence

So yes, a DataGridViewCell.value is an object.  But it seems there should be a way to tell it "hey, in this case, when I ask for a value and you have a null, just hand me an empty string".

So I wrote this (for use until I figure out how to default a null cell to string.empty).

        /// <summary>
        /// Converts an object value to a string.
        /// (usually from a DataGridViewCell.Value;
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public string Val2Str(object value)
        {
            if (value == DBNull.Value)
            {
                return string.Empty;
            }
            return value.ToString();
        }

        /// <summary>
        /// Converts a DataGridViewCell value to a string.
        /// </summary>
        /// <param name="Cell">The cell.</param>
        /// <returns></returns>
        public string Val2Str(DataGridViewCell Cell)
        {
            return Val2Str(Cell.Value);
        }

These overloaded routines can be passed either a DataGridViewCell itself, or just the Value property.  Kinda like this:

string customer = Val2Str(dataGridView1.CurrentRow.Cells["Customer"]);
string customer = Val2Str(dataGridView1.CurrentRow.Cells["Customer"].Value);

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Monday, January 14, 2013

Cannot execute as the database principal.

Cannot execute as the database principal because the principal "username" does not exist, this type of principal cannot be impersonated, or you do not have permission.
I am going to read your mind now.

  1. You recently backed up your database copy-only and moved it to another server or development box. 
  2. You're attempting to perform an  "Execute As..." command.
  3. Your software has been running for some time and this new error just started cropping up after you "refreshed" your copy of the database (from production?).
  4. You looked at the server logins, and the database users, and they seem to match (there is a login with the same name as the user).
What happened is that the SIDs (Security IDs) from the server login does not match the database user of the same name.  Remember that LOGINS are stored at the server level and USERS are in the databases.

What you need to do is re-create the user in the database (and reassign any roles and permissions).

USE [myDB]
GO

/****** Object:  User [myUser]    Script Date: 01/14/2013 18:21:22 ******/
IF  EXISTS (SELECT * FROM sys.database_principals WHERE name = N'myUser')
DROP USER [myUser]
GO

USE [myDB]
GO

/****** Object:  User [myUser]    Script Date: 01/14/2013 18:21:22 ******/
GO

CREATE USER [myUser] FOR LOGIN [myUser] WITH DEFAULT_SCHEMA=[dbo]
GO




...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Contact Us

Name

Email *

Message *