Have a SharePoint site on one of our servers and have lately added a new hostname to that server to access a new site collection. I started getting a lot of entries in the eventlog using event id 2436 stating:
The start address <https://newhostname.domain.com> cannot be crawled.
Context: Application 'Search index file on the search server', Catalog 'Search'
Details:
Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content. (0x80041205)
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Another symptom on this error is that if you open a web browser on the server itself and try to navigate to the url, you'll only get an authentication dialog (symptom on a 401 error).
After a bit of searching I found a solution that I recognized. The following kb article http://support.microsoft.com/kb/971382 provided the solution to add the new hostname to the registry key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\BackConnectionHostNames .
When I started regedit I found that the key already existed and a couple of hostnames already was present. It seems that I had implemented this fix before.
Better to write a post about it so I don't forget it in the future :)
Ps. Don't forget to restart the server after applying the registry change. Ds.
2009-06-24
Export and Import Work item queries in TFS projects
I have lately been introducing new WorkItemTypes in our TFS project to handle tests and support cases. With those new types the need for modifying the queries in the current projects was necessary. To modify a query I could have opened them in visual studio and saved them to disk and then saved them individually to each project. Since we are getting a lot of projects (60+) this would be a quite tedious task to update 10+ queries in each project individually.
To solve this administrative plague I wrote a small commandline program that allows you to export and import queries from a project.
Example
To list all queries in a project
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project"
This will list every Work Item Query by Scope, Name and description
To export all queries to the current folder
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Export /q *
This will export each query using the name of the query (plus the .wiq extension) as name of the exported file. If you want to only export one query, use the example below.
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Export /q "My query"
To import all *.wiq files to a project as Team queries
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Import /f *.wiq /qs Public
This command will use the filename (without the .wiq extension) as name for the imported query.
You can also specify a Description of the query by using the /qd switch (best for use with one query imports)
The format of the wiq files follows the WorkItemQuery schema but since the schema only includes the query and no meta data (like name, scope or description) this has to be provided as parameter switches... (Perhaps something to fix in TFS 2010)
If you need more help add the /? parameter.
I haven't released the program as open source but feel free to use it if you have need for it.
Can be downloaded from http://dan.meridium.se/TfsQueryUtil.rar
To use it you need to have Team Foundation Explorer 2008 installed. (needs the tfs dlls in the GAC).
2009-09-28 Update; small bugfix
* Now writes xml files as utf-8 (was an in consequence between xml notation and file encoding)
To solve this administrative plague I wrote a small commandline program that allows you to export and import queries from a project.
Example
To list all queries in a project
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project"
This will list every Work Item Query by Scope, Name and description
To export all queries to the current folder
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Export /q *
This will export each query using the name of the query (plus the .wiq extension) as name of the exported file. If you want to only export one query, use the example below.
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Export /q "My query"
To import all *.wiq files to a project as Team queries
TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Import /f *.wiq /qs Public
This command will use the filename (without the .wiq extension) as name for the imported query.
You can also specify a Description of the query by using the /qd switch (best for use with one query imports)
The format of the wiq files follows the WorkItemQuery schema but since the schema only includes the query and no meta data (like name, scope or description) this has to be provided as parameter switches... (Perhaps something to fix in TFS 2010)
If you need more help add the /? parameter.
I haven't released the program as open source but feel free to use it if you have need for it.
Can be downloaded from http://dan.meridium.se/TfsQueryUtil.rar
To use it you need to have Team Foundation Explorer 2008 installed. (needs the tfs dlls in the GAC).
2009-09-28 Update; small bugfix
* Now writes xml files as utf-8 (was an in consequence between xml notation and file encoding)
2009-05-05
New version of DocumentatorMacros
Long time since last version was released officially... (almost two years), time to make a change.
New version can be downloaded from http://dan.meridium.se/DocumentatorMacros/v2.5.2.0/Meridium.rar
(For more information about the Documentator Macros, see http://www.codeproject.com/KB/cs/documentatormacros.aspx )
New version contains some news:
New version can be downloaded from http://dan.meridium.se/DocumentatorMacros/v2.5.2.0/Meridium.rar
(For more information about the Documentator Macros, see http://www.codeproject.com/KB/cs/documentatormacros.aspx )
New version contains some news:
Contains support for Resharper 4.5, Visual studio 2008 and some minor changes.
Enhancements /Bugfixes
- No longer enters wrong type of linefeeds when applying some functions
- PasteTemplate
- now indents correctly
- Handles static events
- Handles new, virtual, override keywords when converting fields->property
- DocumentThis - Now autodocuments thrown exceptions
2009-05-04
AssemblyName.GetPublicKeyToken() ToString using lambda
I was searching for a convenient way to get the public key token from a signed assembly and present it in an ordinary string style that is found in all FQ assembly names. The problem is that the GetPublicKeyToken() method from the Assembly type returns a byte array and using ToString() isn’t that great.
I searched the net a bit and all I found was examples on how to do it with a loop and using ToString(”x2”) on every byte, or even more horrible, indexing the 8 bytes by hand...
But if I use a linq/lambda expression, this could be a nice one-liner? ’aye?!
Ok, first convert the byte array to a string array
I searched the net a bit and all I found was examples on how to do it with a loop and using ToString(”x2”) on every byte, or even more horrible, indexing the 8 bytes by hand...
But if I use a linq/lambda expression, this could be a nice one-liner? ’aye?!
Ok, first convert the byte array to a string array
GetPublicKeyToken().Select(x=>x.ToString(”x2”))Then aggregate (i was trying the concat first, but that didn’t make any sense) to a single string.
.Aggregate((x, y) => x + y)With some error handling this boils down to the following method.
#region public static string GetAssemblyPublickKeyToken(Assembly assembly)
/// <summary>
/// Gets the public key token of the supplied argument
/// </summary>
/// <param name="assembly">The <see cref="Assembly">to get the public key token for</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException">If <paramref name="assembly">is null.</exception>
public static string GetAssemblyPublickKeyToken(Assembly assembly) {
if (assembly == null) {
throw new ArgumentNullException("assembly");
}
byte[] token = assembly.GetName().GetPublicKeyToken();
if(token == null token.Length==0)
return null;
return token.Select(x => x.ToString("x2")).Aggregate((x, y) => x + y);
}
#endregion
2009-01-21
RadioButton helper and label
When using Mvc (beta) and rendering RadioButtons using the HtmlHelper they are rendered without any text or description. The label tag is used for this but is not rendered by the RadionButtons method.
Example;
Then the problem occurs if we should use multiple radio buttons with the same name.
Example;
renders
This it not so well since we need different id attributes to be able to bind the label tags.
To fix this we need to add different ids to the input tags.
Example:
Example;
<%=Html.RadioButton("MyRadioButton","MyValue")%>renders<input id="MyRadioButton" value="MyValue" name="MyRadioButton" type="radio">To get the label we just add the label tag and uses the input tags id as reference for the label.
<label for="MyRadioButton">My description</label>This will allow us to check the radio button by clicking on the label as well.
Then the problem occurs if we should use multiple radio buttons with the same name.
Example;
<%=Html.RadioButton("IsItRaining","Yes")%>
<%=Html.RadioButton("IsItRaining","No")%>This will renderrenders
<input id="IsItRaining" value="Yes" name="IsItRaining" type="radio">
<input id="IsItRaining" value="No" name="IsItRaining" type="radio">
This it not so well since we need different id attributes to be able to bind the label tags.
To fix this we need to add different ids to the input tags.
Example:
<%=Html.RadioButton("IsItRaining", "Yes", new {id="IsItRaining_Yes"})%><label for="IsItRaining_Yes">Yes</label>
<%=Html.RadioButton("IsItRaining", "No", new {id="IsItRaining_No"})%><label for="IsItRaining_No">No</label>That will produce the intended output;<input id="IsItRaining_Yes" type="radio" value="Yes" name="IsItRaining"/>And will work as below
<label for="IsItRaining_Yes">Yes</label>
<input id="IsItRaining_No" type="radio" value="No" name="IsItRaining"/>
<label for="IsItRaining_No">No</label>
2008-11-27
The GetField method
Last month I wrote an article about clicking a button in a winforms application and in my code example I referred to the ReflectionUtil.GetField method.
The ReflectionUtil class is an utility class that I have used for several years and they provide a better/easier way to use reflection. They are in line to be converted as Extension methods for the Type type, but for now they are ordinary static methods.
I'll post the GetField method to allow the example to be complete.
The GetField only wraps the InvokeMember method. (I have more wrappers named GetProperty, SetField, SetProperty, InvokeMethod, InvokeStaticMethod etc. that calls the InvokeMember method)
Hope the click button example can make more sense now :)
The ReflectionUtil class is an utility class that I have used for several years and they provide a better/easier way to use reflection. They are in line to be converted as Extension methods for the Type type, but for now they are ordinary static methods.
I'll post the GetField method to allow the example to be complete.
#region public static object GetField(Type type, string name, object instance)
/// <summary>
/// Gets the field from the instance
/// </summary>
/// <param name="type">The <see cref="Type"/> that contains the field</param>
/// <param name="name">The name of the field</param>
/// <param name="instance">The instance to get the value from</param>
/// <returns>The value of the field</returns>
public static object GetField(Type type, string name, object instance) {
return InvokeMember(type, name, instance, BindingFlags.GetField | BindingFlags.Instance);
}
#endregion
The GetField only wraps the InvokeMember method. (I have more wrappers named GetProperty, SetField, SetProperty, InvokeMethod, InvokeStaticMethod etc. that calls the InvokeMember method)
#region public static object InvokeMember(Type type, string name, object instance, BindingFlags flags, params object[] parameters)
/// <summary>
/// Invokes the member
/// </summary>
/// <param name="type">The <see cref="Type"/> that contains the member</param>
/// <param name="name">The name of the member</param>
/// <param name="instance">The instance to invoke on</param>
/// <param name="flags">The <see cref="BindingFlags"/> to use</param>
/// <param name="parameters">The <see cref="object"/> array to pass as parameters</param>
/// <returns>The returnvalue</returns>
public static object InvokeMember(Type type, string name, object instance, BindingFlags flags, params object[] parameters) {
if (instance == null) {
flags |= BindingFlags.Static;
flags &= ~BindingFlags.Instance;
}
try {
return type.InvokeMember(name,BindingFlags.Public | BindingFlags.NonPublic | flags,null,instance,parameters);
//if the target threw an exception, throw this instead.
} catch (TargetInvocationException e) {
// if no exception is found, throw the TIException instead.
if (e.InnerException == null)
throw;
throw e.InnerException;
}
}
#endregion
Hope the click button example can make more sense now :)
2008-11-02
Mvc for Winforms - Mapping the View event to the Controller action Part II
This time I will try to deliver part of the answer to the requirements from my previous post. To recap I would like to be able to connect a component to a controller action by calling the RegisterAction method like below.
We start by creating the RegisterAction method. We get the object which event should be listened to and sometimes also the name of the event that we should listen to. If this argument isn't supplied we need to find the DefaultEvent of the object.
By using reflection we can retrieve the DefaultEventAttribute of the object. The following unit test shows how to get the attribute for a Button object. Notice the true flag on the GetCustomAttributes call. Since the DefaultEventAttribute is not present on the Button class itself, we need to go down in the inheritance chain to look for the attribute. Not until we reach the Control class we find the DefaultEventAttribute.
Now when we have the name of the event (either by parameter or using the DefaultEventAttribute) we should add listener to the event. The listener method is a method in the Controller class, not the controller Action (we will get to that in the next part), but a event hub where all the Views events will pass before they are dispatched to the correct Action. The event hub method is declared as below
So we got the object and the name of the event and the target method of the event, but how can we connect them?
My first thought was to generate a delegate to the ExecuteAction and use reflection to get the EventInfo for the event and use the AddEventHandler of the EventInfo class to bind to the ExecuteAction method.
The conclusion of this is that if I would like to have a single method that acts as an event hub and it must be able to handle any type of delegate that the event declares (note that events as practice should always return void and take two arguments, object and a instance of an EventArgs derived class), I need to generate this method in runtime.
The first option that comes to mind is using Emit. I have tested this in the past, it has worked but comes not so natural to me. Oren Eini used this technique but since I would like to pass a local variable (the ActionData instance) in the call, I needed to modify this piece of code, and possibly use an external list of ActionData instances if I couldn't pass them along using the dynamic method, I searched a bit more for an alternative (second opinion)...
Finally I came across an answer from Mark Cidade that compiled a method in runtime using lambda expressions and that was fairly easy to modify.
First we need to setup the call to the ExecuteAction method. This is done using a lambda expression and storing it in the Action delegate .
The complete test follows.
Anyway, that concludes part II and next we will look how to call the action method of the controller from the ExecuteAction method.
Controller.RegisterAction(saveButton, "Save");And letting those events call the actions defined below
Controller.RegisterAction(createBoldTextButton, "CreateText", new {name="Bold", type=4});
Controller.RegisterAction(myTextBox, "ValidateText","Validating", null);
public void Save() {...}
public void CreateText(string name, int type) {...}
public void ValidateText(CancelEventArgs e, object source) {...}
I will divide the solution in two steps and in this post I will cover the first, that is capturing the event of the object.We start by creating the RegisterAction method. We get the object which event should be listened to and sometimes also the name of the event that we should listen to. If this argument isn't supplied we need to find the DefaultEvent of the object.
By using reflection we can retrieve the DefaultEventAttribute of the object. The following unit test shows how to get the attribute for a Button object. Notice the true flag on the GetCustomAttributes call. Since the DefaultEventAttribute is not present on the Button class itself, we need to go down in the inheritance chain to look for the attribute. Not until we reach the Control class we find the DefaultEventAttribute.
[Test]When we have the attribute, we just look at the Name property to get the name of the default event.
public void GetDefaultEventAttribute() {
object obj = new Button();
DefaultEventAttribute attribute = null;
Attribute[] attributes = obj.GetType().GetCustomAttributes(typeof(DefaultEventAttribute), true) as Attribute[];
if (attributes != null && attributes.Length > 0) {
attribute = attributes[0] as DefaultEventAttribute;
}
Assert.IsNotNull(attribute);
}
Now when we have the name of the event (either by parameter or using the DefaultEventAttribute) we should add listener to the event. The listener method is a method in the Controller class, not the controller Action (we will get to that in the next part), but a event hub where all the Views events will pass before they are dispatched to the correct Action. The event hub method is declared as below
public void ExecuteAction(object source, object eventArgs, ActionData actionData)The ExecuteAction method takes three parameters. The source and arguments of the event that was fired (this is the same values that the original event passes along). The third parameter contains the data for the action that is to take place, like the name of the action and any value parameters (The values that are stated when registering the action).
So we got the object and the name of the event and the target method of the event, but how can we connect them?
My first thought was to generate a delegate to the ExecuteAction and use reflection to get the EventInfo for the event and use the AddEventHandler of the EventInfo class to bind to the ExecuteAction method.
[Test]But when I ran this code I got an Exception
public void BindToButtonClickEvent() {
object obj = new Button();
EventInfo info = obj.GetType().GetEvent("Click");
MethodInfo method = GetType().GetMethod("ExecuteAction");
Delegate d = Delegate.CreateDelegate(typeof(MyExecuteAction),method);
info.AddEventHandler(obj,d);
}
private delegate void MyExecuteAction(object source, object eventArgs, ActionData actionData);
public void ExecuteAction(object source, object eventArgs, ActionData actionData) {}
System.ArgumentException: Error binding to target method.Of course this won't work since the Click event cannot directly connect to the ExecuteAction method because the Click event can only add handlers that matches the EventHandler delegate, a method with a void return value and two arguments, object and EventArgs.
The conclusion of this is that if I would like to have a single method that acts as an event hub and it must be able to handle any type of delegate that the event declares (note that events as practice should always return void and take two arguments, object and a instance of an EventArgs derived class), I need to generate this method in runtime.
The first option that comes to mind is using Emit. I have tested this in the past, it has worked but comes not so natural to me. Oren Eini used this technique but since I would like to pass a local variable (the ActionData instance) in the call, I needed to modify this piece of code, and possibly use an external list of ActionData instances if I couldn't pass them along using the dynamic method, I searched a bit more for an alternative (second opinion)...
Finally I came across an answer from Mark Cidade that compiled a method in runtime using lambda expressions and that was fairly easy to modify.
First we need to setup the call to the ExecuteAction method. This is done using a lambda expression and storing it in the Action
ActionData actionData = new ActionData("Save", null);
//Create the delegate using an lambda expression
Action<object,object> eventHubCall = (source, e) => ExecuteAction(source, e, actionData);
This action will take two parameters and call the ExecuteAction just the way as we would like it to. The problem is that this expression is not typed the correct way as the event is so we need to create a new method using lambda expressions again but with the correct declaration. So we start by getting the information about the event.Type type = obj.GetType();Then we create the lambda
EventInfo evt = type.GetEvent("Click");
ParameterInfo[] eventParams = evt.EventHandlerType.GetMethod("Invoke").GetParameters();
ParameterExpression[] parameters = eventParams.Now we have a method with two parameters of the correct type, the only thing left is to create a delegate that we can use for adding to the event.
Select(p => Expression.Parameter(p.ParameterType, "x")).ToArray();
MethodCallExpression body = Expression.Call(Expression.Constant(eventHubCall),
eventHubCall.GetType().GetMethod("Invoke"), parameters);
LambdaExpression lambda = Expression.Lambda(body, parameters);
Delegate proxy = Delegate.CreateDelegate(evt.EventHandlerType, lambda.Compile(), "Invoke", false);Tada!! No more Error binding to target method errors.
evt.AddEventHandler(obj, proxy);
The complete test follows.
[Test]Not so dumb ey! All credits goes to Mark Cidade for providing the elegant solution. (So I perhaps my greatest talent is to find solutions that others have done before me, and use them ;)
public void BindToButtonClickEvent2() {
ActionData actionData = new ActionData("Save", null);
//Create the delegate using an lambda expression
Action<object,object> eventHubCall = (source, e) => ExecuteAction(source, e, actionData);
object obj = new Button();
//find the exact definition of the event
Type type = obj.GetType();
EventInfo evt = type.GetEvent("Click");
ParameterInfo[] eventParams = evt.EventHandlerType.GetMethod("Invoke").GetParameters();
//create a new lambda expression using the correct parameters
ParameterExpression[] parameters = eventParams.
Select(p => Expression.Parameter(p.ParameterType, "x")).ToArray();
//call the event hub
MethodCallExpression body = Expression.Call(Expression.Constant(eventHubCall),
eventHubCall.GetType().GetMethod("Invoke"), parameters);
//create the expression with the correct parameters to match the event
LambdaExpression lambda = Expression.Lambda(body, parameters);
//and then create the delegate that wraps the lambda expression.
Delegate proxy= Delegate.CreateDelegate(evt.EventHandlerType, lambda.Compile(), "Invoke", false);
evt.AddEventHandler(obj, proxy);
}
Anyway, that concludes part II and next we will look how to call the action method of the controller from the ExecuteAction method.
Subscribe to:
Posts (Atom)