SharePoint 2010 - Receiving error attempting to use SPWebConfigModification - c#

I'm creating a SharePoint feature and within my FeatureReceiver I'm attempting to add a SPWebConfigModification. I've been following the approach outlined in this blog post.
Here is a snippet from my feature receiver:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var webApp = (SPWebApplication)properties.Feature.Parent;
var debugMode = new SPWebConfigModification
{
Path = "configuration/system.web/customErrors",
Name = "mode",
Value = "Off",
Sequence = 0,
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute,
Owner = "MyWebConfigMods"
};
webApp.WebConfigModifications.Add(debugMode); // <------ Error is thrown at this line
webApp.WebService.ApplyWebConfigModifications();
webApp.Update();
}
Here is the stack trace from the error as seen in the SharePoint ULS viewer:
Feature receiver assembly 'MyCompany.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxx', class 'MyCompany.SharePoint.Features.WebConfig.WebConfigFeatureReceiver', method 'FeatureActivated' for feature '3a07b91c-0968-4f14-b2bc-ae0e3f109cf9' threw an exception: System.Xml.XPath.XPathException: '' is an invalid expression.
at MS.Internal.Xml.XPath.XPathScanner..ctor(String xpathExpr)
at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpresion(String xpathExpresion)
at MS.Internal.Xml.XPath.QueryBuilder.Build(String query, Boolean allowVar, Boolean allowKey)
at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver)
at System.Xml.XPath.XPathNavigator.Select(String xpath)
at System.Xml.XmlNode.SelectSingleNode(String xpath)
at Microsoft.SharePoint.Administration.SPWebConfigFileChanges.ApplyModificationsWebConfigXmlDocument(XmlDocument xdWebConfig, String filepath)
at Microsoft.SharePoint.Administration.SPWebApplication.ApplyWebConfigModifications()
at Microsoft.SharePoint.Administration.SPWebService.ApplyWebConfigModifications()
at MyCompany.SharePoint.WebConfigModificationFeatureReceiver.FeatureActivated(SPFeatureReceiverProperties properties)
at Microsoft.SharePoint.SPFeature.DoActivationCallout(Boolean fActivate, Boolean fForce)
Somewhere during the update an empty path is being referenced within an XPath expression. It's not in my feature. Any ideas?

customErrors does not have an attribute named debug, you must be referring to compilation element

This is the code we use:
SPWebApplication wappCurrent = (SPWebApplication)properties.Feature.Parent;
SPWebConfigModification modAuthorizedType = new SPWebConfigModification();
modAuthorizedType.Name = "authorizedType[#Assembly='Infowise.AssociatedTasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=23853b1f8d5855a5']";
modAuthorizedType.Owner = "Infowise.Actions";
modAuthorizedType.Path = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes";
modAuthorizedType.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
modAuthorizedType.Value = #"<authorizedType Assembly=""Infowise.AssociatedTasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=23853b1f8d5855a5"" Namespace=""Infowise.Sharepoint.V3.Fields.Workflow"" TypeName=""*"" Authorized=""True"" />";
wappCurrent.WebConfigModifications.Add(modAuthorizedType);
wappCurrent.Update();
wappCurrent.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
Hope if helps

In my case, wappCurrent.WebConfigModifications had some old values with an invalid Path property. Clearing the array fixed the problem.

Related

AWS .NET SDK SimpleEmail SendEmail returning 'Could not load type' error

I'm developing an application using AWS SimpleEmail. I'm getting the error below when I try to test SendEmail function.
Could not load type 'Amazon.Runtime.Internal.InvokeOptions' from
assembly 'AWSSDK.Core, Version=3.3.0.0, Culture=neutral,
PublicKeyToken=885c28607f98e604'.
I have AWSSDK.Core v3.3.31.7 and AWSSDK.SimpleEmail v3.3.7.30 installed.
var credentials = new BasicAWSCredentials("key", "secret");
var client = new Amazon.SimpleEmail.AmazonSimpleEmailServiceClient(credentials, Amazon.RegionEndpoint.EUWest1);
var sesResponse = client.SendEmail(new SendEmailRequest
{
Destination = new Destination
{
BccAddresses = new List<string>
{
},
ToAddresses = new List<string> {
"user#cuchuma.net",
"user2#cuchuma.net"
}
},
Message = new Message
{
Body = new Body
{
Html = new Content
{
Charset = "UTF-8",
Data = "This message body contains HTML formatting. It can, for example, contain links like this one: <a class=\"ulink\" href = \"http://docs.aws.amazon.com/ses/latest/DeveloperGuide\" target = \"_blank\"> Amazon SES Developer Guide </a>."
},
Text = new Content
{
Charset = "UTF-8",
Data = "This is the message body in text format."
}
},
Subject = new Content
{
Charset = "UTF-8",
Data = "Test email"
}
},
ReplyToAddresses = new List<string>
{
},
ReturnPath = "",
ReturnPathArn = "",
Source = "no-reply#cuchuma.net",
SourceArn = ""
});
string messageId = sesResponse.MessageId;
The class it cannot load was only added 2 months ago. So my suspicion is that you have an older version of AWSSDK.Core than you have stated (v3.3.31.7).
Now I'm not sure how this happens, but I have seen instances in the past where Nuget gets messed up and a manual entry in the project file causes an incorrect dll to be loaded.
Open up your project file in notepad and look for the SDK references. They should look like the following:
<Reference Include="AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL">
<HintPath>..\packages\AWSSDK.Core.3.3.31.7\lib\net45\AWSSDK.Core.dll</HintPath>
</Reference>
<Reference Include="AWSSDK.SimpleEmail, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL">
<HintPath>..\packages\AWSSDK.SimpleEmail.3.3.7.30\lib\net45\AWSSDK.SimpleEmail.dll</HintPath>
</Reference>
Check to see that the package names are indeed AWSSDK.Core.3.3.31.7 and AWSSDK.SimpleEmail.3.3.7.30.
Also check that there are no other random AWSSDK.Core entries.
Lastly... Another issue you might run into, if you don't specify them then don't include the following lines with blank string. It will throw an invalid email address error:
ReturnPath = "",
ReturnPathArn = "",
SourceArn = ""
A variation of #Martin Beeby's answer.
Using the fuslogvw tool I saw that the GAC version of AWSSDK.Core is loaded before attempting to load the local copy. My GAC had an outdated version of the AWSSDK.Core assembly and worse I could not safely uninstall it because there were dependencies. What ended up working was: I navigated to the local copy in my project (something like <solution folder>/packages/AWSSDK.Core.3.5.3.1/) and with an elevated PowerShell prompt I issued:
&"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\gacutil.exe" /i .\AWSSDK.Core.dll
so that the newer version gets installed, and the error went away.
Note: you might have gacutil in a different path and it might even be on the path environment variable so you don't need a path.

C# create instance of type from DLL extending host application type

Is this possible if not could some one please explain how i could implement this to work?
So i have a C# Application and a folder with it called modules, so files:
Application.exe
modules/
Application.Handler.ModuleName.dll
So inside the DLL it has the namespace Application.Handle containing the type ModuleName and ModuleName extends Handler that is implemented in Application.exe so to compile requires Application.exe as a reference.
Inside my host application i have:
string[] dirs = Directory.GetFiles(#"modules/", "Application.Handler.*.dll");
foreach(string filePath in dirs)
{
Assembly.LoadFile(new FileInfo(filePath).FullName);
string fileName = filePath.Split('/').Last();
string typeAssemblyName = fileName.Replace(".dll", "");
string typeName = typeAssemblyName.Split('.').Last();
}
But i'm unsure if i can implement the types from the strings i thought i could with Activator.CreateInstance but i'm not sure if I'm doing it correctly or if the way I'm trying to implement it works?
UPDATE
I might not have been clear but effectively what i need to do is
Application.Handler handler = new Application.Handler.ModuleName() Where Application.Handler.ModuleName in php it's done like below i thought there would be a system that returns an object of the type given in the string. if it's not there throw an exception
$className = "\Application\Handler\ModuleName";
$instance = new $className();
I have also tried using the Unwrap system that #rene suggested
Assembly asm = Assembly.LoadFile(new FileInfo(filePath).FullName);
string fileName = filePath.Split('/').Last();
string typeAssemblyName = fileName.Replace(".dll", "");
string typeName = typeAssemblyName.Split('.').Last();
FrameHandler fh;
fh = (FrameHandler)Activator.CreateInstance(asm.FullName, typeAssemblyName).Unwrap();
fh.RegisterHandlers();
using this method where i give it the Assembly name it gives me a FileNotFoundException and without the Assembly name i get TypeLoadException but it must be loading the manifest of the assembly as Application.Handler.ModuleName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
You just need a handle to the type, so you'll need the assembly path and the type's full name.
var assy = Assembly.LoadFile("...");
var type = assy.GetType("...");
var obj = Activator.CreateInstance(type);

Error with Dependency Injection [Xamarin]

I´m implementing a SQLite database on my app.
I have a SQLite_Android class that handles the DB connection. When I insert the dependency ([assembly: Dependency(typeof(SQLite_Android))]) I get a lot of errors like:
Error retrieving parent for item: No resource found that matches the given name 'Animation.AppCompat.Dialog'
Error retrieving parent for item: No resource found that matches the given name 'TextAppearence.AppCompat.Button'
No resource found that matches the given name: attr 'backgroundTint'.
No resource found that matches the given name: attr 'elevation'.
And finally:
Unexpected error - Please file a bug report at http://bugzilla.xamarin.com. Reason: System.IO.FileNotFoundException: Could not load assembly 'MyProject.App.Engine.Droid, Version=, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?
When I take that dependency line out of the class, the app builds successfully.
What I´ve already tried:
Updating the compiling SDK version
Updating all nuget packages
reinstalled Xamarin.Forms
So, someone please give me any ideas of what I should do to fix this
OBS, here is my Interface and my DBhelper:
[assembly: Dependency(typeof(SQLite_Android))]
namespace MyProject.Device.Engine.Droid.DB
{
public class SQLite_Android : ISQLConfig
{
public SQLite_Android(){}
public SQLite.Net.SQLiteConnection GetConnection()
{
var fileName = "DbFile.db3";
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, fileName);
var platform = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
var connection = new SQLite.Net.SQLiteConnection(platform, path);
return connection;
}
}
namespace MyProject.Device.Engine.Shared.Portable.DB
{
public interface ISQLConfig
{
SQLiteConnection GetConnection();
}
}
You should specify full path to your class [assembly: Dependency(typeof(AppName.Path.SQLite_Android))]
For Example:
[assembly: Dependency(typeof(AppName.Droid.DataBaseHelper.SQLite_Android))]

How to load a signed assembly dynamically in c#

Assembly myDll = Assembly.LoadFrom("D:\\ClassLib.dll, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=173d654960d26d29");
I am getting the exception saying "Could not load the assembly"
Please help me here.
Refer to the MSDN documentation for loading assembly. Try giving just the assembly path as an argument to this method and it would work as per the example in documentation.
In order to check the authenticity of your assembly what you can do is following:
string filePath = "C:/path/to/file.dll";
Assembly assembly = Assembly.LoadFrom(filePath);
Module module = assembly.GetModules().First();
X509Certificate certificate = module.GetSignerCertificate();
if (certificate == null)
{
// file is not signed.
}
As a matter of fact once your assembly is loaded you have most of the properties such as version number etc. in the assembly object.
Based on this article on MSDN website, there is a better way to check validity.
Paste this 2 line of code to the top of your relevant class.
[DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
static extern bool StrongNameSignatureVerificationEx(string wszFilePath, bool fForceVerification, ref bool pfWasVerified);
Load your assembly
var filePath = "C:/whatever.dll";
var assembly = Assembly.LoadFrom(filePath);
Set the last 2 parameters regarding to your needs and call the function.
Little helper table
var alertMessage = "Spoofed!";
var isValid = StrongNameSignatureVerificationEx(filePath, ....);
if (!isValid)
throw new FileNotFoundException(alertMessage, filePath);
Note: As far as I know there is no managed version of this. So, be thread-safe when you use this function!
you can load the Assembly as follows
string path = #"D:\ClassLib.dll";
Assembly assembly = Assembly.LoadFrom(path);
More Sources here

Returning a CLR type from IronRuby

I am trying to return a CLR object from Iron Ruby.
I have the following CLR type defined in C#
public class BuildMetaData
{
public string Description { get; set; }
}
I have the following IronRuby file:
$:.unshift(File.dirname(__FILE__) + '/../bin/Debug')
require 'mscorlib'
require 'Horn.Core.DSL.Domain'
class MetaDataFactory
def return_meta_data()
meta = Horn::Core::DSL::Domain::BuildMetaData.new
meta.Description = "A description of sorts"
meta
end
end
I have the following test that is failing:
[Fact]
public void Then_a_build_metadata_object_is_returned()
{
var engine = Ruby.CreateEngine();
engine.ExecuteFile("test.rb");
var code = String.Format("{0}.new.method :{1}", "MetaDataFactory", "return_meta_data");
var action = engine.CreateScriptSourceFromString(code).Execute();
var result = (BuildMetaData)engine.Operations.Call(action);
Assert.Equal(result.Description, "A description of sorts");
}
It fails when trying to cast the object returned from IronRuby.
I get the following error message:
[A]Horn.Core.DSL.Domain.BuildMetaData cannot be cast to [B]Horn.Core.DSL.Domain.BuildMetaData. Type A originates from 'Horn.Core.DSL.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location 'C:\Projects\horn\branches\rubydsl\src\Horn.Dsl.Specificatioin\bin\Debug\Horn.Core.DSL.Domain.dll'. Type B originates from 'Horn.Core.DSL.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Users\paul.cowan\AppData\Local\Temp\1vt2usw2.rxf\Horn.Dsl.Specificatioin\assembly\dl3\1d5ed945\7c19e429_1a97c901\Horn.Core.DSL.Domain.DLL'.
Is it possible to return CLR types from Iron Ruby
Rather than getting the method with a specially crafted string of Ruby, and then using C# to call the method, the preferred way to call into Ruby code from C# is the following:
var engine = IronRuby.Ruby.CreateEngine()
engine.ExecuteFile("test.rb")
var klass = engine.Runtime.Globals.GetVariable("MetaDataFactory")
var instance = engine.Operations.CreateInstance(klass)
engine.Operations.InvokeMember(instance, "return_meta_data")
~Jimmy
Actually it was all down to shadow copying.
My code ended up looking like this:
[Fact]
public void Then_the_object_should_be_accessible_in_csharp()
{
var engine = Ruby.CreateEngine();
engine.Runtime.LoadAssembly(typeof (BuildMetaData).Assembly);
engine.ExecuteFile(buildFile);
var klass = engine.Runtime.Globals.GetVariable("MetaDataFactory");
var instance = (RubyObject)engine.Operations.CreateInstance(klass);
//You must have shadow-copying turned off for the next line to run and for the test to pass.
//E.g. in R# "ReSharper/Options/Unit Testing/Shadow-Copy Assemblies being tested" should be un-checked.
var metaData = (BuildMetaData)engine.Operations.InvokeMember(instance, "return_meta_data");
Assert.Equal(metaData.Description, "A description of sorts");
Assert.Equal(metaData.Dependencies.Count, 1);
}
But if I turned off shadow-copying from the R# test runner then the test now passes.

Categories