none
EX2007 OWA How can I get the user's mailbox server in startpage.aspx ? RRS feed

  • Question

  • As we are actually working with legacy.contoso.com for webmail.contoso.com during coexistence of our Ex2007 and Ex2010 our startpage.aspx can no more open correctly the calendars of mailboxes still located on Ex2007 mailbox servers.

    In startpage.aspx (located in C:\Program Files\Microsoft\Exchange Server\ClientAccess\Owa\forms\premium) we open the calendars with a call like this:

    mail = 'firstname.lastname@contoso.com' //the eMail-Address is actually typed in by the user

    w = window.open ('https://webmail.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');

    This worked fine until we defined the webmail.contoso.com to resolve to the new EX10 CAS&HUB-array and legacy.contoso.com resolving/being redirected to the legacy EX07 CAS&HUB-servers.

    So I either need a means to find the mailbox-server of the logged in user to be able to call either

    w = window.open ('https://webmail.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');

    or

    w = window.open ('https://legacy.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');

    or someone can give me a hint on how to do it so that the call works indipendently of the mailbox-server. At the moment being webmail.contoso.com works only for mailboxes located on the new EX10 servers, whilst the URL is truncated to legacy.contoso.com/firstname.lastname@contoso.com which tries to open the whole mailbox which of course is not allowed. So the users get an errory saying that they do not have the correct access rights.

    If something like

    var a_iQtWrn = <%= UserContext.QuotaWarning %>;

    would be possible, but UserContext.Server does not exist, neither UserContext.MailboxServer, nor UserContext.homeMDB.

    And if there were also the possibility to get the users' language, we could display the "Open shared calendar" GUI in the correct language. We need only german and english.

    Thanks a lot


    Rosario


    • Edited by Rosario2 Monday, March 26, 2012 2:42 PM
    Monday, March 26, 2012 2:38 PM

Answers

  • OK, I did it, thanks again to Lee for guidance. Here is the code I put into startpage.aspx (I had to put it after the closing </head> and <noscript>...</noscript> and <img style .. />, i.e. after line 51 in my original startpage.aspx, so as not to break anything preceeding):

    <script language="javascript" type="text/javascript">

    //Cr: as it is hard to get the user's mailbox server we hard code it here
    //
    //Cr: declare list of users whose mailboxes are on EX10 mailboxes

    var a_sUsers = [
      'firstname.lastname@contoso.com',
      'firstname.lastname@students.contoso.com'
       ];


    function OpenCalendar() {

      mail = window.prompt ('Please enter the eMail-Address of the person.', 'firstname.lastname@contoso.com/@students.contoso.com');
      strCancel = mail + 'SomeText';

      if ((mail != '')  && (strCancel != 'nullSomeText')) {
     
    //Cr: lookup user in the EX10-userArray

      isInList = false;
     
      for (var i=0; i < a_sUsers.length; i++) {
        if (a_sUsers[i] == mail) {
          isInList = true;
          break;
        }
      }

        if ( ! isInList ) { //Cr: the user is not in the EX10-List
          w = window.open ('https://legacy.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');
        } else {
          w = window.open ('https://webmail.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');    
        }
      }
    }

    function OpenMailbox() {

      mail = window.prompt ('Please enter the eMail-Address of the person.', 'firstname.lastname@contoso.com/@students.contoso.com');
      strCancel = mail + 'SomeText';

      if ((mail != '')  && (strCancel != 'nullSomeText')) {
     
    //Cr: lookup user in the EX10-userArray
      isInList = false;
     
      for (var i=0; i < a_sUsers.length; i++) {
        if (a_sUsers[i] == mail) {
          isInList = true;
          break;
        }
      }

        if ( ! isInList ) { //Cr: the user is not in the EX10-List
          w = window.open ('https://legacy.contoso.com/owa/'+mail, '', 'height=768, width=1024, location=yes, menubar=yes, resizable=yes');
        } else {
          w = window.open ('https://webmail.contoso.com/owa/'+mail, '', 'height=768, width=1024, location=yes, menubar=yes, resizable=yes');
        }   
      }
    }

    </script>

    Of course you have to set links accordingly in the table that follows to call these functions when the users click on those links. Here are my two table cells where this is the case:

    <td nowrap>
      <a class="ntbMBtn" href="javascript:OpenCalendar();" title="Open shared calendar">
      <img border="0" align="absmiddle" height="20" width="0"><img border="0" align="absmiddle" height="20" src="<%UserContext.RenderThemeFileUrl(Response.Output, ThemeFileId.Calendar);%>">Open shared calendar
    </a>
    </td>
    :
    :
    <td nowrap>
    <!-- Cr: link/function replaced with next line  <a id="lnkMbx" class="ntbMBtn" href="#" <%RenderOnClick("opnMbx();");%>> -->
      <a id="lnkMbx" class="ntbMBtn" href="javascript:OpenMailbox();" title="Open Mailbox">
      <img border="0" align="absmiddle" height="20" width="0"><span id="spnMbx"><img width="1"><%= Utilities.HtmlEncode(ExchangePrincipalDisplayName) %><img width="1"></span>&nbsp;<img id="imgMbxWd" border="0" align="absmiddle" src="<%UserContext.RenderThemeFileUrl(Response.Output, ThemeFileId.ExplicitLogonDownArrow);%>">
      </a>
    </td>


    Rosario

    • Marked as answer by Rosario2 Friday, May 4, 2012 3:28 PM
    Thursday, May 3, 2012 3:24 PM

All replies

  • Please help. After 3 or 4 days of investigations I did not succeed in finding any docs regarding the UserContext Data-Structure used in the mentioned startpage.aspx

    The very first line in startpage.aspx is

    <%@ Page language="c#" Codebehind="StartPage.aspx.cs" AutoEventWireup="false" Inherits="Microsoft.Exchange.Clients.Owa.Premium.StartPage" %>

    Should I have a look at StartPage.aspx.cs first?


    Rosario

    Wednesday, March 28, 2012 9:18 AM
  • OK, a friend of mine adviced to use Visual Studio and to browse the dll files directly with the object browser. So I am going through a steep learning courve now. First I searched for the file Microsoft.Exchange.Clients.Owa.dll on the CAS&HUB server. It was found on C:\Program Files\Microsoft\Exchange Server\ClientAccess\Owa\Bin with some patched/updated versions in some windows subdirectories. I copied it to  my own computer where Visual Studio is installed. I looked at it and found some of the mentioned properties like UserContext.QuotaWarning:

    objectBrowser UserContext

    Now the big question is whether there is a ready made property containing the mailbox server or the database name of the users' mailbox.

    At a first glance there is no such property and no utility-member-function to get that names.

    Any ideas? Hints?


    Rosario


    • Edited by Rosario2 Wednesday, March 28, 2012 12:13 PM
    Wednesday, March 28, 2012 11:56 AM
  • It should work if you use the name of a CAS server (although it looks like you're already doing that).  Pointing it at a mailbox server won't work, unless that MBX server also has the CAS role installed.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Monday, April 2, 2012 3:56 PM
  • Thanks, legacy.contoso.com points to the old four 2007 CAS-Servers and webmail.contoso.com points to the new 2010 CAS-Servers. That's why it does not work any more and why I tried to solve it programmatically. Bytheway OPEN MAILBOX of another user does behave the same way. The called function opnMbx (...href="#" <%RenderOnClick("opnMbx();") continues to use our webmail.contoso.com URL and hence can only open mailboxes we have already migrated to EX10. But for the moment we are not ready to migrate all of our mailboxes. We have to coexist for another couple of weeks. For the moment I scripted the open mailbox function the same way I showed in my first post, with  window.open ('https://legacy.contoso.com/owa/'+mail) where mail contains the eMail-Address the user types in.


    Rosario

    Monday, April 2, 2012 6:16 PM
  • If the redirect to the correct CAS server works internally, you should be able to use something like the WinHTTPRequest object to attempt to load the OWA GUI from the E2010 CAS.  If WinHTTPRequest gets a 302 response, then you know that it has been redirected.  One of its properties will show the new location, and presumably, this will be the correct CAS server.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Tuesday, April 3, 2012 1:02 PM
  • Yes internally it works. Only when opening another users' maibox or calendar from inside startpage.aspx it does not work correctly.

    So, do you think I could check the WinHTTPRequest inside startpage.aspx? Depending on the mailbox server the user has already been correctly redirected to the new Outlook-Web-App and for old EX07 mailboxes to legacy.contoso.com where my startpage.aspx is correctly called.

    Will WinHTTPRequest not simply contain legacy.contoso.com, which per se is correct??

    I do not see your point.


    Rosario


    • Edited by Rosario2 Tuesday, April 3, 2012 1:12 PM
    Tuesday, April 3, 2012 1:12 PM
  • Well, it's possible that I have completely misunderstood your question, of course.  It seems that you want all your users to go to OWA on the E2010 CAS, but you have changed the E2010 CAS startpage.aspx to contain a link that pops up a window showing the calendar.  The location for the popup window is

     window.open ('https://webmail.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar'

    but for some reason, this doesn't work for mailboxes on an E2007 server (I'm not actually sure if that should work, or not).

    If my assumptions are correct, my idea would be to add code to create a WinHTTPRequest object in server-side executed code, and tell it to send a GET request to a URL that would result in an internal redirect for an E2007 mailbox.  You can inspect the WinHTTPRequest's status property.  If it is a 200, then it has not been redirected (and presumably we have an E2010 mailbox).  If it has been redirected to the E2007 CAS (the status is 302, and the old server URL is in one of its .Options properties - I'll have to go away and look it up), then presumably we have an E2007 mailbox instead.  You can then get the code to write window.open code that points to the older server.  Of course, this needs the older server to be actually reachable from the location that you are browsing from.


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Tuesday, April 3, 2012 1:29 PM
  • Yes, you misunderstood. It is the OTHER WAY round:

    - Outlook-Web-App on webmail.contoso.com is working fine with the user mailboxes already migrated to EX10. Nothing tweaked or changed in its code. And the code correctly opens calendars and mailboxes of old EX07 users.

    - Outlook-Web-Access on legacy.contoso.com is broken. The user is correctly redirected to Outlook-Web-Access when his mailbox is located on a EX07 Mailbox server. But when he tries to open a mailbox or calendar of a user whose mailbox has already been moved to EX10 Mailbox server, he does not get back the webmail.contoso.com URL but simply legacy.contoso.com/firstname.lastname@contoso.com which is wrong for two reasons:

    a) because it tries to open a whole mailbox

    b) because the parameters ?cmd=contents&module=calendar are truncated and lost

    That's why I changed the startpage.aspx of old OWA 07 to use a hardcoded legacy.contoso.com/firstname.lastname@contoso.com/?cmd=contents&module=calendar which works fine for all EX07 mailboxes, but fails for new EX10 mailboxes.

    The good dynamic solution would be to check for the mailbox-server and then do a window.open with legacy... for old EX07 and webmail... for new EX10 mailboxes.

    Oooh, I see a Microsoft.Exchange.Clients.Owa.Core.OwaContext.HttpContext in the mentioned dll. Do you think I could test on this whether there was a redirection to legacy.contoso.com in which case I know the users' mailbox is located on EX07? Hmmm... this could not help because I need to decide on the mailbox THE USER ACTUALLY WANTS TO OPEN and not on his own. If the mailbox/calendar the user wants to open is on EX10, I need to call with webmail.contoso.com/firstname.lastname@contoso.com/?cmd=contents&module=calendar and if it is on EX07, I need to call with legacy.contoso.com/firstname.lastname@contoso.com/?cmd=contents&module=calendar


    Rosario





    • Edited by Rosario2 Tuesday, April 3, 2012 2:02 PM
    Tuesday, April 3, 2012 1:48 PM
  • I don't know - I'll have a look at the dll when I have some time.  In the meantime, can you see anything that looks like MailboxVersion ?  This is an AD property for each user, that indicates the version of Exchange that the mailbox is hosted on.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Tuesday, April 3, 2012 4:03 PM
  • As far as I can see, UserContext.MailboxIdentity would be the nearest bet to your MailboxVersion?


    Rosario

    Wednesday, April 4, 2012 11:48 AM
  • I wrote a bit of code (it works here) that uses DirectorySearcher to get the mailbox server name from LDAP, if that's something you'd like to try?  You need to add a reference to the System.DirectoryServices assembly to OWA's web.config file, though.  It might cause a problem if this gets replaced by a standard one at the next Exchange rollup.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Wednesday, April 4, 2012 2:05 PM
  • I am experienced in VB, Javascript, PHP, C/C++ but I never assembled an ASP or .NET project/program.

    So I am able to deal with simple variables and function calls inside startpage.aspx  (located in C:\Program Files\Microsoft\Exchange Server\ClientAccess\Owa\forms\premium) of our EX07 CAS&HUB Servers. Anything going beyond that would mean taking me by the hand and guiding me through it. So far I could implement the mentioned two workarounds for opening a calendar or mailbox during normal operation hours of our servers, without having to restart IIS. So the question is also whether your solution needs downtime or restart of IIS which breaks webmail-connections of our users. If so, I would have to implement and test during night hours.

    No problems with rollups/upgrades, one because we are accustomed to reintroduce our little open calendar code after such upgrades and two because we coexist for another few months without changing anything on EX07 server farm.

    How do you see it?


    Rosario


    • Edited by Rosario2 Wednesday, April 4, 2012 3:33 PM
    Wednesday, April 4, 2012 3:29 PM
  • Doesn't need any downtime ( if we both get the typing/spelling correct :-) ), and you don't need to assemble anything.  I would make copies of the files first, before you change them.  The editing is most easily done in Notepad.  Don't need to stop/start anything.

    Add this line to the web.config in the ClientAccess\owa folder.  Put it just before the line that says </assemblies> :

    <add assembly="System.DirectoryServices,Version=2.0.0.0,Culture=neutral,publicKeyToken=b03f5f7f11d50a3a" />

    Then add this code somewhere in the startpage.aspx file.  I put it just after <head> :

    <%
    System.DirectoryServices.DirectorySearcher objDS = new System.DirectoryServices.DirectorySearcher();
    objDS.PropertiesToLoad.Add("msExchHomeServerName");
    objDS.Filter = "(displayName=" + ExchangePrincipalDisplayName + ")";
    System.DirectoryServices.SearchResult objSR = objDS.FindOne();
    string strHSN = objSR.Properties["msExchHomeServerName"][0].ToString();
    Response.Write(strHSN);
    %>

    If everything's working okay, you should see the distinguished name of the mailbox server displayed at the top of the OWA GUI.  If so, then you can remove (or comment with // ) the Response.Write(strHSN); line.  Or you can record the values by looking at the page HTML source first.  You can then use this value to conditionally ouput the window.open() code later on in the page.


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m


    Wednesday, April 4, 2012 3:58 PM
  • OK then, lets go. I'll report back.

    Rosario

    Thursday, April 5, 2012 8:32 AM
  • Yiiiiiikkeees, web.config breaks, nothing to do. Even without adding the code in startpage.aspx

    Ex07 runs on Windows Server 2003 R2 SP2, if this could be of any importance in the assemblies line.


    Rosario


    • Edited by Rosario2 Thursday, April 5, 2012 10:20 AM
    Thursday, April 5, 2012 10:20 AM
  • Drat, I keep thinking that this is going onto the E2010 server, because that's the new one.  What was the error you saw?  Something like 'can't load file or assembly'?

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, April 5, 2012 12:08 PM
  • NOooo, definitely we have to implement on old EX07 CAS&HUB Servers, because that's where old users are redirected correctly. In the Web-Browser unfortunately the error was only a generic one, saying to set <customErrors ..> to on and redirect them to an own page.

    And as I do not need the actual logged in users' mailbox server, but the one of the user-mailbox he types in to open, I wonder if I can pass this as parameter in your line:

    >>objDS.Filter = "(displayName=" + ExchangePrincipalDisplayName + ")";

    as

    objDS.Filter = "(displayName=" + "firstname.lastnameOfuserWhoseMailboxOrCalendarWeWantToOpen" + ")";


    Rosario

    Thursday, April 5, 2012 1:04 PM
  • The format must ultimately be:

    objDS.Filter = "(displayName=John Whatever)"

    once the strings are evaluated.  No quotes within the brackets.

    It's usually sufficient to have customErrors mode="Off".  It may work better if you try it directly on the server (i.e. http://localhost/owa), because some configurations don't allow remote debugging.

    Do you have the System.DirectoryServices.dll in this folder:

    C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.DirectoryServices\v4.0_4.0.0.0__b03f5f7f11d50a3a

    ?  The last part of the folder name matches the publicKeyToken we tried to use.


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, April 5, 2012 1:25 PM
  • Unfortunately no dll:

    And how could I test, without breaking the OWA-GUI like I did before?


    Rosario

    Thursday, April 5, 2012 1:37 PM
  • Sorry, I sent you to the wrong place.  It should be in C:\Windows\Assembly .  This is a rather strange folder (you won't see any files), but can you see an entry in the list for

    System.DirectoryServices     2.0.0.0     b03f5f7f11d50a3a

    I can't think of a way to completely guarantee that anything won't break the OWA GUI.  You'll just have to try any changes when things are quiet.  At least it can all be undone fairly quickly.  But if that assembly isn't there, we'll have to think of something else.  If it is there, we'll have to work out why you can't use it without seeing the error message.  I spent a long time looking at the OWA dlls in VStudio, but can't see anything that would help us.  So, we have to look in Active Directory.  System.DirectoryServices is the preferred method, and in C# we can't use the rather handy GetObject method that VB has, so anything else would be a bit complicated.


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, April 5, 2012 1:52 PM
  • OK, there we are now:

    So I think even the reference number is correct? But I have no clue why it does not work. I will certainly test during night hours. I copied and pasted your line correctly in the <assemblies> section, so no spelling errors. Is something wrong in your line:

    <add assembly="System.DirectoryServices,Version=2.0.0.0,Culture=neutral,publicKeyToken=b03f5f7f11d50a3a" />


    Rosario


    • Edited by Rosario2 Thursday, April 5, 2012 2:20 PM
    Thursday, April 5, 2012 2:16 PM
  • The line I used works here, but in IIS7.  It's possible that capitalization rules were different in earlier versions (I've seen web.config errors here saying that you should use "True" instead of "true" when I pasted in older code, for example).  Do you have an example of another <add assembly /> entry from your existing web.config file, so we can see what the others look like?

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, April 5, 2012 2:32 PM
  • I guess we are at IIS 6. I checked your line and capitalization already but could not see any problem. Here my whole section:

       <assemblies>
        <!-- Any assembly not in the GAC or the owa\bin folder that is referenced from an aspx page needs to be
        added here.  An assembly can be referenced by an aspx page through a namespace import or through usage
        of a method or property that returns a type from that assembly.  aspx page compilation is similar to
        regular c# compilation where any assembly that is referenced in the code needs to be provided to the
        compiler at compile time.  These entries are our means of providing additional assembly references to
        the compiler.  All assemblies in the GAC and owa\bin are referenced automatically.
        -->
        <add assembly="Microsoft.Exchange.Data,
         Version=8.0.0.0,
         Culture=neutral,
         publicKeyToken=31bf3856ad364e35"/>
        <add assembly="Microsoft.Exchange.Data.Storage,
         Version=8.0.0.0,
         Culture=neutral,
         publicKeyToken=31bf3856ad364e35"/>
       </assemblies>


    Rosario

    Thursday, April 5, 2012 2:42 PM
  • Well, C:\Windows\assembly is the GAC (Global Assembly Cache), so you might get away with not adding it to web.config.  But I was not able to use System.DirectoryServices in IIS7 without adding it to my own web.config here.  One thing you could try is to add the code to startpage.aspx first, and then see if you get an error mentioning the unreferenced assembly.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, April 5, 2012 3:08 PM
  • OK, I will try with startpage.aspx

    As it is getting dark here in Switzerland I  hope to do it in the next minutes. But I will be out of office for Easter starting tomorrow. So I might come back only then.

    Thanks a lot so far.


    Rosario

    Thursday, April 5, 2012 4:26 PM
  • No luck. Now the error is that there is a Namespace missing, System.Directory.Services. Could it be we have to load it like the other ones in startpage.aspx:

    <%@ Page language="c#" Codebehind="StartPage.aspx.cs" AutoEventWireup="false" Inherits="Microsoft.Exchange.Clients.Owa.Premium.StartPage" %>
    <%@ Import Namespace="Microsoft.Exchange.Clients" %>
    <%@ Import Namespace="Microsoft.Exchange.Clients.Owa.Core" %>
    <%@ Import namespace="Microsoft.Exchange.Clients.Owa.Premium"%>
    <%@ Import Namespace="Microsoft.Exchange.Clients.Owa.Premium.Controls" %>

    So I could try with a line lilke this one?

    <%@ Import Namespace="System.DirectoryServices" %>

    I will try this last one and then leave.

    Nope, the same error again:

    Exception message: c:\Program Files\Microsoft\Exchange
    Server\ClientAccess\Owa\forms\premium\startpage.aspx(7): error CS0234: The type
    or namespace name 'DirectoryServices' does not exist in the namespace 'System'
    (are you missing an assembly reference?)

    So there is definitely something missing in our syntax. Do we have to register something also in registry.xml located in the forms\Customization folder?


    Rosario


    • Edited by Rosario2 Thursday, April 5, 2012 6:18 PM
    Thursday, April 5, 2012 6:08 PM
  • You should only need the web.config line.  Try it again when it's quiet, and let's see if we can get a better error message.  You may need to make some other changes to web.config to get it to display a better error message.  Let's see what it says.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, April 5, 2012 6:56 PM
  • After inserting the add assembly line into web.config it broke the whole OWA GUI, which means, that this page is also loaded on the fly like startpage.aspx. But could it be, I have to restart IIS after modifiying web.config?


    Rosario

    Monday, April 16, 2012 12:13 PM
  • As far as I can tell, IIS can tell when it has been modified, and it will reload it automatically as soon as you save it.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Monday, April 16, 2012 1:32 PM
  • OK. In web.config the error section is configured as follows:

      <customErrors
       mode="On"
       defaultRedirect="auth/error.aspx"/>

    And this gave me a rather generic error as I reported before. What could I do to get a better hint to what goes wrong if I add the assembly line here?


    Rosario

    Monday, April 16, 2012 1:37 PM
  • I think you just change the On to Off.  May need to get rid of the defaultRedirect value, since it's now surplus to requirements, but see if it will let you leave it in.  Because then it will be easier to change it back later.  On the other hand, the error messages are (as you say) rather generic, and maybe you'd prefer not to change it back, and to have it display normal error messages.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Monday, April 16, 2012 2:22 PM
  • OK I will start in about 4 or 5 hours during night here in Switzerland.

    Rosario

    Monday, April 16, 2012 2:27 PM
  • Sorry for the delay, but we scheduled a major intervention for tonight. And we seem to be more lucky, with errors off and the add assembly line as the first one instead of the last one:

      <customErrors
       mode="Off"
       />

       <assemblies>
        
    <add assembly="System.DirectoryServices,Version=2.0.0.0,Culture=neutral,publicKeyToken=b03f5f7f11d50a3a" />

        <add assembly="Microsoft.Exchange.Data,
         Version=8.0.0.0,
         Culture=neutral,
         publicKeyToken=31bf3856ad364e35"/>
        <add assembly="Microsoft.Exchange.Data.Storage,
         Version=8.0.0.0,
         Culture=neutral,
         publicKeyToken=31bf3856ad364e35"/>
       </assemblies>

    Now I will try to insert your code into startpage.aspx


    Rosario


    • Edited by Rosario2 Monday, April 30, 2012 10:45 PM
    Monday, April 30, 2012 10:43 PM
  • OK, now I have a partial success: if I start OWA on the CAS&HUB Server 2007 your code behaves correctly:

    On the CAS&HUB Server I use the internal, not published servername URL.

    When I start OWA using the external, published webmail.contoso.com which is redirected to legacy.contoso.com, then I get this error:

    Request
    Url: https://legacy.contoso.com:443/owa/forms/premium/StartPage.aspx
    User host address: xxx.xxx.xxx.xxx
    User: Carcò Rosario
    EX Address: /o=FHNW/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=rosario.carco
    SMTP Address: rosario.....
    OWA version: 8.3.245.1
    Mailbox server: MXAMU11.adm.ds.fhnw.ch

    Exception
    Exception type: System.NullReferenceException
    Exception message: Object reference not set to an instance of an object.

    Call stack

    ASP.forms_premium_startpage_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer)
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
    System.Web.UI.Page.Render(HtmlTextWriter writer)
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

    I hope you can help me track this down too in the next days.


    Rosario

    Monday, April 30, 2012 11:24 PM
  • Could it be, that placed after the <head> Tag your code comes too early, i.e. before the user has logged in? On the CAS&HUB Server I get correctly the windows logon prompt whilst I get the above error before I can log in when using webmail/legacy URL.

    Rosario

    Monday, April 30, 2012 11:45 PM
  • I don't think that will be the cause of the problem, as far as I know, IIS will not return anything at all if the authentication is not yet complete.  Can you find the iis log entry that shows the above failed request for startpage.aspx (or recreate the failed login, so that the recorded request is easier to find)?

    It's interesting that the error page knows the mailbox server name.  If you look at the HTML page source in the IE view menu, is there something near the top that says which .aspx page might be retrieving these details to display to the user?


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Tuesday, May 1, 2012 1:27 PM
  • Many thanks Lee. I will have time to analyze this afternoon.

    But there is another big problem, I fear we can not solve: as I told at the beginning (unfortunately wrong until we cleared that), I am not interested in the mailbox-server of the logged in user, but as soon as he types in a username, I will have to retrieve that user's mailbox-server and then compose the correct URL to open his calendar with:

    w = window.open ('https://legacy.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');

    where the JavaScript variable mail contains the user's email-address just typed in. So your code can retrieve the mailbox server name when the startPage.aspx is rendered and sent to the client. But after that, it's the client that should be able to send another request to the IIS-Server and get the desired mailbox-server name. This would be sort of  XHR request (XMLHttpRequest) to dynamically reload parts of a HTML-page.

    For the moment I do not see how JavaScript could retrieve the desired mailbox-server name.


    Rosario

    Wednesday, May 2, 2012 8:12 AM
  • Well, I notice that the OWA error page displays the mailbox server name (assuming the user has been authenticated) if you request a page in the OWA directory that doesn't exist (at least, it does in E2010).  I think you could get the request object to send a GET request to something like https://yourserver/owa/x.aspx and then parse the response.

    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Wednesday, May 2, 2012 9:01 AM
  • Lee, you are right, the error page comes up only after login. Analyzing in InternetExplorer with developer tools doesn't show where the mailbox server name comes from. The html code only shows the name but not which aspx page rendered it. So we would have to go through the whole aspx code involved.

    Strangely the only line I can find in the IIS logs is this one:

    2012-05-03 09:35:02 W3SVC1 10.51.2.72 GET /OWA/default.aspx &prfltncy=152&prfrpccnt=36&prfrpcltncy=78&prfldpcnt=3&prfldpltncy=16&prfavlcnt=0&prfavlltncy=0 443 adm\rosario.carco IP-ADDRESS-OF-ISA-SERVER Mozilla/5.0+(compatible;+MSIE+9.0;+Windows+NT+6.1;+Win64;+x64;+Trident/5.0) 200 0 0

    So sending a GET request back to the server as you propose, something like https://yourserver/owa/x.aspx?user=firstname.lastname to get its mailbox server name back, would involve registering an own aspx page and parsing the response back in the startPage.aspx, which is quite a lot of work and reinventing the wheel for something that is already built in: in the startPage.aspx the user can actually OPEN MAILBOX of another user. He can also select from a populated list of user names/mailboxes.

    Hmmm... I think I would be faster if I would hard-code a list of usernames and their mailbox-server-names, so that they are available directly in a JavaScript variable. I have visual basic scripts to export mailbox and user data directly in an Excel-Sheet from where I can copy/paste the desired data. I know, this would be statically hardcoded and not dynamic, but it could be used as a workaround until final migration to EX10 takes place.

    Would you agree?


    Rosario

    Thursday, May 3, 2012 10:13 AM
  • I think the error output that shows the mailbox name is in a function called RenderErrorDetails, which appears to be compiled in one of the codebehind .cs files, so we can't see where it comes from.  What's more, if we try to call RenderErrorDetails, and there hasn't really been an error, the most useful information (like the mbx server name) doesn't appear.  That was why I suggested sending a GET to a bogus page name like x.aspx (no need to put any query on the end).  I wasn't suggesting to actually create a page called x.aspx - the idea was to try to get a HTTP requester to load a page that doesn't exist, and so retrieve a 404 error message (which would include the server name in the error text) in its ResponseText property.  But all this has to happen after the user has logged in, otherwise it doesn't know who you are.

    But yes, depending on how many users have not migrated yet, it would probably now be easier to use a text file.  No need to include all usernames and server names.  Just have a list of those who have not yet migrated, and assume that if they're not in the list, their mailbox is on the E2010 server.  Or the other way round - add the login names of those who have been migrated, and if they're not in the list, their mailbox is still on the other server.


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, May 3, 2012 12:09 PM
  • Lee, thanks a lot, you are very right:

    a) lets reduce complexity to a strictly necessary minimum

    b) yes, lets take, the other way round, the list of already migrated users, which is for the moment the smaller list with about 30 mailboxes and assume all others still on the EX07 mailbox servers. It will also be easier to maintain this little list up to date with newly migrated mailboxes.

    c) the trick with the bogus-page would not have worked either because I do not need the mailbox server name of the logged in user but of the user he chooses to open the calendar or mailbox

    I'm going to program this in the next hours and report back.


    Rosario


    • Edited by Rosario2 Thursday, May 3, 2012 12:33 PM
    Thursday, May 3, 2012 12:31 PM
  • OK, I did it, thanks again to Lee for guidance. Here is the code I put into startpage.aspx (I had to put it after the closing </head> and <noscript>...</noscript> and <img style .. />, i.e. after line 51 in my original startpage.aspx, so as not to break anything preceeding):

    <script language="javascript" type="text/javascript">

    //Cr: as it is hard to get the user's mailbox server we hard code it here
    //
    //Cr: declare list of users whose mailboxes are on EX10 mailboxes

    var a_sUsers = [
      'firstname.lastname@contoso.com',
      'firstname.lastname@students.contoso.com'
       ];


    function OpenCalendar() {

      mail = window.prompt ('Please enter the eMail-Address of the person.', 'firstname.lastname@contoso.com/@students.contoso.com');
      strCancel = mail + 'SomeText';

      if ((mail != '')  && (strCancel != 'nullSomeText')) {
     
    //Cr: lookup user in the EX10-userArray

      isInList = false;
     
      for (var i=0; i < a_sUsers.length; i++) {
        if (a_sUsers[i] == mail) {
          isInList = true;
          break;
        }
      }

        if ( ! isInList ) { //Cr: the user is not in the EX10-List
          w = window.open ('https://legacy.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');
        } else {
          w = window.open ('https://webmail.contoso.com/owa/'+mail+'/?cmd=contents&module=calendar', '', 'height=768, width=1024, location=yes, menubar=no, resizable=yes');    
        }
      }
    }

    function OpenMailbox() {

      mail = window.prompt ('Please enter the eMail-Address of the person.', 'firstname.lastname@contoso.com/@students.contoso.com');
      strCancel = mail + 'SomeText';

      if ((mail != '')  && (strCancel != 'nullSomeText')) {
     
    //Cr: lookup user in the EX10-userArray
      isInList = false;
     
      for (var i=0; i < a_sUsers.length; i++) {
        if (a_sUsers[i] == mail) {
          isInList = true;
          break;
        }
      }

        if ( ! isInList ) { //Cr: the user is not in the EX10-List
          w = window.open ('https://legacy.contoso.com/owa/'+mail, '', 'height=768, width=1024, location=yes, menubar=yes, resizable=yes');
        } else {
          w = window.open ('https://webmail.contoso.com/owa/'+mail, '', 'height=768, width=1024, location=yes, menubar=yes, resizable=yes');
        }   
      }
    }

    </script>

    Of course you have to set links accordingly in the table that follows to call these functions when the users click on those links. Here are my two table cells where this is the case:

    <td nowrap>
      <a class="ntbMBtn" href="javascript:OpenCalendar();" title="Open shared calendar">
      <img border="0" align="absmiddle" height="20" width="0"><img border="0" align="absmiddle" height="20" src="<%UserContext.RenderThemeFileUrl(Response.Output, ThemeFileId.Calendar);%>">Open shared calendar
    </a>
    </td>
    :
    :
    <td nowrap>
    <!-- Cr: link/function replaced with next line  <a id="lnkMbx" class="ntbMBtn" href="#" <%RenderOnClick("opnMbx();");%>> -->
      <a id="lnkMbx" class="ntbMBtn" href="javascript:OpenMailbox();" title="Open Mailbox">
      <img border="0" align="absmiddle" height="20" width="0"><span id="spnMbx"><img width="1"><%= Utilities.HtmlEncode(ExchangePrincipalDisplayName) %><img width="1"></span>&nbsp;<img id="imgMbxWd" border="0" align="absmiddle" src="<%UserContext.RenderThemeFileUrl(Response.Output, ThemeFileId.ExplicitLogonDownArrow);%>">
      </a>
    </td>


    Rosario

    • Marked as answer by Rosario2 Friday, May 4, 2012 3:28 PM
    Thursday, May 3, 2012 3:24 PM
  • Slightly similar to something I did here:

    http://www.leederbyshire.com/Articles/Block-Or-Allow-OWA-Depending-On-Location-2010.asp

    Anyway, an interesting thread.  I learned a few things along the way :-)


    Mobile OWA For Smartphone
    www.leederbyshire.com
    email a@t leederbyshire d.0.t c.0.m

    Thursday, May 3, 2012 4:00 PM