I have following code:
public class A: IContract, ...
{
private B b = new B();
// contract method
public string MethodA(string p1, string p2)
{
Log("Start");
SomeObject obj = CreateObj(p1, p2);
Log("Before Send");
string result = b.SendToExternalSth(obj);
// do sth
return result;
}
}
public class B
{
public string SendToExternalSth(SomeObject obj)
{
Log("BEGIN");
string a, b;
a = proxy.Send(obj);
// do sth
Log("End");
return a;
}
}
After line with Before Send is executed I got System.Exception with empty message, and exception's stack trace is pointing to line with closing } for SendToExternalSth method.
Do you have any ideas why it is happening?
I should mentioned that:
this happening only on production environment (works locally and on test env.),
code is in c# - .net 4.0,
This code is part of soap web services code (MethodA is an soap action and SendToExternalSth method is internal method of some other class) hosted under IIS 7.0,
I am building it with 'any cpu' option,
I am deploying Debug build on production env,
Both production and test envs are 64bit windows 2008 r2 sp1,
.net 4 framework is installed with the same version on both of them,
There is lack of Microsoft .NET Framework 4 Multi-Targeting Pack component on production server, comparing to test env, but currently I am not able to install it there.
Please tell me if some more information is needed to solve this issue, I will be more then happy to provide you it.
I've written some more debugging code and changed compilation option several times. After next deploy to production this error didn't occur. I think that was some compilation issue related to Any CPU option, but this is just wild guess.
Related
Below is the code to build a cache which stores (typeName,type) found in the assemblies loaded in the current app domain.
I am facing this weird issue when trying to load types from one particular assembly say assemblyK. The assemblyK has around 954 types. Logs are in sync and it works all well when locally hosted in Visual Studio. Also, when I deploy the website in IIS it works well in when the buildCache is called for the first time.
However when the application pool is restarted/ after calling it later, it runs the nested loop for only for 5 types and goes on to execute the next function i.e. it does not throw any exception and moves forward.
private static void BuildCache()
{
Assembly[] assemblies= AppDomain.CurrentDomain.GetAssemblies();
foreach(Assembly assembly in assemblies){
if(assembly.GlobalAssemblyCache){
if(assemblly.ToString().Contains("assemblyK"))
Logger.Log("GAC");
continue;
}
try
{
if(assembly.ToString().Contains("AssemblyK"))
{
string allTypes = string.Join(",",assembly.GetTypes().Select(x => x.ToString()).ToArray())
Logger.Log("All types :{0}",allTypes);
}
foreach(Type type in assembly.GetTypes())
{
if(assembly.ToString().Contains("AssemblyK"))
{
Logger.Log("Type parsed :{0}",type);
}
if(!typeCache.ContainsKey(type.FullName))
{
if(assembly.ToString().Contains("AssemblyK"))
{
Logger.Log("Adding to cache :{0}",type);
}
typeCache.Add(type.FullName,type);
}
}
catch(Exception ex)
{
Logger.Log("Exception Caught : {0}",ex.ToString());
}
}
}
Notably, The AssemblyK.dll build in Visual Studio 2008 in .Net 3.5 version works all well and when complied in Visual Studio 2019 causing the issue. Application Pool is 2.0. And the assemblyK is loaded in the "assemblies" always. Please Help.
P.S.: I copied the logs for allTypes received in both the cases(when it works and doesnt) in two files and did a file compare using cmd, with fc file1 file2.
Both contained the identical data i.e.954 types. So my question is how can the foreach run randomly? What could be the issue here?
Update : The logs read:
1) In Working case :
All Types : Type1,Type2,Type3,..Type954
Type Parsed 954 times
Adding to cache 954 times
2) In Not Working case :
All Types : Type1,Type2,Type3,..Type954.
Type Pased 4 Times.
typeCache is a private static readonly Dictionary
I have a .net windows forms application target both .Net framework 3.5 and 4 , and target to any cpu, when I start the app with Debug(F5) in visual studio target .net 3.5, I encountered StackOverflowException, but I can start app without debug(ctrl+F5) successfully. Also I can start app with debug(ctrl+F5) target .net4 successfully. Can anyone tell me the possible reason. Thanks. code as below:
public struct AStuctType : IInterface {
// some properties
// if changed the return type to IInterface, will not encounter StackOverflowException in debug/.net 3.5
// but will encounter StackOverflowException when convert the value to AStuctType
public static AStuctType LoadFromXml(XmlReader reader) {
var result = new AStuctType();
//...read xml and assign result properties' values.
// exception encountered here
return result.
}
}
I migrated Mining Structures from a 2008 server to a 2012 server. When I try my CLR UDF (which is working fine on SQL server 2008) in a DMX query on the 2012 server, I am getting this error:
Exception has been thrown by the target of an invocation. Object reference not set to an instance of an object.
My original goal was to get the GetNodeDescription(...) method running. While debugging the problem, I could isolate the problem to this UDF which fails on my SQL server 2012
[SafeToPrepare(true)]
public static string test()
{
return Context.CurrentMiningModel.Name;
}
My guess is that CurrentMiningModel is null because the following code works fine
[SafeToPrepare(true)]
public static string testUser()
{
return Context.CurrentConnection.User.Name;
}
Any Idea on how to solve this?
Is somebody out there who can reproduce this?
Thanks.
Jan
UPDATE:
A contact at Microsoft confirmed this behaviour as desired due to a "Metadata-Refactoring" (whatever this means...). However, the website still pends to be updated appropiately.
This is not the ultimate answer but it's a workaround to get Microsoft's GetNodeDescription working (by explicitly providing the mining model):
[SafeToPrepare(true)]
public static string GetNodeDescription(string MiningModel, string nodeUniqueName)
{
if (Context.ExecuteForPrepare)
{
return string.Empty;
}
return Context.MiningModels[MiningModel].GetNodeFromUniqueName(nodeUniqueName).Description;
}
I am building a webcam app based on the VideoRendererElement project (http://videorendererelement.codeplex.com/), which uses the DirectShowLib and Interop with an unmanaged activex component. I am using Visual Studio 2010, but am targeting .NET 3.5 (2.0 clr runtime).
I have been able to build and run the app on my development machine with no problem (outside of Visual Studio, even). However, when I deployed the app on the target machine (Windows 7,.NET up to date, C++ redistributable up to date) the app crashes. I set up an additional method to log the running application to a text file on the target machine a traced down one key difference, the unmanaged code calls the method in the managed code, only the static fields defined previously are missing. This only happens on the target machine (the one I deployed the code to). Here are some code snippets and what I logged. What is confusing is that this error ONLY occurs on the target machine. Any help pointing me in the right direction would be greatly appreciated.
namespace MediaBridge
{
.....
public class MediaBridgeManager
{
public delegate void NewMediaGraphInfo(MediaBridgeGraphInfo GraphInfo);
private static readonly Dictionary<string, NewMediaGraphInfo> _delegateHash = new Dictionary<string, NewMediaGraphInfo>();
......
public static void AddMediaGraphInfo(MediaBridgeGraphInfo GraphInfo)
{
if (_delegateHash.ContainsKey(GraphInfo.MediaUrl))
{
NewMediaGraphInfo callback = _delegateHash[GraphInfo.MediaUrl];
_delegateHash.Remove(GraphInfo.MediaUrl);
/* Suppress all errors on the callback */
try
{
callback(GraphInfo);
}
catch {}
}
}
......
public static bool RegisterCallback(string MediaUrl, NewMediaGraphInfo Callback)
{
bool returnval = true;
MediaUrl = FormatUrl(MediaUrl);
if (!_delegateHash.ContainsKey(MediaUrl))
{
_delegateHash.Add(MediaUrl, Callback);
}
else
{
returnval = false;
}
return returnval;
}
}
}
Before the .NET part of the app calls RegisterCallback() first and populates _delegateHash with a URL and callback function. This was verified in the logfile on the target machine.
Now the unmanaged part:
STDMETHODIMP CMediaBridgeSourceFilter::Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt)
{
/* Thread-saftey */
CAutoLock cAutoLockShared(&m_cSharedState);
HRESULT phr = S_OK;
/* Create the output pin for our filter */
m_pPin = new CMediaBridgeSourceFilterPin(&phr, this);
/* Create a new class to store information about us/graph in it */
MediaBridge::MediaBridgeGraphInfo ^ graphInfo = gcnew MediaBridge::MediaBridgeGraphInfo();
/* Set the media url sent */
graphInfo->MediaUrl = gcnew System::String(lpwszFileName);
/* Set the pointer to the filter graph */
graphInfo->FilterGraph = System::IntPtr(this->GetFilterGraph());
/* Store the pointer for our instance of the filter */
graphInfo->SourceFilter = System::IntPtr(this);
/* Do the callback into our managed code */
MediaBridge::MediaBridgeManager::AddMediaGraphInfo(graphInfo);
return phr;
}
According to my log file MediaBridge::MediaBridgeManager::AddMediaGraphInfo() is being called on the .NET side but the call back is never reached because the _delegateHash variable is now empty.
Here is what my log file says on the target machine that I'm trying to deploy the app on:
RegisterCallback(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ Contains Key: True Delegate Hash count: 1
InitializeDirectShow(): RegisterCallback == true, Url == DShowMediaBridge://d0ffd222-d023-483b-8fc7-4b4035ce3922
AddMediaGraphInfo(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ FilterGraph: 71122304 Contains Key: False Delegate Hash count: 0
Note how the Delegate Hash count (_delegateHash.Count) is now at 0 when the unmanaged code calls AddMediaGraphInfo().
Is there something I should be doing to identify the dll to COM/C++ on the target machine that VS is doing for me on my development machine?
How are you deploying and running the application on the target machine. Are you simply copying over the executable or are you creating an installer? If you are creating an installer, are you registering the AX file with RegSvr32?
The issue with COM components is they have to be registered in the registry on the box in question. On your box, you already have this registered, so you will not have an issue. On the target box, however, it may or may not be registered, at the whim of the user. If you have set up an installer, you have to "install" the AX file so it is registered in the registry. If not, the AX file cannot be found, no matter how you deploy the AX file. It is one of the downsides to COM.
I was under the impression Mono's compiler was usable in Microsoft.NET
edit: updated blog posting here that I originally missed that explains some of it (is consistent with Justin's answers)
I created a simple class to try to use it
[TestFixture]
class Class1
{
[Test]
public void EXPR()
{
Evaluator.Run("using System;");
int sum = (int)Evaluator.Evaluate("1+2");
}
}
And a project in Visual Studio 2010 that references C:\Program Files (x86)\Mono-2.10.1\lib\mono\4.0\Mono.CSharp.dll.
However when I try to run this task I get the following exception, thrown at the Evaluator.Run call:
System.TypeInitializationException was unhandled by user code
Message=The type initializer for 'Mono.CSharp.Evaluator' threw an exception.
Source=Mono.CSharp
TypeName=Mono.CSharp.Evaluator
StackTrace:
at Mono.CSharp.Evaluator.Run(String statement)
at Experiments.Class1.EXPR() in W:\Experiments\Class1.cs:line 16
InnerException: System.TypeLoadException
Message=Method 'Mono.CSharp.Location.ToString()' is security transparent, but is a member of a security critical type.
Source=Mono.CSharp
TypeName=Mono.CSharp.Location.ToString()
StackTrace:
at Mono.CSharp.Evaluator..cctor()
InnerException:
A google confirms one other person asking this question but no answer. I tried to start reading the microsoft article on security transparent code but got confused quite quickly. Would someone be able to suggest a quick workaround to allow me to use this? And possibly summarise the security implications, if any, to me (in the context of my situation - in the future I hope to package it with a thick client application, to be used both internally and by end-users)
It has worked under .NET since April of last year.
Small point but I notice you are missing a semi-colon in your expression for sum.
int sum = (int)Evaluator.Evaluate("1+2;");
I only have Mono 2.11 (from git) at the moment and they have changed to using a multi-instance version of the compiler instead of the static version. So, my code looks a little different:
using System;
using Mono.CSharp;
namespace REPLtest
{
class MainClass
{
public static void Main (string[] args)
{
var r = new Report (new ConsoleReportPrinter ());
var cmd = new CommandLineParser (r);
var settings = cmd.ParseArguments (args);
if (settings == null || r.Errors > 0)
Environment.Exit (1);
var evaluator = new Evaluator (settings, r);
evaluator.Run("using System;");
int sum = (int) evaluator.Evaluate("1+2;");
Console.WriteLine ("The sum of 1 + 2 is {0}", sum);
}
}
}
EDIT: I guess I should confirm that I did in fact successfully execute this on .NET 4 (using Visual C# Express 2010 on Windows XP)
EDIT AGAIN: If you have Visual Studio, you can download the latest version of Mono.CSharp and compile it yourself. There is a .sln (solution file) included with the source so you can build it on Windows without Mono. The resulting assembly would run the code above. Miguel has a post explaining the new Mono.CSharp here.
FINAL EDIT: I uploaded the compiled Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
It looks like this is a bug in Mono.
.NET 4 abandoned Code Access Security but kept the concept of Security Transparent Code. In a nutshell, low-level code that does stuff, like call unmanaged code, must be "security critical". Application level code is marked "transparent". "Transparent" code cannot call into "security critical" code.
It sounds like Mono.CSharp.Location.ToString() needs to be marked with the [SecuritySafeCritical] attribute if you want the Mono 2.10 code to work with .NET 4. Maybe even better would be marking all of Mono.CSharp as SecuritySafeCritical.
http://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute.aspx
PS. Sorry to have multiple answers for one question. After I realized that 2.11 would work, I became more curious about what the error with 2.10 meant. I cannot really combine this answer with the others.
I decided I should have kept the code more like the question but I did not want to overwrite my previous answer:
The code below works with version 2.11 of Mono.CSharp (available here including a solution file for building with Visual Studio/.NET). It was tested with .NET 4 on Windows XP. I do not have access to Mono 2.10 at the moment.
[TestFixture]
class Class1
{
private Evaluator evaluator;
public Class1()
{
var report = new Report(new ConsoleReportPrinter());
evaluator = new Evaluator(new CompilerSettings(), report);
}
[Test]
public void EXPR()
{
evaluator.Run("using System;");
int sum = (int)evaluator.Evaluate("1+2;");
}
}
EDIT: I uploaded the Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.