While in process of using the jQuery UI Slider in creating an alpha slider for a rolodex interface I came across some desired UI enhancements. Instead of having a slider that was plain i want to add the current value of the slider to interface. A quick simple line to the slider function gave me my desired appearance.

$("#slider-vertical").slider({
    orientation: "vertical",
    animate: true,
    range: "min",
    min: -90,
    max: -64,
    value: -64,
    step: 1,
    slide: function(event, ui) {
        if (ui.value == -64) {
            $(".ui-slider-handle,a").css("text-decoration", "none").css("text-align", "center").text("*");
            sliderCharacter = '';
        } else {
            sliderCharacter = String.fromCharCode(ui.value * -1);
            $(".ui-slider-handle,a").css("text-decoration", "none").css("text-align", "center").text(sliderCharacter);                        
        }
        
    },
    stop: function(event, ui) {
        //CALL AJAX TO RETRIEVE LIST
        slideAction(sliderCharacter);
    }
});

before 
BEFORE

after
AFTER

Convert XML to XSD to Class
 
From a command prompt run the following statements to convert first to an XSD then to a CS file.
 
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin>xsd c:\myXML.xml /out:c:\

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin>xsd c:\myXML.xsd /out:c:\ /classes /language:CS

Then move the XML and XSD to your web application’s APP_Data for safe keeping and move the cs file to App_Code folder. Then load and read the XML data.
XML
   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <links>
   3:     <link title="Yahoo" url="www.yahoo.com" />
   4:     <link title="Google" url="www.google.com" />
   5:     <link title="Bing" url="www.bing.com" />
   6:     <link title="Asp.Net" url="www.asp.net" />
   7:     <link title="MSN" url="www.msn.com" />
   8: </links>
 
CODE
   1: System.IO.StreamReader str = new System.IO.StreamReader(document); 
   2: System.Xml.Serialization.XmlSerializer xSerializer = new System.Xml.Serialization.XmlSerializer(typeof(links));
   3: links links = (links)xSerializer.Deserialize(str);
   4: foreach (linksLink l in links.Items)
   5: {
   6:     litXMLReader.Text += l.title + " : " + l.url + "<br />";
   7: }
   8: str.Close();
   9:  
  10: litXMLReader.Text += "";

Not to poach a blog post/article you need to go to www.mikesdotnetting.com and read his great article on Cascading DropDownLists with jQuery and ASP.NET.

http://www.mikesdotnetting.com/Article/97/Cascading-DropDownLists-with-jQuery-and-ASP.NET

After I read this article I decided to recreate it and build in some features of my own.  The feature I wanted most was a way to preserve the values on post back so that I didn't have to reload the list.  Also I wanted to be able to select the car (radio button) and then post that as well. The approach I took was using hidden variables (<asp:HiddenField />) that got updated as the dropdown list got changed and edited. Then on postback reload the lists based off of the values. If anyone has suggestions to better ways to accomplish the same thing I am listening. Here is the resulting code.

   1: <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
   2:     <script language="javascript" type="text/javascript" src='<%=ResolveClientUrl("~/") %>resources/scripts/jquery.selectboxes.min.js' ></script>
   1:  
   2:     <script type="text/javascript">
   3:         $(function() {
   4:             $('#<%= this.ddlMake.ClientID %>').change(function() {
   5:                 $("#<%= this.hidModel.ClientID %>").val('');
   6:                 $("#<%= this.hidColor.ClientID %>").val('');
   7:                 $("#<%= this.hidSelect.ClientID %>").val('');
   8:                 $('#output').empty();
   9:                 getModels();
  10:             });
  11:             $('#<%= this.ddlModel.ClientID %>').change(function() {
  12:                 $("#<%= this.hidModel.ClientID %>").val($(this).val());
  13:                 $("#<%= this.hidColor.ClientID %>").val('');
  14:                 $("#<%= this.hidSelect.ClientID %>").val('');
  15:                 $('#output').empty();
  16:                 getColors();
  17:             });
  18:             $('#<%= this.ddlColor.ClientID %>').change(function() {
  19:                 $("#<%= this.hidColor.ClientID %>").val($(this).val());
  20:                 $("#<%= this.hidSelect.ClientID %>").val('');
  21:                 $('#output').empty();
  22:                 getCarListByColor();
  23:             });
  24:  
  25:             $('#<%= this.ddlModel.ClientID %>').attr('disabled', true);
  26:             $('#<%= this.ddlColor.ClientID %>').attr('disabled', true);
  27:  
  28:             if ($('#<%= this.ddlMake.ClientID %>').val() != '') {
  29:                 getModels();
  30:             }
  31:  
  32:             $(".carSelect").live("click", function() {
  33:                 $("#<%= this.hidSelect.ClientID %>").val($(this).val());
  34:             });
  35:         });
  36:  
  37:         function getModels() {
  38:              $.ajax({
  39:                 type: "POST",
  40:                 url: "WebServices/CarService.asmx/GetCarsByModel",
  41:                 data: "{make: '" + $('#<%= this.ddlMake.ClientID %>').val() + "'}",
  42:                 contentType: "application/json; charset=utf-8",
  43:                 dataType: "json",
  65:                 data: "{make: '" + $('#<%= this.ddlMake.ClientID %>').val() + "', model: '" + $('#<%= this.hidModel.ClientID %>').val() + "'}",
  44:                 success: function(response) {
  45:                     var models = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
  46:                     $('#<%= this.ddlModel.ClientID %>').attr('disabled', false).removeOption(/./).addOption('', ' -- Select Model -- ');
  47:                     $('#<%= this.ddlColor.ClientID %>').attr('disabled', true).removeOption(/./);
  48:                     for (var i = 0; i < models.length; i++) {
  49:                         var val = models[i];
  50:                         var text = models[i];
  51:                         $('#<%= this.ddlModel.ClientID %>').addOption(val, text, (val == $("#<%= this.hidModel.ClientID %>").val()) ? true : false);
  52:                     }
  53:                     if ($('#<%= this.ddlModel.ClientID %>').val() != '')
  54:                     { 
  55:                         getColors();
  56:                     }
  57:                 }
  58:             });
  59:         }
  60:  
  61:         function getColors() {
  62:             $.ajax({
  63:                 type: "POST",
  64:                 url: "WebServices/CarService.asmx/GetCarsByColor",
  66:                 contentType: "application/json; charset=utf-8",
  67:                 dataType: "json",
  68:                 success: function(response) {
  69:                     var Colors = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
  70:                     $('#<%= this.ddlColor.ClientID %>').attr('disabled', false).removeOption(/./).addOption('', ' -- Select Color -- ');
  71:                     for (var i = 0; i < Colors.length; i++) {
  72:                         var val = Colors[i];
  73:                         var text = Colors[i];
  74:                         $('#<%= this.ddlColor.ClientID %>').addOption(val, text, (val == $("#<%= this.hidColor.ClientID %>").val()) ? true : false);
  75:                     }
  76:                     if ($('#<%= this.ddlColor.ClientID %>').val() != '') {
  77:                         getCarListByColor();
  78:                     }
  79:                 }
  80:             });
  81:         }
  82:  
  83:         function getCarListByColor() {
  84:             $.ajax({
  85:                 type: "POST",
  86:                 url: "WebServices/CarService.asmx/GetCarListByColor",
  87:                 data: "{make: '" + $('#<%= this.ddlMake.ClientID %>').val() + "', " + "model: '" + $('#<%= this.hidModel.ClientID %>').val() + "', " + "color: '" + $('#<%= this.hidColor.ClientID %>').val() + "'}",
  88:                 contentType: "application/json; charset=utf-8",
  89:                 dataType: "json",
  90:                 success: function(response) {
  91:                     var cars = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
  92:                     $('#output').empty();
  93:                     for (var i = 0; i < cars.length; i++) {
  94:                         var checked = ($('#<%= this.hidSelect.ClientID %>').val() == cars[i].ID) ? 'checked' : '';
  95:                         $('#output').append('<p><input class="carSelect" ' + checked + ' type="radio" name="car" value="' + cars[i].ID + '" /><strong>' + cars[i].Make + ' ' +
  96:                               cars[i].Model + '</strong><br /> Year: ' +
  97:                               cars[i].Year + '<br />Doors: ' +
  98:                               cars[i].Doors + '<br />Color: ' +
  99:                               cars[i].Color + '<br />Mileage: ' +
 100:                               cars[i].Mileage + '<br />Price: $' +
 101:                               cars[i].Price + '</p>');
 102:                     }
 103:                 }
 104:             });
 105:         }
 106:     
</script>
   3:  
   4: </asp:Content>
   5: <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
   6:     <div>
   7:         <div>
   8:             <p>
   9:                 <label>
  10:                     Please choose a Make:</label><br />
  11:                 <asp:DropDownList ID="ddlMake" runat="server" />
  12:             </p>
  13:         </div>
  14:         <div>
  15:             <p>
  16:                 <label>
  17:                     Please choose a Model:</label><br />
  18:                 <select ID="ddlModel" runat="server" />
  19:             </p>
  20:         </div>
  21:         <div>
  22:             <p>
  23:                 <label>
  24:                     Please choose a Color:</label><br />
  25:                 <select ID="ddlColor" runat="server" />
  26:             </p>
  27:         </div>
  28:         <div>
  29:             <asp:Button ID="btnSubmit" runat="server" Text="Submit" 
  30:                 onclick="btnSubmit_Click" />
  31:         </div>
  32:         <div id="output">
  33:         </div>
  34:     </div>
  35:     <asp:Label runat="server" ID="lblResults" />
  36:     <asp:HiddenField runat="server" ID="hidModel" />
  37:     <asp:HiddenField runat="server" ID="hidSelect" />
  38:     <asp:HiddenField runat="server" ID="hidColor" />
  39: </asp:Content>

In order to capture the car selected on postback I added an ID to each car. I needed to adjust the car object by adding an ID field.  Here is the resulting code.

   1: using System;
   2: using System.Web;
   3: using System.Web.Services;
   4: using System.Web.Services.Protocols;
   5: using System.Web.Script.Services;
   6: using System.Collections.Generic;
   7: using System.Linq;
   8:  
   9: public class Car
  10: {
  11:     public int ID;
  12:     public string Make;
  13:     public string Model;
  14:     public int Year;
  15:     public int Doors;
  16:     public string Color;
  17:     public float Price;
  18:     public int Mileage;
  19: }
  20:  
  21: /// <summary>
  22: /// Summary description for CarService
  23: /// </summary>
  24: [WebService(Namespace = "http://tempuri.org/")]
  25: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  26: [ScriptService]
  27: public class CarService : WebService
  28: {
  29:     List<Car> Cars = new List<Car>{
  30:     new Car{ID=1,Make="Audi",Model="A4",Year=1995,Doors=4,Color="Red",Price=2995f,Mileage=122458},
  31:     new Car{ID=2,Make="Ford",Model="Focus",Year=2002,Doors=5,Color="Black",Price=3250f,Mileage=68500},
  32:     new Car{ID=3,Make="BMW",Model="5 Series",Year=2006,Doors=4,Color="Grey",Price=24950f,Mileage=19500},
  33:     new Car{ID=4,Make="Renault",Model="Laguna",Year=2000,Doors=5,Color="Red",Price=3995f,Mileage=82600},
  34:     new Car{ID=5,Make="Toyota",Model="Previa",Year=1998,Doors=5,Color="Green",Price=2695f,Mileage=72400},
  35:     new Car{ID=6,Make="Mini",Model="Cooper",Year=2005,Doors=2,Color="Grey",Price=9850f,Mileage=19800},
  36:     new Car{ID=7,Make="Mazda",Model="MX 5",Year=2003,Doors=2,Color="Silver",Price=6995f,Mileage=51988},
  37:     new Car{ID=8,Make="Ford",Model="Fiesta",Year=2004,Doors=3,Color="Red",Price=3759f,Mileage=50000},
  38:     new Car{ID=9,Make="Honda",Model="Accord",Year=1997,Doors=4,Color="Silver",Price=1995f,Mileage=99750},
  39:     new Car{ID=10,Make="Audi",Model="A6",Year=2005,Doors=5,Color="Silver",Price=22995f,Mileage=25400},
  40:     new Car{ID=11,Make="Jaguar",Model="XJS",Year=1992,Doors=4,Color="Green",Price=3450,Mileage=92000},
  41:     new Car{ID=12,Make="Jaguar",Model="X Type",Year=2006,Doors=4,Color="Grey",Price=9950f,Mileage=17000},
  42:     new Car{ID=13,Make="Renault",Model="Megane",Year=2007,Doors=5,Color="Red",Price=8995f,Mileage=8500},
  43:     new Car{ID=14,Make="Peugeot",Model="406",Year=2003,Doors=4,Color="Grey",Price=3450f,Mileage=86000},
  44:     new Car{ID=15,Make="Mini",Model="Cooper S",Year=2008,Doors=2,Color="Black",Price=14850f,Mileage=9500},
  45:     new Car{ID=16,Make="Mazda",Model="5",Year=2006,Doors=5,Color="Silver",Price=6940f,Mileage=53500},
  46:     new Car{ID=17,Make="Vauxhall",Model="Vectra",Year=2007,Doors=5,Color="White",Price=13750f,Mileage=31000},
  47:     new Car{ID=18,Make="Ford",Model="Puma",Year=1998,Doors=3,Color="Silver",Price=2995f,Mileage=84500},
  48:     new Car{ID=19,Make="Ford",Model="Ka",Year=2004,Doors=3,Color="Red",Price=2995f,Mileage=61000},
  49:     new Car{ID=20,Make="Ford",Model="Focus",Year=2007,Doors=5,Color="Blue",Price=9950f,Mileage=19000},
  50:     new Car{ID=21,Make="BMW",Model="3 Series",Year=2001,Doors=4,Color="White",Price=5950f,Mileage=98000},
  51:     new Car{ID=22,Make="Citroen",Model="C5",Year=2005,Doors=5,Color="Silver",Price=5995f,Mileage=38400},
  52:     new Car{ID=23,Make="Toyota",Model="Corolla T3",Year=2004,Doors=5,Color="Blue",Price=5995f,Mileage=71000},
  53:     new Car{ID=24,Make="Toyota",Model="Yaris",Year=2005,Doors=3,Color="Grey",Price=5350f,Mileage=39000},
  54:     new Car{ID=25,Make="Porsche",Model="911",Year=2003,Doors=2,Color="Red",Price=16995f,Mileage=88000},
  55:     new Car{ID=26,Make="Ford",Model="Fiesta",Year=2004,Doors=3,Color="Red",Price=5759f,Mileage=49000},
  56:     new Car{ID=27,Make="Honda",Model="Accord",Year=1996,Doors=4,Color="Black",Price=1995f,Mileage=105000},
  57:     new Car{ID=28,Make="Audi",Model="A3 Avant",Year=2005,Doors=5,Color="Blue",Price=12995f,Mileage=22458},
  58:     new Car{ID=29,Make="Ford",Model="Mondeo",Year=2007,Doors=5,Color="Gold",Price=12250f,Mileage=8500},
  59:     new Car{ID=30,Make="BMW",Model="1 Series",Year=2006,Doors=4,Color="Black",Price=16950f,Mileage=19500},
  60:     new Car{ID=31,Make="Renault",Model="Clio",Year=2005,Doors=3,Color="Red",Price=5995f,Mileage=32600},
  61:     new Car{ID=32,Make="Toyota",Model="Verso",Year=2008,Doors=5,Color="White",Price=12995f,Mileage=5800},
  62:     new Car{ID=33,Make="Mini",Model="Cooper",Year=2003,Doors=2,Color="Black",Price=7950f,Mileage=36800},
  63:     new Car{ID=34,Make="Mazda",Model="6",Year=2007,Doors=4,Color="Blue",Price=16995f,Mileage=11300},
  64:     new Car{ID=35,Make="Ford",Model="Mondeo",Year=2004,Doors=5,Color="Green",Price=8759f,Mileage=66000},
  65:     new Car{ID=36,Make="Honda",Model="Civic",Year=1997,Doors=4,Color="Grey",Price=1995f,Mileage=99750},
  66:     new Car{ID=37,Make="Audi",Model="Q7",Year=2005,Doors=5,Color="Black",Price=22995f,Mileage=25400},
  67:     new Car{ID=38,Make="Jaguar",Model="XK8",Year=1992,Doors=4,Color="Blue",Price=3450,Mileage=92000},
  68:     new Car{ID=39,Make="Jaguar",Model="S Type",Year=2006,Doors=4,Color="Red",Price=9950f,Mileage=17000},
  69:     new Car{ID=40,Make="Renault",Model="Megane",Year=2007,Doors=5,Color="Yellow",Price=8995f,Mileage=8500},
  70:     new Car{ID=41,Make="Peugeot",Model="406",Year=2003,Doors=4,Color="White",Price=3450f,Mileage=86000},
  71:     new Car{ID=42,Make="Mini",Model="Cooper",Year=2008,Doors=2,Color="Red",Price=14850f,Mileage=9500},
  72:     new Car{ID=43,Make="Mazda",Model="5",Year=2006,Doors=5,Color="White",Price=6940f,Mileage=53500},
  73:     new Car{ID=44,Make="Vauxhall",Model="Vectra",Year=2007,Doors=5,Color="Blue",Price=13750f,Mileage=31000},
  74:     new Car{ID=45,Make="Ford",Model="Puma",Year=1998,Doors=3,Color="Red",Price=2995f,Mileage=84500},
  75:     new Car{ID=46,Make="Ford",Model="Puma",Year=2004,Doors=3,Color="Red",Price=2995f,Mileage=61000},
  76:     new Car{ID=47,Make="Ford",Model="Focus",Year=2007,Doors=5,Color="Grey",Price=9950f,Mileage=19000},
  77:     new Car{ID=48,Make="BMW",Model="3 Series",Year=2001,Doors=4,Color="Red",Price=5950f,Mileage=98000},
  78:     new Car{ID=49,Make="Citroen",Model="C5",Year=2005,Doors=5,Color="Yellow",Price=5995f,Mileage=38400},
  79:     new Car{ID=50,Make="Toyota",Model="Corolla T3",Year=2004,Doors=5,Color="Red",Price=5995f,Mileage=71000},
  80:     new Car{ID=51,Make="Toyota",Model="Yaris",Year=2005,Doors=3,Color="Black",Price=5350f,Mileage=39000},
  81:     new Car{ID=52,Make="Porsche",Model="911",Year=2003,Doors=2,Color="White",Price=16995f,Mileage=88000},
  82:     new Car{ID=53,Make="Ford",Model="Fiesta",Year=2004,Doors=3,Color="Grey",Price=5759f,Mileage=49000},
  83:     new Car{ID=54,Make="Honda",Model="Accord",Year=1996,Doors=4,Color="Green",Price=1995f,Mileage=105000}
  84:     };
  85:  
  86:     [WebMethod]
  87:     public List<Car> GetCarsByDoors(int doors)
  88:    {
  89:         var query = from c in Cars
  90:                     where c.Doors == doors
  91:                     select c;
  92:         return query.ToList();
  93:     }
  94:  
  95:     [WebMethod]
  96:     public List<Car> GetAllCars()
  97:    {
  98:         return Cars;
  99:     }
 100:  
 101:     [WebMethod]
 102:     public List<string> GetCarMakes()
 103:    {
 104:         var query = (from c in Cars
 105:                      orderby c.Make
 106:                      select c.Make).Distinct();
 107:         return query.ToList();
 108:     }
 109:  
 110:     [WebMethod]
 111:     public List<string> GetCarsByModel(string make)
 112:    {
 113:         var query = (from c in Cars
 114:                      where c.Make == make
 115:                      orderby c.Model
 116:                      select c.Model).Distinct();
 117:         return query.ToList();
 118:     }
 119:  
 120:     [WebMethod]
 121:     public List<string> GetCarsByColor(string make, string model)
 122:    {
 123:         var query = (from c in Cars
 124:                      where c.Make == make && c.Model == model
 125:                      orderby c.Color
 126:                      select c.Color).Distinct();
 127:         return query.ToList();
 128:     }
 129:  
 130:     [WebMethod]
 131:     public List<Car> GetCarListByColor(string make, string model, string color)
 132:    {
 133:         var query = from c in Cars
 134:                     where (c.Make == make &&
 135:                     c.Model == model &&
 136:                     c.Color == color)
 137:                     select c;
 138:         return query.ToList();
 139:     }
 140: }

Please note that I renamed colour to color throughout my project and I store my webservice (asmx) page in a folder called WebServcies. Also I am using a MasterPage so I used the $("#<%= this.<CONTROLID>.ClientID %>") name throught out the code.

First off, I hate really dislike IE, although IE 8 is better. Secondly there are ways to overcome the hate dislike. Here is a nice explanation of fixing the img scaling issue in IE.

http://joelonsoftware.com/items/2008/12/22.html

In short, add this to you site css file. 

img { -ms-interpolation-mode:bicubic; }

Recently for a client I created a custom Document Library that is specific to their organization. After creating it I wanted to hide the standard document library that comes with SharePoint. I don't want to delete it, just hide it so it can't be accidentally created. Here in lies my problem. I search high and low for a possible solution. While waiting to here back from the SharePoint blog team, I decided try and find a workaround. This is what I came up with. 

I decided to look at the actually aspx page that you see when you select "Create" from the site content area. I thought maybe I can hide the fields as they are created on this page.  The file is called "/_layouts/create.aspx" and can be found at "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS". If you go down to line 158 you can see the code setting a string variable to the list template name. I found gold. After this line is where I inserted my nasty little hack.

//IF YOU WANT TO HIDE CERTAIN LIBRARIES FROM BEING AVAILABLE
if ((strTemplateDisplayName == "Document Library") || (strTemplateDisplayName == "Translation Management Library"))
continue;

This will hide the libraries from the view of the user. Just be aware that this might break if there is a Service Pack and/or Patch applied for SharePoint.

If you can shed some light on a better way please, let me know.

I recently downloaded the latest version of Apple Safari 4 Beta and was happy to see someone is making progress in standardization. The acid 3 test can be found and run at http://acid3.acidtests.org/.

And the winner is….

Safari 4 – 100/100

image

Firefox 3.1 Beta – 93/100

image

Chrome – 79/100

image

Safari 3.5 – 75/100

image

Firefox 3.06 – 71/100

image

IE 8 – 20/100

image

IE 7 – ??? WTF?

image

Digg This

Whenever I publish my blog post through LiveWriter it doesn't show up on http://weblogs.asp.net/. Has anyone else experieced this? Am I missing a setting in LiveWriter?

A while back I found a really cool tool on CodePlex called Terminals.  It allows you to store all you RDP, VNC, VMRC, RAS, Telnet, SSH, ICA Citrix, Amazon S3, etc in the same interface.  It has a really useful tabbing feature that tabs out all the active connections you have for quick switching. If you work in the RDC world its a must check out.

http://www.codeplex.com/Terminals

image

Today a fellow colleague sent me an email telling me about this cool little MMC Snap-In. This will allow you to list all of the computers and Servers and connect to them via RDP Sessions quickly. This snap-in is included in the Adminpak.msi.

http://support.microsoft.com/kb/309375 

image

http://www.microsoft.com/downloadS/details.aspx?FamilyID=c16ae515-c8f4-47ef-a1e4-a8dcbacff8e3&displaylang=en 

image

After installing the admin pack, click Start –> Run –> tsmmc.msc.

image

This will open the MMC.  Add you connections. Then File –> Save As to save the connections.

image

I work with around 6 servers and on a daily basis and this makes it really easy to login and logout quickly. Anyone else have any cool RDP tools?

Digg This

This morning I went about finally setting myself up with Windows Live Writer so that I can start taking my blog experience a little more serious. This post will document the procedure needed to setup you weblog.asp.net blog with Windows Live Writers blogging tool.

1) Download and Install Windows Live Writer(http://windowslivewriter.spaces.live.com/)

2) Start the program. It should launch the configuration/setup wizard. Click Next.

clip_image002

3) Select “Other blog service”. Click Next.

clip_image004

4) Enter your blog address and blog credentials (http://weblogs.asp.net/%3cBlogName>). Click Next.

clip_image006

5) Select “Community Server” and enter http://weblogs.asp.net/metablog.ashx for the blog type. Click Next.

clip_image008

6) It will run through an install and identify the name of you blog and finish. You are now all set.

clip_image010

I already like the interface. It makes it very easy to add images and code snippets. In fact, this post was created with it.

I was recently working on a small POC project. Basically I had an internal MOSS 2007 server site and an locally hosted public facing website. I wanted to have the ability to add files to various MOSS document libraries and then give outside website visitors the ability to view and download these documents. So, what I did was:

  1. Created a document library in MOSS with Version and Content Approval enabled. I also added additional custom fields to the document library that could  display along with the document on the public web.
  2. Created a user control that I could drag to the public pages to display the documents and wired up the user control to access SharePoints webservices to rectrieve and display the document libraries specifics. (SEE CODE BELOW)

This is only a POC so bare with me.  You should be able to follow the basics of what I am doing.  Nothing is rocket science.

  1. Create a new WebSite in Visual Studio.
  2. Add a new web_reference. Point it at your SharePoint server (http://<Your SharePoint Server>/_vti_bin/List.asmx)
  3. Add a new user control to your website. (SEE CODE BELOW)
  4. Add a new webpage and drag on your user control to it. Run and enjoy.

Imports System.Net

Imports System.IO

Imports MOSS 'THIS IS YOUR WEB_REFERENCE

 

Partial Class SPDocuments

    Inherits System.Web.UI.UserControl

 

    'THIS IS THE KEY TO IT ALL. THIS USER MUST HAVE READ ONLY CREDENTIALS

    'TO THE DOCUMENT LIBRARY. THAT WAY THE SEE THE LATEST PUBLISH DOCUMENT ONLY.

    Dim networkCredential As New NetworkCredential("username", "password")

 

 

    Private _DocumentLibraryID As String

    Public Property DocumentLibraryID() As String

        Get

            Return _DocumentLibraryID

        End Get

        Set(ByVal value As String)

            _DocumentLibraryID = value

        End Set

    End Property

 

    Private _DocumentLibrary As String

    Public Property DocumentLibrary() As String

        Get

            Return _DocumentLibrary

        End Get

        Set(ByVal value As String)

            _DocumentLibrary = value

        End Set

    End Property

 

    Private _FileServer As String

    Public Property FileServer() As String

        Get

            Return _FileServer

        End Get

        Set(ByVal value As String)

            _FileServer = value

        End Set

    End Property

 

    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)

        MyBase.OnInit(e)

        If DocumentLibraryID Is Nothing Then

            DocumentLibraryID = GetListID(DocumentLibrary)

        Else

            DocumentLibrary = GetListID(DocumentLibraryID)

        End If

        BindLiteral()

    End Sub

 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then

 

        End If

    End Sub

 

    Private Sub BindLiteral()

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE LIST LIBRARY

 

        'Declare and initialize a variable for the Lists Web service

        Dim listService As MOSS.Lists = New MOSS.Lists()

 

        'Authenticate the current user by passing their default

        'credentials to the Web service from the system credential cache.

 

        listService.Credentials = networkCredential

 

        'Set the Url property of the service for the path to a subsite.

        listService.Url = String.Format("http://{0}/_vti_bin/Lists.asmx", FileServer)

 

        ' Instantiate an XmlDocument object

        Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()

 

        ' Assign values to the string parameters of the GetListItems method, using GUIDs for the listName and viewName

        'variables. For listName, using the list display name will also work, but using the list GUID is recommended. For

        'viewName, only the view GUID can be used. Using an empty string for viewName causes the default view

        'to be used.

        Dim listName As String = DocumentLibraryID

        Dim viewName As String = ""

        Dim rowLimit As String = "1000"

 

        'Use the CreateElement method of the document object to create elements for the parameters that use XML.*/

        Dim query As System.Xml.XmlElement = xmlDoc.CreateElement("Query")

        Dim viewFields As System.Xml.XmlElement = xmlDoc.CreateElement("ViewFields")

        Dim queryOptions As System.Xml.XmlElement = xmlDoc.CreateElement("QueryOptions")

 

        'To specify values for the parameter elements (optional), assign CAML fragments to the InnerXml property of each element.*/

        query.InnerXml = QueryCAML()

        viewFields.InnerXml = "<FieldRef Name=""DocIcon"" /><FieldRef Name=""ProgId"" /><FieldRef Name=""FileRef"" /><FieldRef Name=""Public_x0020_Title"" /><FieldRef Name=""Public_x0020_Description"" /><FieldRef Name=""LinkFilename"" /><FieldRef Name=""Modified"" /><FieldRef Name=""Author"" /> "

        queryOptions.InnerXml = ""

 

        ' Declare an XmlNode object and initialize it with the XML response from the GetListItems method. The last parameter specifies the GUID of the Web site containing the list. Setting it to null causes the Web site specified by the Url property to be used.

        Dim nodeListItems As System.Xml.XmlNode = listService.GetListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, Nothing)

        nodeListItems.Normalize()

 

        For Each node As System.Xml.XmlNode In nodeListItems

            If node.Name = "rs:data" Then

                For Each childNode As System.Xml.XmlNode In node.ChildNodes

                    If childNode.Name = "z:row" Then

                        'For i As Integer = 0 To childNode.Attributes.Count - 1

                        '    strHTML += childNode.Attributes(i).Name & "<br />"

                        'Next

                        Dim strDocIcon As String = childNode.Attributes("ows_DocIcon").Value

                        Dim strLinkFilename As String = childNode.Attributes("ows_LinkFilename").Value

                        Dim strLinkFileRef As String = childNode.Attributes("ows_FileRef").Value.Replace(childNode.Attributes("ows_ProgId").Value, "")

                        Dim strLastModified As String = childNode.Attributes("ows_Modified").Value

                        'CUSTOM FIELD

                        Dim strPublicTitle As String = childNode.Attributes("ows_Public_x0020_Title").Value

                        'CUSTOM FIELD

                        Dim strPublicDescription As String = childNode.Attributes("ows_Public_x0020_Description").Value.Replace(childNode.Attributes("ows_ProgId").Value, "")

                        'Dim strBody As String = childNode.Attributes("ows_Body").Value

                        'strBody = System.Text.RegularExpressions.Regex.Replace(strBody, "<[^>]*>", "")

 

                        Dim ib As ImageButton = New ImageButton()

                        ib.ImageUrl = GetIcon(strDocIcon)

                        ib.CommandArgument = strLinkFilename

                        AddHandler ib.Click, AddressOf ImageButtonGetFile

 

                        Dim lb As LinkButton = New LinkButton()

                        lb.Text = strPublicTitle

                        lb.CommandArgument = strLinkFilename

                        AddHandler lb.Click, AddressOf LinkButtonGetFile

 

                        Me.phDocuments.Controls.Add(ib)

                        Me.phDocuments.Controls.Add(lb)

                        Me.phDocuments.Controls.Add(New HtmlGenericControl("br"))

                    End If

                Next

            End If

        Next

    End Sub

 

    Private Function QueryCAML() As String

        'Use this tool to build the CAML for you http://www.codeplex.com/SPCamlViewer

        Dim oSb As New System.Text.StringBuilder

 

        oSb.Append("         <OrderBy>")

        oSb.Append("              <FieldRef Name=""Public_x0020_Title"" />")

        oSb.Append("         </OrderBy>")

        oSb.Append("         <Where>")

        oSb.Append("              <And>")

        oSb.Append("                   <Eq>")

        oSb.Append("                        <FieldRef Name=""Publicly_x0020_Available"" />")

        oSb.Append("                        <Value Type=""Boolean"">1</Value>")

        oSb.Append("                   </Eq>")

        oSb.Append("                   <Eq>")

        oSb.Append("                        <FieldRef Name=""_ModerationStatus"" />")

        oSb.Append("                        <Value Type=""ModStat"">Approved</Value>")

        oSb.Append("                   </Eq>")

        oSb.Append("              </And>")

        oSb.Append("         </Where>")

 

        Return oSb.ToString()

    End Function

 

    Private Sub ImageButtonGetFile(ByVal sender As Object, ByVal e As ImageClickEventArgs)

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE DOCUMENT LIBRARY

        Dim ib As ImageButton = CType(sender, ImageButton)

        GetFile(ib.CommandArgument)

    End Sub

 

    Private Sub LinkButtonGetFile(ByVal sender As Object, ByVal e As EventArgs)

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE DOCUMENT LIBRARY

        Dim lb As LinkButton = CType(sender, LinkButton)

        GetFile(lb.CommandArgument)

    End Sub

 

    Private Sub GetFile(ByVal strFileName As String)

 

        Dim strURI As String = String.Format("http://{0}/{1}/{2}", FileServer, DocumentLibrary, strFileName)

        Dim request As WebRequest = WebRequest.Create(New Uri(strURI))

 

        request.Credentials = networkCredential

        Dim webResponse As WebResponse = request.GetResponse()

        Dim webStream As Stream = webResponse.GetResponseStream()

 

        System.Web.HttpContext.Current.Response.ClearHeaders()

        System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"

        System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName)

 

        Dim binaryReader As BinaryReader = New BinaryReader(webStream)

        Dim buffer As Byte() = binaryReader.ReadBytes(webResponse.ContentLength)

        System.Web.HttpContext.Current.Response.OutputStream.Write(buffer, 0, webResponse.ContentLength)

        System.Web.HttpContext.Current.Response.Flush()

 

        webResponse.Close()

        webStream.Close()

 

    End Sub

 

    Private Function GetIcon(ByVal strDocIcon As String) As String

        'THIS IS JUST FOR FANCY DISPLAY

        Dim imgLocation As String = ""

        Select Case strDocIcon

            Case "doc", "rtf", "wps", "txt", "docx", "dot"

                imgLocation = "~/images/word.png"

            Case "xls", "csv", ".xlw", "xlt", "xlsx"

                imgLocation = "~/images/excel.png"

            Case "ppt", "pptx"

                imgLocation = "~/images/powerpoint.png"

            Case "pdf"

                imgLocation = "~/images/pdf.png"

            Case "zip", "rar", "gzip"

                imgLocation = "~/images/zip.png"

            Case Else

                imgLocation = "~/images/default.png"

        End Select

        Return imgLocation

    End Function

 

    Function GetListID(ByVal strListName As String) As String

        Dim strListID As String = ""

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE LIST LIBRARY

 

        'Declare and initialize a variable for the Lists Web service

        Dim listService As MOSS.Lists = New MOSS.Lists()

 

        'Authenticate the current user by passing their default

        'credentials to the Web service from the system credential cache.

 

        listService.Credentials = networkCredential

 

        'Set the Url property of the service for the path to a subsite.

        listService.Url = String.Format("http://{0}/_vti_bin/Lists.asmx", FileServer)

 

        ' Instantiate an XmlDocument object

        Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()

 

        ' Declare an XmlNode object and initialize it with the XML response from the GetListItems method. The last parameter specifies the GUID of the Web site containing the list. Setting it to null causes the Web site specified by the Url property to be used.*/

        Dim nodeListItems As System.Xml.XmlNode = listService.GetListCollection()

        nodeListItems.Normalize()

        For Each node As System.Xml.XmlNode In nodeListItems

            If node.Name = "List" AndAlso node.Attributes("Title").Value = strListName Then

                strListID = node.Attributes("ID").Value

                Exit For

            End If

        Next

        Return strListID

    End Function

 

    Function GetListName(ByVal strListID As String) As String

        Dim strListName As String = ""

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE LIST LIBRARY

 

        'Declare and initialize a variable for the Lists Web service

        Dim listService As MOSS.Lists = New MOSS.Lists()

 

        'Authenticate the current user by passing their default

        'credentials to the Web service from the system credential cache.

 

        listService.Credentials = networkCredential

 

        'Set the Url property of the service for the path to a subsite.

        listService.Url = String.Format("http://{0}/_vti_bin/Lists.asmx", FileServer)

 

        ' Instantiate an XmlDocument object

        Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()

 

 

        ' Declare an XmlNode object and initialize it with the XML response from the GetListItems method. The last parameter specifies the GUID of the Web site containing the list. Setting it to null causes the Web site specified by the Url property to be used.*/

        Dim nodeListItems As System.Xml.XmlNode = listService.GetListCollection()

        nodeListItems.Normalize()

        For Each node As System.Xml.XmlNode In nodeListItems

            If node.Name = "List" AndAlso node.Attributes("ID").Value = strListID Then

                strListName = node.Attributes("Title").Value

                Exit For

            End If

        Next

        Return strListName

    End Function

 

End Class


    <div>

        <pcoe:SPDocuments ID="SPDocuments1" runat="server" FileServer="<SERVER NAME>/<SITE NAME>" DocumentLibrary="<DOC LIB NAME>" />

    </div>


Like I said this is only a POC I created to demostrate how it can be done. I am sure there are several ways to achomplish the same task. I would be interested in hearing them.
More Posts Next page »