Thursday, March 25, 2010

The type [ ] provided as the Service attribute value in the ServiceHost directive could not be found.

We have a list of WCF services hosted in IIS, implemented in numerous assemblies.
Testing all the services after each deployment we encounter from time to time the error:


The type [ ] provided as the Service attribute value in the ServiceHost directive could not be found.


Unfortunately, there's no much more info, why the referenced type cannot be found. First, we wrote some test code (actually console application to scan the assemblies and implemented service types). This solution has its limits: starting with differences in security context etc.

Surfing the Web, we found following approach to investigate the problem.

Slightly extending the idea, we created the ASPX page, helping us to test deployed assemblies and implemented as services types.

The page collects on start information about all installed in the virtual directory assemblies (optionally - recursively or just the /bin folder) and lists automatically all implemented types after one assembly is selected.


Here's the screenshot for succeeded call:
clip_image001
... and this one - on failure:
clip_image002
The page source:


------------------START
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Runtime.Remoting" %>
<script runat="server">
    protected override void  OnLoad(EventArgs e)
    {
        if (!IsPostBack)
        {
            initializeAssemblyList();
        }
        base.OnLoad(e);
    }
    private void initializeAssemblyList()
    {
        string[] files;
        DropDownListAssembly.Items.Clear();
        if (!CheckBoxBinFolderOnly.Checked)
        {
            files = System.IO.Directory.GetFiles(Server.MapPath(""), "*.dll", System.IO.SearchOption.AllDirectories);
        }
        else
        {
            files = System.IO.Directory.GetFiles(Server.MapPath("bin"), "*.dll");
        }
        foreach (string file in files)
        {
            DropDownListAssembly.Items.Add(file);
        }
        initializeTypeList("");
    }
    private void initializeTypeList(string assemblyFullName)
    {
        DropDownListType.Items.Clear();
        if (!string.IsNullOrEmpty(assemblyFullName))
        {
            foreach (Type type in System.Reflection.Assembly.LoadFile(assemblyFullName).GetTypes())
            {
                DropDownListType.Items.Add(type.FullName);
            }
        }
    }
    protected void ButtonTest_Click(object sender, EventArgs e)
    {
        try
        {
            TextBoxResult.Text = "";
            ObjectHandle objHandle = Activator.CreateInstance(
                TextBoxAssembly.Text,
                TextBoxType.Text
                );
            TextBoxResult.Text =
            string.Format("Successfully loaded {0} from {1}.",
                objHandle.Unwrap(),
                TextBoxAssembly.Text);
        }
        catch (Exception ex)
        {
            TextBoxResult.Text = ex.Message + "\r\n" + ex.StackTrace;
        }
    }
    protected void DropDownListAssembly_SelectedIndexChanged(object sender, EventArgs e)
    {
        try
        {
            TextBoxResult.Text = "";
            string assemblyFullName = DropDownListAssembly.SelectedValue;
            string[] chunks = assemblyFullName.Split('\\');
            string assemblyName = chunks[chunks.Length - 1];
            assemblyName = assemblyName.Replace(".dll", "");
            TextBoxAssembly.Text = assemblyName;
            TextBoxType.Text = "";
            initializeTypeList(assemblyFullName);
        }
        catch (Exception ex)
        {
            TextBoxResult.Text = ex.Message + "\r\n" + ex.StackTrace;
        }       
    }
    protected void DropDownListType_SelectedIndexChanged(object sender, EventArgs e)
    {
        TextBoxResult.Text = "";
        string typeName = DropDownListType.SelectedValue;
        TextBoxType.Text = typeName;
    }
    protected void CheckBoxBinFolderOnly_CheckedChanged(object sender, EventArgs e)
    {
        try
        {
            initializeAssemblyList();
        }
        catch (Exception ex)
        {
            TextBoxResult.Text = ex.Message + "\r\n" + ex.StackTrace;
        }             
    }
</script>
<% %>
<html>
<head>
<style type="text/css" media="screen">
    body {font-family: @Arial Unicode MS; font-size: x-small; background-color:silver;}
    span {font-family: @Arial Unicode MS; font-size:x-small}  
    .button {font-family: @Arial Unicode MS; font-size: x-small;}
    .textbox { width: 700 px;font-family: @Arial Unicode MS; font-size: x-small;}
    .dropdown { width: 700 px; font-family: @Arial Unicode MS; font-size: x-small;}
    .textboxmulti { width: 700 px; height: 400 px;font-family: @Arial Unicode MS; font-size: x-small }
    .validator { width: 700 px;font-family: @Arial Unicode MS; font-size: x-small; color: Red;}
</style>
</head>
<form id="form1" runat="server">
<div><asp:Label ID="LabelAssembly"  AssociatedControlID="TextBoxAssembly" runat="server" Text="Enter Assembly Name:"></asp:Label></div>
<div>
    <asp:requiredfieldvalidator runat="server"
        errormessage="Assembly name missing!" ControlToValidate="TextBoxAssembly"
        Display="Dynamic" SetFocusOnError="True" CssClass="validator"></asp:requiredfieldvalidator></div>
<div><asp:TextBox ID="TextBoxAssembly" runat="server" CssClass="textbox"></asp:TextBox></div>
<div><asp:Label ID="LabelSelectAssembly"  AssociatedControlID="DropDownListAssembly" runat="server" Text="...or select from list:"></asp:Label></div>
<div><asp:checkbox ID="CheckBoxBinFolderOnly" Text="'bin' folder only"
        runat="server" AutoPostBack="True"
        oncheckedchanged="CheckBoxBinFolderOnly_CheckedChanged"></asp:checkbox>
</div>
<div>   
    <asp:dropdownlist runat="server" ID="DropDownListAssembly"
        onselectedindexchanged="DropDownListAssembly_SelectedIndexChanged"
        AutoPostBack="True" CssClass="dropdown">
        </asp:dropdownlist>
    </div>
<div><asp:Label ID="LabelType"  AssociatedControlID="TextBoxType" runat="server" Text="Enter Fulltypename:"></asp:Label></div>
<div>
    <asp:requiredfieldvalidator runat="server"
        errormessage="Type name missing!" ControlToValidate="TextBoxType"
        Display="Dynamic" SetFocusOnError="True" CssClass="validator"></asp:requiredfieldvalidator></div>
<asp:TextBox ID="TextBoxType" runat="server" CssClass="textbox"></asp:TextBox></div>
<div><asp:Label ID="LabelSelectType"  AssociatedControlID="DropDownListType" runat="server" Text="...or select from list:"></asp:Label></div>
<div>
    <asp:dropdownlist runat="server" ID="DropDownListType"
        onselectedindexchanged="DropDownListType_SelectedIndexChanged"
        AutoPostBack="True" CssClass="dropdown">
        </asp:dropdownlist>
    </div>
<div><asp:Button ID="ButtonTest" runat="server" Text="Test load type" onclick="ButtonTest_Click" /></div>
<div><asp:Label ID="LabelResult"  AssociatedControlID="TextBoxResult" runat="server" Text="Result:"></asp:Label></div>
<div>
    <asp:TextBox ID="TextBoxResult" runat="server" ReadOnly="True"
        TextMode="MultiLine" CssClass="textboxmulti"></asp:TextBox>
</div>
</form>
</html>
------------------END

1. Copy the text.

2. Save in an ASPX file (for example, TestService.aspx).

3. Put the file in Virtual Directory hosting your Services.
clip_image004

4. Call the page to ensure, the assemblies and the servicing types can be loaded.

Enjoy!

(This post is created with Windows Live Writer)

1 comment:

winmike said...

...or use Core Configurator
http://coreconfig.codeplex.com/Wikipage