While creating a custom Sharepoint web service I received an error while attempting to serialise a class for transmission.
There are no errors with my serializable classes. They are structured in a manner I have used before and can be serialised successfully on a local test environment, the issue only arises when the Sharepoint web service has been deployed.
System.InvalidOperationException was caught
Message=There was an error generating the XML document.
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
at SPServiceExtensions.DTOSerializerHelper.SerializeDTO(SharepointDTO dto)
InnerException: System.Security.SecurityException
Message=Request failed.
Source=xo46jp-i
StackTrace:
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterSharepointDTO.Write4_SharepointDTO(String n, String ns, SharepointDTO o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterSharepointDTO.Write5_SharepointDTO(Object o)
InnerException:
The inner SecurityException was unfamiliar. What is causing this Exception?
ASP.NET uses different trust levels for it's security policies. This is so applications cannot access the data from other unrelated applications.
Microsoft Sharepoint has two additional code access levels of its own and by default runs on WSS_Minimal.
As the webservice is operating as a local application on the Sharepoint server it requires Full Trust
However Microsoft discourages applying full trust willy nilly. I gather that it potentially allows other applications to call your code which has the potential of being used maliciously to exploit the system.
So a better way to prevent the SecurityException is to modify the projects AssemblyInfo.cs and add this attribute [assembly:AllowPartiallyTrustedCallers] to it.
Microsoft's article on Code Access Security.
Related
When I call a COM function passing a SAFEARRAY of UDT's (VT_RECORD) from .Net 7, I get the following exception:
System.Runtime.InteropServices.COMException
HResult=0x80131165
Message=Typelib export: Type library is not registered. (0x80131165)
Source=System.Private.CoreLib
StackTrace:
at System.StubHelpers.MngdSafeArrayMarshaler.ConvertSpaceToNative(IntPtr pMarshalState, Object& pManagedHome, IntPtr pNativeHome)
at IServer.ComputePi(ExampleStruct[] param)
at ManagedClient.Program.Main(String[] _)
The exception does not occur on .Net Framework or from native clients. It does not occur when the struct is not used in a SAFEARRAY or VARIANT. The type library is indeed registered. Reviewing registry access from the client with procmon shows that it appears to be looking for some arbitrary typelib - not the correct one.
Example struct (full idl) based on Out-of-process COM Server Demo
typedef [uuid(7C88E088-A91F-4AE0-B7BA-B1594CCFCD7E), version(1.0)] struct ExampleStruct {
long x;
} ExampleStruct;
and the parameter:
HRESULT ComputePi([in] SAFEARRAY(ExampleStruct) param);
Why does this exception occur?
The error indicates that the .Net SafeArray marshaller cannot load the typelib for the struct. Confusingly, while the tlb containing the structs has indeed been registered, .Net cannot locate it. .Net locates the typelib for a struct by examining the containing assembly.
Unless the assembly has the GuidAttribute to specify a typelib ID, it calculates an id from the assembly name, version, and other factors. In .Net Framework, this did not cause issues so long as tlbexp/tlbimp were used since [assembly: GuidAttribute()] was added automatically (though it would break even then if Embed Interop Types was enabled).
There are several ways to fix the sample:
Specify [assembly: Guid("46F3FEB2-121D-4830-AA22-0CDA9EA90DC3")] in Contract/IServer.cs to make the assemblies match the midl generated typelibNote: In a non-trivial example where a client may call upon multiple different type-libs, it is necessary to move the COM imports and structs to a separate assembly (1:1 per tlb similar to those generated by tlbimp)
Use a tool such as dscom tlbexport to create the tlb from the assembly (reducing the chance of mismatches both in guids and in binary interface). An example of such a solution is available at github in NetCoreOop
I have an asp.net core 3.1 app with AD authentication that works fine. We are migrating it to a new infra setup, with a new set of CI/CD pipelines that use terraform. After re-deployment it fails with the above error (full stack trace below). Any idea what could be causing it?
It uses a containerized build so in theory everything should be the same, apart from the Azure components. As the error has to do with Authentication/Authorization, I have reviewed the AD app registration very closely. I believe I've got it as close as is possible with terraform. Could it be a peculiarity with the app registration that terraform is not supporting? I'm linking the two app manifests (stripped of company-specific data). I'm also doing a detailed comparison of all the differences, under the stack trace.
AD app manifest (old, which works): https://drive.google.com/file/d/187LFczxaReqZLxDrlv7SoWA8nEccUqOj/view?usp=sharing
AD app manifest (new one, broken): https://drive.google.com/file/d/1a0ygOo7MvBt6enro3J5DaBvj6lP9HzH6/view?usp=sharing
Additional info that may be relevant - the app uses swagger, which for some reason has its own app registration. I have yet to investigate that aspect in comparable detail
Review of the differences:
replyUrlsWithType - I'm guessing this is governed by the
redirect_uris param in terraform, which doesn't let me change it for
apps of type 'api', only for web, spa and public_client
signInUrl -
this doesn't seem to exist in the terraform module at all, it's
probably a copy of the above (the values are the same in the legacy
app)
acceptMappedClaims - ends up as 'false' even if I hardcode null into the terraform script
optionalClaims - null v an object with 3 empty arrays; I can't
seem to get it to spit out the latter with terraform
This seems to be it - the rest of the differences seem to be IDs and names. I can't think of anything else that's different between the two environments. It's on two different Azure subscriptions (same AD tenant) and all other dependencies are different (storage, sql db, azure service bus, azure search, etc.) but if there was an issue with these I would expect the error to indicate the same.
Full stack trace:
Application startup exception: System.InvalidOperationException:
Unable to find the required services. Please add all the required
services by calling 'IServiceCollection.AddAuthorization' inside the
call to 'ConfigureServices(...)' in the application startup code.
at
Microsoft.AspNetCore.Builder.AuthorizationAppBuilderExtensions.VerifyServicesRegistered(IApplicationBuilder
app) at
Microsoft.AspNetCore.Builder.AuthorizationAppBuilderExtensions.UseAuthorization(IApplicationBuilder
app) at
projectname.WebApi.Startup.DefaultHttpPipeline(IApplicationBuilder
app) in /app/projectname.WebApi/Startup.cs:line 360 at
projectname.WebApi.Startup.ConfigureDevelopment(IApplicationBuilder
app) in /app/projectname.WebApi/Startup.cs:line 317 at
System.RuntimeMethodHandle.InvokeMethod(Object target, Object[]
arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object
instance, IApplicationBuilder builder) at
Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.b__0(IApplicationBuilder
builder) at
Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder
app) at
Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder
app) at Microsoft.AspNetCore.Hosting.WebHost.BuildApplication()
Next steps I've planned to try:
Get the Client ID & Client secret of the new app reg (provisioned via terraform) and stick them manually into the old app (it's the same AD tenant so there shouldn't be access issues). If we get the same error - this confirms the problem is with the app registration.
Comment out everything to do with swagger to make sure it's not it
Migrate the whole thing to .net 6 - it has to be done anyway, maybe we'll get a better error message
Figured it out finally, there was a wrong value for the swagger app registration client ID.
I'll explain what I've done so far. I'm using VS2010.
Firstly I've created a ASP.NET Web Service Application (framewkork 3.5) with a service with these operations:
[WebMethod]
public Boolean ShoppingTripNeeded(DateTime d)
{
DBConnection db = new DBConnection();
return db.ShoppingTripNeeded(d);
}
[WebMethod]
public String[] ShopsToVisit(DateTime d)
{
DBConnection db = new DBConnection();
return db.ShopsToVisit(d);
}
[WebMethod]
public Item[] ItemsToBuy(DateTime d, String shop)
{
DBConnection db = new DBConnection();
return db.ItemsToBuy(d, shop);
}
And now I'm creating a WCF Workflow Service Application, in which I want to call sequently the 3 methods above, so I've added a Service Reference to my service wsdl here:
http://awtassignment3-shoppinglistservice1.cloudapp.net/Service1.asmx?WSDL
This referencing adds the 3 operations. The first one "ShoppingTripNeeded" seems to be fine (receiving a DateTime and returning a Boolean), but for the other operations, the parameters have changed in a strange way...
For example the operation ShopsToVisit now ask for a ShopsToVisitRequestBody and returns a ShopsToVisitResponseBody... I don't know why this happens! because the first operation is fine...
Moreover, as I'm working with a workflow, I can't "play" with this types to find out what's going on...
Have you any guess? any help will be fine...
Thanks very much!
Is there a reason you are using ASMX? WCF has replaced Web Services as far more superior service communication technology. See SO: Web Services — WCF vs. Standard, SO: Web Service vs WCF Service
To answer your question:
WF 3.5 will wrap any operation with Request/Response message pattern that is not a primitive (e.g. bool, int). String[] is not a primitive type hence it will be wrapped.
WF 4.0 adding service reference (dialog) will wrap all operations in Request/Response message pair by default regardless if this is primitive or complex type. On top of that, it will create Activity for each operation that it discovers.
Using Request/Response message pattern allows for controlling the message shape specifically message headers.
For Reference:
SO: When should I use Message Contracts instead of DataContract and why?
MSDN: Message Contracts
I am building a site using fluent NHibernate, which works just fine on the dev box.
However, after I uploaded it to my host I get the following when trying to run it.
"System.TypeInitializationException: The type initializer for 'NHibernate.ByteCode.Castle.ProxyFactory' threw an exception. ---> System.Security.SecurityException: That assembly does not allow partially trusted callers.
Is this something I will need to resolve with the hosting company (CrystalTech)?
Any help much appreciated.
The rest of the inner exception:
at Castle.DynamicProxy.ModuleScope..ctor(Boolean savePhysicalAssembly, String strongAssemblyName, String strongModulePath, String weakAssemblyName, String weakModulePath) at Castle.DynamicProxy.ModuleScope..ctor(Boolean savePhysicalAssembly) at Castle.DynamicProxy.ProxyGenerator..ctor() at NHibernate.ByteCode.Castle.ProxyFactory..cctor() The action that failed was: LinkDemand The Zone of the assembly that failed was: MyComputer
--- End of inner exception stack trace ---
nHibernate does not work out of the box on a medium-trust environment (which most shared hosts run your application under). Lazy Loading with nHibernate Under Medium Trust describes some of the steps taken to try to get it working.
I have configured a new VM (MS Virtual Server running Windows Server 2003) as a copy of an existing VM hosting BizTalk server 2006. I have run into a problem with BRE processing. The policy is deployed and vocabulary published exactly as on the working VM.
An orchestration calls a helper component which in turn makes use of the BRE components. The last line in the helper component that seems to execute is:
Policy workflowPolicy = new Policy(policyName)
I have pasted the stack trace from the event log below:
Exception type: InvalidCastException
Source: Microsoft.RuleEngine
Target Site: Int32 GetInt32(System.String, Int32)
The following is a stack trace that identifies the location where the exception occured
at Microsoft.RuleEngine.Configuration.GetInt32(String key, Int32 defaultValue)
at Microsoft.RuleEngine.ReteTranslator.RuleSetToReteTranslatorImpl.Translate(RuleSet ruleset, Int32 duration)
at Microsoft.RuleEngine.ReteTranslator.RuleSetToReteTranslator.Translate(RuleSet ruleset, Int32 duration)
at Microsoft.RuleEngine.RuleEngine..ctor(RuleSet ruleSet, Boolean doOptimizations)
at Microsoft.RuleEngine.RuleEngineCache.Allocate(String rulesetName, Int32 majorRevision, Int32 minorRevision, TrackingConfiguration& trackingConfig)
at Microsoft.RuleEngine.RuleEngineCache.Allocate(String rulesetName, TrackingConfiguration& trackingConfig)
at Microsoft.RuleEngine.Policy..ctor(String policyName)
at Tesco.BRE.Services.PolicyServices.Direct.OrderWorkflowServices.Commands.GetNextTaskList.Execute()
at Tesco.DataSources.Integration.Common.CommandBase.CommandDecorators.CommandLoggingDecorator`1.Execute()
at Tesco.DataSources.Integration.Common.CommandBase.CommandUtilities.GetCommandResponse[T](CommandBase`1 command)
at Tesco.BRE.Services.PolicyServices.Direct.OrderWorkflowServices.OrderWorkflowOperations.GetNextTaskList(String currentTaskName, String currentTaskStatus, XmlDocument order)
at Tesco.Direct.OrderManagement.Orchestrations.FollowTaskResult.segment2(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception&
It looks like Microsoft.RuleEngine.Configuration.GetInt32 is being passed a value that cannot be cast to an Int32?
I have tried un-configuring / re-configuring the BRE. As far as I can tell everything on the new server is configured exactly as per the working server.
Any help, gratefully receive - I've been stuck with this all day!
If one follow the stack trace one could read "cache" and "tracking". I would try to restart the host and uncheck any rule tracking in HAT.
Thanks for your response Martin. I have now fixed the issue. The problem was user error (mine) in making a registry change. I had to create a reg setting as follows
HKLM\SOFTWARE\Microsoft\BusinessRules\3.0\StaticSupport (DWORD), value 2
in order to enable the BRE to make use of static methods. This is described at: http://technet.microsoft.com/en-us/library/dd298814.aspx
Although I had made the addition when configuring the server, I had inadvertently used a string rather than a dword. Since this cost me over a day to figure out - I won't be making the same mistake any time soon!