LINQ is awesome solution for creating efficient queries with dynamic WHERE conditions

by jasonvonruden 25. January 2011 14:16

I have been using this method for a long time and I just want to share an example of applying dynamic “WHERE” conditions to make more efficient queries.

For example you could create a query using the “LIKE” verb to handle a query with multiple where clauses when you have the potential of having only 1 parameter and you are expecting the other parameter to wildcard.  You will quickly find out that if field that you are wildcarding with just “%” is null you will not match on it when you where expecting a match. This example of applying dynamic “WHERE” conditions totally solves that solution and it is much cleaner code as an added bonus.

Example of just using ‘LIKE’ conditions:

As you can see the query will be less efficient because you are filtering an a column that you may not need to based on the input parameters provided. Must include the function to convert nulls into empty strings, yuck.

SELECT r
FROM XrfReservation r
WHERE ISNULL(r.ReservationProject,'') like :dd and
      ISNULL(r.ReservationName,'') like :di and
ORDER BY r.ReservationProject, r.ReservationName

Example of of applying dynamic “WHERE” conditions:

As I hope that you will see this code looks nicer and is more efficient!

//*******************************************************************
// Get XrfReservations By ReservationProject and ReservationName
//*******************************************************************
public IList<XrfReservation> GetXrfReservationsByProjectName(string _reservationproject, string _reservationname, int _resultpage, int _resultpagesize)
{
    //Paging Logic
    int firstResult = 0;
    if (_resultpage > 1)
    {
        firstResult = (_resultpage - 1) * _resultpagesize;
    }
 
    //Linq - base query
    var xrfReservations = from r in _Session.Query<XrfReservation>()
                          select r;
 
    //Linq: Apply where clauses
    if (!string.IsNullOrEmpty(_reservationproject))
    {
        xrfReservations = xrfReservations.Where(_w => _w.ReservationProject == reservationProject);
    }
 
    if (!string.IsNullOrEmpty(_reservationname))
    {
        xrfReservations = xrfReservations.Where(_w => _w.ReservationName == _reservationname);
    }
 
    //Linq Apply order by.
    var xrfReservationsOrderBy = from o in xrfReservations orderby o.ReservationProject, o.ReservationName select o;
 
    //Linq: Apply paging.
    IList<XrfReservation> xrfReservationsList = xrfReservationsOrderBy.Skip(firstResult).Take(_resultpagesize);
 
    //Execute Query and return list of data
    return xrfReservationsList.ToList();
}

Tags: , ,

c# | LINQ | NHibernate

SharePoint SIG - InfoPath with SharePoint Code and Slides

by jasonvonruden 17. November 2010 02:49

The recent WI .NET Users Group  - SharePoint Special Interest Group (SharePoint SIG) was a lot of fun yesterday. I spoke about using InfoPath with SharePoint to enhance your users SharePoint experience.

Summary
InfoPath allows you to collect and store form data directly in SharePoint and best of all the actual data is stored as xml. Once the form is stored in a SharePoint form library you can expose any of the form’s data as columns on SharePoint views. InfoPath has the ability to on form load get data from web services, dynamically get and send data to web services based on user interaction, display context sensitive help, and finally submit the form directly into SharePoint so that the user does not have to worry about where to save the form. Think of InfoPath as a Microsoft Word template on steroids! My personal favorite InfoPath feature which is missing from Microsoft Word is unlimited repeatable sections.

My source code includes a complete solution consisting of an InfoPath form that receives data from a locally running  web service.

Tags:

Use SharpZipLIb to create zip file directly from database without saving any temporary files on the hard disk

by jasonvonruden 28. July 2010 00:13

The Goal

I needed to package up inspection photos into a zip file and make them available for download directly from a website.   The inspection photos are stored not stored in the file system, instead they are stored in a MySql database via NHibernate. 

My Approach

Every example that I could find involved reading the database, writing out the files to a temporary working directory on the hard disk,  zip up the files using SharpZipLib, and then delete the temporary files.  

This seemed like a lot of extra work!

So I decided to create my zip file completely in-memory and skip writing out the files to working directory on disk.

Steps:

  1. Determine if inspection has any photo attachments.
  2. Create Zip File Memory Streams using SharpZipLib a .NET compression library that supports Zip files using both stored and deflate compression methods, PKZIP 2.0 style and AES encryption, tar with GNU long filename extensions, gzip, zlib and raw deflate, as well as BZip2.
  3. Read every photo on the database and create zip entries in memory streams.
  4. Finalize the zip file.
  5. Return the zip file to the user via website http response stream.

Generate Inspection Photo Zip File

//*****************************************************************************
//Generate Inspection Photo Zip File
//*****************************************************************************
public byte[] GenerateInspectionPhotosZipFile(Inspection _inspection)
{
    //Open Zip File.
    MemoryStream zipOutMemoryStream = new MemoryStream();
    ZipOutputStream zipOutStream = new ZipOutputStream(zipOutMemoryStream);
 
    //Add Photos to Zip File.
    foreach (var inspectionAttachment in _inspection.fkInspectionAttachments)
    {
        if (inspectionAttachment.Attachment != null && inspectionAttachment.Attachment.Length > 0)
        {
            MemoryStream photoMemoryStream = new MemoryStream(inspectionAttachment.Attachment);
            ZipEntry entry = new ZipEntry(inspectionAttachment.AttachmentName);
            zipOutStream.PutNextEntry(entry);
            byte[] photoBytesBuffer = photoMemoryStream.ToArray();
            zipOutStream.Write(photoBytesBuffer, 0, photoBytesBuffer.Length);
            photoMemoryStream.Dispose();
            zipOutStream.CloseEntry();
        }
    }
    zipOutStream.Finish();
    zipOutStream.Close();
    zipOutMemoryStream.Close();
    byte[] responseBytes = zipOutMemoryStream.ToArray();
    zipOutMemoryStream.Dispose();
    zipOutStream.Dispose();
 
    //Return Null on Empty Zip File
    const int ZIP_FILE_EMPTY = 22;
    if (responseBytes.Length <= ZIP_FILE_EMPTY)
        return null;
 
    return responseBytes;
}

Return Photo to User Via Http Output Response Stream

//*****************************************************************************
 //Build Inspection Photo Zip File
 //*****************************************************************************
 private void GenerateInspectionPhotosZipFile(NHibernateDataProvider _provider, Inspection _inspection)
 {
     //Generate Inspection Photos.
     byte[] responseBytes = _provider.GenerateInspectionPhotosZipFile(_inspection);
 
     //Return Zipfile in Response Output Stream
     if (responseBytes != null)
     {
         //Response Return Zip File
         Response.ContentType = "application/zip";
         Response.AppendHeader("Content-Disposition", string.Format("attachment; filename=InspectionPhotos_{0}_{1}_{2}.zip", _inspection.Id.Inspectionid, _inspection.Bankid, _inspection.Processorid));
         Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
     }
 }

Tags:

c# | NHibernate

Display SharePoint List Contents Outside of SharePoint using LINQ to SharePoint

by jasonvonruden 23. July 2010 12:48

My Project was to create a contacts search page for a SharePoint 2007 list library. Out of the box I could not find SharePoint built in support for searching a list library in a user friendly way.  Creating a SharePoint webpart was not an option at this time due to the pain involved in setting up the development environment and deploying the wepart to SharePoint 2007.

To accomplish this task in the required timeframe, I decided to create the contacts search page on an existing ASP.NET Website and use LINQ to SharePoint to communicate with SharePoint 2007 in an authenticated domain environment with anonymous access disabled.  The ASP.NET webpage can then be embedded in SharePoint using the built-in webpage viewer webpart.

Requirements:

  • SharePoint, for this project SharePoint 2007.
  • ASP.NET Website on an internal IIS web server.
  • LINQ to SharePoint which provides a custom query provider for LINQ that allows you to query SharePoint lists using the familiar LINQ syntax. 

Steps:

  1. Download LINQ to SharePoint and Install.
  2. Navigate to LINQ to SharePoint install location. Default location:  “C:\Program Files\BdsSoft LINQ to SharePoint”
  3. Run SPMetal.exe to generate c# LINQ class based on the SharePoint library.
  4. Create SharePoint Data Access Layer Project: Project source:

  5. SharePointDataAccessLayer
  6. Create SharePointDataProvider.cs class.  The trickiest part figuring out how to pass the was Domain Service User Account’s User Name, Password, and Domain to LINQ To SharePoint.  I also found out that the Domain Service User Account must have full permissions to the SharePoint list library for SharePoint’s data services to work for “LINQ To SharePoint” access.

    SharePointDataProvider.cs Source Listing:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using FrameworkCore;
    using BdsSoft.SharePoint.Linq;
    using FrameworkData;
     
    namespace SharePointCore
    {
        public class SharePointDataProvider : IDisposable
        {
            private readonly NetworkCredential _networkCredential;
     
     
            public SharePointDataProvider(NHibernateDataProviderIg _providerm)
            {
                //Get Sharepoint Credentials
                XrfSetting xrfSettingsUserName = _providerm.GetXrfSettingByName("NetworkServiceAccount-UserName");
                XrfSetting xrfSettingPassword = _providerm.GetXrfSettingByName("NetworkServiceAccount-Password");
                XrfSetting xrfSettingDomain = _providerm.GetXrfSettingByName("NetworkServiceAccount-Domain");
                string sharepointUserName = _providerm.EncryptDecryptText(null, xrfSettingsUserName.SettingText);
                string sharepointPassword = _providerm.EncryptDecryptText(null, xrfSettingPassword.SettingText);
                string sharepointDomain = _providerm.EncryptDecryptText(null, xrfSettingDomain.SettingText);
                _networkCredential = new NetworkCredential(sharepointUserName, sharepointPassword, sharepointDomain);    
            }
     
            public void Dispose()
            {
     
            }
     
            //*******************************************************************
            // Get Sharepoint Regulatory Contacts List Items
            //******************************************************************* 
            public IEnumerable<Contacts> GetSharePointRegulatoryContacts(string _name, string _firmcompany)
            {
                //Initialize Vaiables
                IEnumerable<Contacts> contacts = null;
     
                const string SHAREPOINT_SITE_REGULATORY = "http://YourSharePointServer/Sites/SiteName/";
                var sharePointDataContext = new SharePointDataContext(new Uri(SHAREPOINT_SITE_REGULATORY));
                sharePointDataContext.Credentials = _networkCredential;
                var contactsDataContext = sharePointDataContext.GetList<Contacts>();
                contacts = (from c in contactsDataContext select c).AsEnumerable();
     
                //Apply Filters
                const string DEFAULT_WILDCARD_TYPE = "Contains";
                string name = _name == null ? string.Empty : _name.Replace("*", "%").ToLower();
                string firmCompany = _firmcompany == null ? string.Empty : _firmcompany.Replace("*", "%").ToLower();
     
                if (!string.IsNullOrEmpty(_name))
                {
                    string wildcardType = DetermineFilterWildcardType(name, DEFAULT_WILDCARD_TYPE);
                    if (wildcardType == "Equals")
                    {
                        contacts = (from c in contacts where c.Name.ToLower() == name select c);
                    }
                    else if (wildcardType == "StartsWith")
                    {
                        contacts = (from c in contacts where c.Name.ToLower().StartsWith(name) select c);
                    }
                    else if (wildcardType == "EndsWith")
                    {
                        contacts = (from c in contacts where c.Name.ToLower().EndsWith(name) select c);
                    }
                    else if (wildcardType == "Contains")
                    {
                        contacts = (from c in contacts where c.Name.ToLower().Contains(name) select c);
                    }
                }
     
                if (!string.IsNullOrEmpty(_firmcompany))
                {
                    string wildcardType = DetermineFilterWildcardType(firmCompany, DEFAULT_WILDCARD_TYPE);
                    if (wildcardType == "Equals")
                    {
                        contacts = (from c in contacts where c.FirmCompany.ToLower() == firmCompany select c);
                    }
                    else if (wildcardType == "StartsWith")
                    {
                        contacts = (from c in contacts where c.FirmCompany.ToLower().StartsWith(firmCompany) select c);
                    }
                    else if (wildcardType == "EndsWith")
                    {
                        contacts = (from c in contacts where c.FirmCompany.ToLower().EndsWith(firmCompany) select c);
                    }
                    else if (wildcardType == "Contains")
                    {
                        contacts = (from c in contacts where c.FirmCompany.ToLower().Contains(firmCompany) select c);
                    }
                }
     
                return contacts ?? new List<Contacts>();
            }
     
            //*******************************************************************
            // Determine Filter Wildcard Type Routine
            //*******************************************************************       
            private static string DetermineFilterWildcardType(string _inputvalue, string _defaultwildcardtype)
            {
                if (!_inputvalue.Contains("%"))
                {
                    return _defaultwildcardtype;
                }
                if (_inputvalue.StartsWith("%") && _inputvalue.EndsWith("%"))
                {
                    return "Contains";
                }
                if (_inputvalue.EndsWith("%"))
                {
                    return "StartsWith";
                }
                if (_inputvalue.StartsWith("%"))
                {
                    return "EndsWith";
                }
                return _defaultwildcardtype;
            }
     
        }
    }
  7. Create ASP.NET Contacts Search webpage using the SharePointCore Data Access project.

    ContactsSearch.aspx.cs webpage code-behind Source Listing:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.UI.WebControls;
    using FrameworkCore;
    using SharePointCore;
     
    namespace BdsgIgWeb.Groups.Bpa
    {
        public partial class ContactsSearch : System.Web.UI.Page
        {
            //*******************************************************************
            // Page Load
            //******************************************************************* 
            protected void Page_Load(object _sender, EventArgs _e)
            {
                if (!Page.IsPostBack)
                {
                    //Get Sharepoint Credentials
                    NHibernateDataProviderIg providerM = new NHibernateDataProviderIg(NHibernateStaticSessionManager.SessionFactoryM.GetCurrentSession());
     
                    //Get Regulatory Contacts List
                    using (var sharePointDataProvider = new SharePointDataProvider(providerM))
                    {
                        const string NAME_EMPTY = null;
                        const string FIRM_COMPANY_EMPTY = null;
     
                        //Get Contacts
                        IEnumerable<Contacts> contacts = sharePointDataProvider.GetSharePointRegulatoryContacts(NAME_EMPTY, FIRM_COMPANY_EMPTY);
     
                        //Build Lookup Dropdown Values.
                        BuildLookupLists(contacts);
                    }
                }
            }
     
            //*****************************************************************************
            // Build Program Lookup Values
            //*****************************************************************************
            private void BuildLookupLists(IEnumerable<Contacts> _contacts)
            {
                //Get Contact Names ComboBox Dropdown Values
                var contactNamesDistinct = (from c in _contacts
                                            orderby c.Name
                                            select new { Name = c.Name == null ? string.Empty : c.Name.Trim() }).Distinct();
                cbContactName.DataSource = contactNamesDistinct;
                cbContactName.DataTextField = "Name";
                cbContactName.DataValueField = "Name";
                cbContactName.DataBind();
                cbContactName.Items.Insert(0, new ListItem("", null));
                cbContactName.Width = 200;
     
                //Get FirmCompany ComboBox Dropdown Values
                var firmCompanyNamesDistinct = (from c in _contacts
                                                orderby c.FirmCompany
                                                select new { FirmCompany = c.FirmCompany == null ? string.Empty : c.FirmCompany.Trim() }).Distinct();
                cbFirmCompanyName.DataSource = firmCompanyNamesDistinct;
                cbFirmCompanyName.DataTextField = "FirmCompany";
                cbFirmCompanyName.DataValueField = "FirmCompany";
                cbFirmCompanyName.DataBind();
                cbFirmCompanyName.Items.Insert(0, new ListItem("", null));
                cbFirmCompanyName.Width = 200;
     
     
            }
     
            //*****************************************************************************
            //Search Regulatory Contacts.
            //*****************************************************************************
            protected void btnSearch_Click(object _sender, EventArgs _e)
            {
                ProcessSearchRequest();
            }
     
            //*****************************************************************************
            // Process Search Request
            //*****************************************************************************
            private void ProcessSearchRequest()
            {
                const int STRING_LENGTH_MAX = 150;
                NHibernateDataProviderIg providerM = new NHibernateDataProviderIg(NHibernateStaticSessionManager.SessionFactoryM.GetCurrentSession());
     
                //Get Regulatory Contacts List
                using (var sharePointDataProvider = new SharePointDataProvider(providerM))
                {
                    //Get Contacts
                    IEnumerable<Contacts> contacts = sharePointDataProvider.GetSharePointRegulatoryContacts(cbContactName.Text, cbFirmCompanyName.Text);
     
                    //Apply Filters
                    var contactsfiltered = from c in contacts
                                           orderby c.Name, c.FirmCompany
                                           select new
                                                      {
                                                          Name = c.Name == null ? string.Empty : c.Name.Trim(),
                                                          ContactDetailsLink = string.Format("http://YourSharePointSite/Sites/SiteName/Lists/Contacts/DispForm.aspx?ID={0}", c.ID),
                                                          Title = c.Title == null ? string.Empty : c.Title.Trim(),
                                                          FirmCompany = c.FirmCompany == null ? string.Empty : c.FirmCompany.Trim(),
                                                          Phone = c.Phone == null ? string.Empty : c.Phone.Trim(),
                                                          Cell = c.Cell == null ? string.Empty : c.Cell.Trim(),
                                                          Email = c.Email == null ? string.Empty : c.Email.Trim(),
                                                          EmailMailTo = c.Email == null ? string.Empty : string.Format("mailto://{0}", c.Email.Trim()),
                                                          Address = c.Address == null ? string.Empty : c.Address.Trim(),
                                                          Notes = c.Notes == null ? string.Empty : bdsgIgFrameworkCoreWebUtils.TruncateAndRemoveRtfFromString(c.Notes, STRING_LENGTH_MAX)
                                                      };
     
                    gvContacts.DataSource = contactsfiltered;
                    gvContacts.DataBind();
                }
            }
        }
    }

Project source: 

 

Tags: , ,

c# | SharePoint | LINQ

AjaxControlToolkit ComboBox.Text User Entered Value is Missing When Enter Key is Pressed also the on change events are not called

by jasonvonruden 10. June 2010 04:55

The Issue

The AjaxControlToolkit ComboBox has a .Text attribute and a couple of server side events OnSelectedIndexChanged and OnTextChanged to deal with field changing.

However  the user entered value is missing in the .Text attribute on an enter key press and the “on change” events events are not called.

 

Issue Code Example:

private void BuildFileListDetails(NHibernateDataProvider _providerM)
{
    int resultsPage = Convert.ToInt32(ddlNavPageNumber.Text); 
    const int RESULTS_PAGE_SIZE = 100;
 
    //The Problem: AjaxControlToolkit ComboBox.Text User Entered Value Missing When Enter Key Pressed.
    string searchFileName= cbFileName.Text;  // The cbFileName.Text equals ""
 
    var xrfFiles = _providerM.GetXrfFiles(searchFileName, resultsPage, RESULTS_PAGE_SIZE);
    gvXrfFileList.DataSource = xrfFiles;
    gvXrfFileList.DataBind();
}

The Solution

You need to access the AjaxToolkit "ComboBox" imbedded TextBox control's .Text to access the value entered by user.

I ended up creating Utility Method to fix this issue that is executed before first use of the ComboBox.Text property. Since the AjaxToolKit ComboBox has a drop down sub component, I needed to check the drop down list to see if the new value already exists in the list and add it if it is missing before assigning the new text value.

Solution Code Example:

//*****************************************************************
// Fix AjaxToolKit ComboBox Text when Enter Key is pressed bug.
//*****************************************************************
public void FixAjaxToolKitComboBoxTextWhenEnterKeyIsPressedIssue(AjaxControlToolkit.ComboBox _combobox)
{
  TextBox textBox = _combobox.FindControl("TextBox") as TextBox;
  if (textBox != null)
  {
      if (_combobox.Items.FindByText(textBox.Text) == null)
      {
          _combobox.Items.Add(textBox.Text);
      }
      _combobox.Text = textBox.Text;
  }
 
 
/*****************************************************************
/ Build File List Details.
/*****************************************************************
rivate void BuildFileListDetails(NHibernateDataProvider _providerM)
 
   int resultsPage = Convert.ToInt32(ddlNavPageNumber.Text); 
   const int RESULTS_PAGE_SIZE = 100;
 
   FixAjaxToolKitComboBoxTextWhenEnterKeyIsPressedIssue(cbFilename);
   string searchFileName = cbFileName.Text;
 
   var xrfFiles = _providerM.GetXrfFiles(searchFileName, resultsPage, RESULTS_PAGE_SIZE);
   gvXrfFileList.DataSource = xrfFiles;
   gvXrfFileList.DataBind();
 

Tags:

ASP.NET

Use Case Maker- free application to write organized use cases

by jasonvonruden 17. May 2010 21:10

Check out Case Maker a free application to capture use case information and create use case documentation.

http://sourceforge.net/projects/use-case-maker/

Use Case Maker helps software developers to write organized use cases and to maintain related requirements.

  • Creation and handling of Package, Sub package, Actor and Use Case objects
  • Tree view objects organization
  • Glossary definition
  • Requirements definition
  • Assign detailed attributes to every type of objects
  • Information about use case state, priority, complexity, etc.
  • Flow of events handling of use case
  • Prose representation of use case
  • History handling of modification of state and implementation phases
  • Dynamic selection of defined objects during text creation and editing
  • References keeping between objects and textual instance
  • Automatic replace of names of objects in textual instances
  • Automatic removing of objects in textual instances
  • Save project into XML format
  • Export project into HTML multipage document
  • Export project into PDF document
  • Export project into RTF document
  • Export objects into XMI 1.1 format
  • Multilanguage support via XML configuration file
  • Packages, Actors and Use Cases can be reordered and renumbered
  • Dependency between use cases can be inserted into "Flow of events" section
  • Flow of events behavior and user interface has been redesigned to improve usability

Screenshot

ucm02

Tags:

General

Software Ideas Modeler-free visio alternative to create technical diagrams

by jasonvonruden 17. May 2010 20:59

If you are Looking to create development related technical documentation then this free Visio alternative is for you.  The custom activity based diagram templates look great and are easy to use.  An added bonus is that Software Ideas Modeler can export to EMF, WMF, SVG, PNG, PDF formats.

Software Ideas Modeler is a lightweight and powerful CASE Tool for the creation of UML diagrams and some others. Software Ideas Modeler is freeware (also for commercial-use).

http://www.softwareideas.net/

Diagram Type Supported

* Activity diagram
* Class Diagram
* Communication diagram
* Component Diagram
* Composite Structure Diagram
* Deployment diagram
* Interaction Overview Diagram
* Object diagram
* Package Diagram
* Profile Diagram
* Sequence diagram
* State machine diagram
* Use case diagram

Main features:
* Fast and easy drawing of diagrams
* 13 types of UML diagrams
* 6 types of other diagrams (Data Flow, Mixed, CRC, Requirement, UI, ERD)
* Diagram styling
* Export to EMF, WMF, SVG, PNG, PDF
* Source code generating (C#, VB.NET, SQL DDL)
* Documentation generating

Screenshots

SoftwareIdeasScreenshot01

SoftwareIdeasScreenshot02

Tags:

General

How do I add duplicate copies of a bookmark that already exist in Firefox

by jasonvonruden 13. May 2010 22:56

In Firefox version 3+ the Bookmarks > Bookmark this page does not support creating duplicate / multiple copies of the same bookmark that already exists.

Here is how to create duplicate bookmarks.

  1. On the bookmark on the bookmark menu, use right-click Copy
  2. Right-click in the folder where the copy is desired
  3. Select Paste

Tags:

General

Moving Existing Wordpress Blog on Linux to Windows Hosting

by jasonvonruden 18. April 2010 12:20

 

After purchasing new windows web hosting for several new ASP.NET websites. I decided to also transferring my existing Fantastic Freeware Wordpress Blog that was hosted on the Linux Platform onto my new Windows based Hosting.  My preferred option was to convert the Wordpress blog to BlogEngine.NETusing BlogML XML format, but I ran into a lot of conversion issues. (See below)

The Bottom Line

In the end decided to move Fantastic Freeware Wordpress blog as is from Linux hosting to Windows Hosting with 404 redirect, because the default hosting company’s 404 redirect is prevents url rewriting from working.

Options

Problems

  • The WordPress BlogML Export 1.0a for BlogML 2.0 is creating a BlogML XML file that is not compatible with the BlogEngine.NET import process which must be using BlogML 2.1Now it looks like I am going to have to dive into the source code and the XML. 
  • The RSS import was not an option because the blog has over 3000 entries and Search Engine Optimization (SEO) principles the URL must remain the same after the conversion.
  • The default hosting company’s 404 redirect was preventing url rewriting from working.

Tags: ,

ASP.NET | Wordpress

Wordpress Blog on Windows Hosting using Managed Fusion URL Rewriter

by jasonvonruden 18. April 2010 12:13

The free Managed Fusion URL Rewriteris one of the easiest url rewriters to setup and configure for use with a WordpressBlog or for your general URL Rewriting Needs.

What is Managed Fusion URL Rewriter

Managed Fusion URL Rewriter is a powerful URL manipulation engine based on the Apache mod_rewrite extension. It is designed, from the ground up to bring all the features of Apache mod_rewrite to IIS 6.0 and IIS 7.0. Managed Fusion Url Rewriter works with ASP.NET on Microsoft's Internet Information Server (IIS) 6.0 and Mono XPS Server and is fully supported, for all languages, in IIS 7.0, including ASP.NET and PHP. Managed Fusion Url Rewriter gives you the freedom to go beyond the standard URL schemes and develop your own scheme.

Warning:

If your hosing provider has a default 404 redirect that overrides if a file is not found,  then URL Rewriting will not work, because the url rewrite engine will never see the request.  Please refer to my other blog post about The Easy Way to Setup Wordpress on Windows Hosting with Permalinks

How to Setup Managed Fusion URL Rewriter for Wordpress

  1. Follow the Managed Fusion URL Rewriter setup instructions.
  2. Configure the contents of the ManagedFusion.Rewriter.txt file. (See Below)
  3. Configure the contents of the web.config. (See Below)

ManagedFusion.Rewriter.txt

RewriteEngine On
 
RewriteBase /
 
# wordpress admin folder rewrite rules
RewriteCond %{REQUEST_URI} ^wp-admin/
RewriteRule ^wp-admin/(.*) . /wp-admin/$1 [C]
 
# wordpress includes folder rewrite rules
RewriteCond %{REQUEST_URI} ^wp-includes/
RewriteRule ^wp-includes/(.*) . /wp-includes/$1 [C]
 
# wordpress general rewrite rules
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) /index.php [L]

web.config

<?xml version="1.0"?>
<!-- 
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
    <configSections>
        <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                    <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
                    <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                </sectionGroup>
            </sectionGroup>
        </sectionGroup>
        <section name="managedFusion.rewriter" type="ManagedFusion.Rewriter.Configuration.ManagedFusionRewriterSectionGroup"/>
    </configSections>
    <appSettings/>
    <connectionStrings/>
    
    <managedFusion.rewriter xmlns="http://managedfusion.com/xsd/managedFusion/rewriter">
        <rules engine="Apache" />
    </managedFusion.rewriter>
    
    <system.web>
        <!-- 
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->
        <compilation debug="true">
            <assemblies>
                <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
                <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            </assemblies>
        </compilation>
        <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
        <authentication mode="Windows"/>
        <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.
           <customErrors mode="Off" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>         
        -->
 
        <customErrors mode="Off">
        </customErrors>
 
        <pages>
            <controls>
                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
                <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            </controls>
        </pages>
        <httpHandlers>
            <remove verb="*" path="*.asmx"/>
            <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
        </httpHandlers>
        <httpModules>
            <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add name="RewriterModule" type="ManagedFusion.Rewriter.RewriterModule, ManagedFusion.Rewriter"/>           
        </httpModules>
    </system.web>
    <system.codedom>
        <compilers>
            <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
                <providerOption name="CompilerVersion" value="v3.5"/>
                <providerOption name="WarnAsError" value="false"/>
            </compiler>
            <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
                <providerOption name="CompilerVersion" value="v3.5"/>
                <providerOption name="OptionInfer" value="true"/>
                <providerOption name="WarnAsError" value="false"/>
            </compiler>
        </compilers>
    </system.codedom>
    <!-- 
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    -->
    <system.webServer>
        <validation validateIntegratedModeConfiguration="false"/>
        <modules>
            <remove name="ScriptModule"/>
            <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        </modules>
        <handlers>
            <remove name="WebServiceHandlerFactory-Integrated"/>
            <remove name="ScriptHandlerFactory"/>
            <remove name="ScriptHandlerFactoryAppServices"/>
            <remove name="ScriptResource"/>
            <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        </handlers>
    </system.webServer>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
                <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
                <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

Tags:

Wordpress

The Easy Way to Setup Wordpress on Windows Hosting with Permalinks

by jasonvonruden 18. April 2010 12:11

If you search for how to setup a Wordpress blog using permalinks on windows hosting you will find a lot of hits referring to url rewriting which is very complex and confusing.

In the end going down the url rewriting path is a waste of time especially if you hosting company has a custom 404 redirect in place.

If you are still interested in url rewriting, please see my other blog entry about setting up a Wordpress Blog on Windows Hosting using Managed Fusion URL Rewriter

How-To Get Wordpress Permalinks working on Windows Hosting: 

  1. Install and configure Wordpress as you normally would, including your permalink settings.
  2. To get permalinks to work correctly with no url rewriting needed, change in the hosting control panel the 404 redirect to point Wordpress’s index.php.

That’s It!

Tags: , ,

ASP.NET | Wordpress

BlogEngine.NET Setup and Customization Adventures

by jasonvonruden 12. April 2010 20:46

The main reason that I picked BlogEngine.NET as the blog software for this website is because it is lightweight and easy to use.  I also found it is easy to customize the master page and CSS template to fit my needs.  The website was going to be a development blog so the Windows Live Writer and code snippet plug-in was a requirement.  I am planning to use the BlogML which is an open format derived from XML to store and restore the content of a blog to convert my Fantastic Freeware website from a Wordpress blog to BlogEngine.NET blog. 

 Customizations

What Did Not Worked

  • Converting ASP.NET Website into ASP.NET Web Application. It worked, but extensions feature no longer works, Dropped it because, it had no practical benefit.
  • Wordpress to Blogengine.NET conversion issues.  The WordPress BlogML Export 1.0a for BlogML 2.0 is creating a BlogML XML file that is not compatible with the BlogEngine.NET import process which must be using BlogML 2.1Now it looks like I am going to have to dive into the source code and the XML. (More on this in a future Post)

 

What Still Does Not Work

  • Resolved:  Windows Live Writer Issue: No spell checking (Firefox) - (Editor brakes Firefox's spell check feature) 

Tags: , ,

c# | General | Wordpress | ASP.NET