exePath exception when using SAP .net connector 3.0 in ASP.net - asp.net

Have a WPF app that I am converting to ASP.net and I am having issues with SAP.
When I run this line I get an exception.
RfcDestinationManager.RegisterDestinationConfiguration(Backend);
Exception Message {"exePath must be specified when not running inside a stand alone exe."}
Stack Trace
at System.Configuration.ConfigurationManager.OpenExeConfigurationImpl(ConfigurationFileMap fileMap, Boolean isMachine, ConfigurationUserLevel userLevel, String exePath, Boolean preLoad)
at System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel userLevel)
at SAP.Middleware.Connector.RfcConfigParameters..cctor()
googling around I saw as similar issue here exePath must be specified when not running inside a stand alone exe
The issue seems to be using ConfigurationManager.OpenExeConfiguration rather that System.Web.Configuration.WebConfigurationManagerwhich is what I need to use. Problem is I can't change that as its part of the SAP.Net Connector.
Is there anything I can do?
Edit: My BackendConfig code
public class BackendConfig : IDestinationConfiguration
{
public RfcConfigParameters GetParameters(String destinationName)
{
if ("P38".Equals(destinationName))
{
var parms = new RfcConfigParameters
{
{RfcConfigParameters.AppServerHost, "SAPSERVER"},
{RfcConfigParameters.SystemNumber, "86"},
{RfcConfigParameters.SncMode, "1"},
{RfcConfigParameters.SncPartnerName, "p:SAP#SERVER"},
{RfcConfigParameters.Client, "010"},
{RfcConfigParameters.Language, "EN"},
{RfcConfigParameters.PoolSize, "5"}
};
return parms;
}
else return null;
}
// The following two are not used in this example:
public bool ChangeEventsSupported()
{
return false;
}
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
}

Related

Cannot initialize ChromiumWebBrowser inside a JSB-bounded class

I have followed this steps to setup JSB. In my bounded-class, I need to return the source of an API request (I cannot, therefore, use GetPageSourceAsync because no JS context is ever created). So, I use the trick of copying and immediately pasting the page content to a string variable (see result). This code is not working, I get the following exception:
The ChromiumWebBrowser instance creates the underlying Chromium Embedded Framework (CEF) browser instance in an async fashion. The undelying CefBrowser instance is not yet initialized. Use the IsBrowserInitializedChanged event and check the IsBrowserInitialized property to determine when the browser has been initialized.
which is happening on bro.SelectAll();:
public class boundClass
{
ChromiumWebBrowser bro;
public boundClass()
{
bro = new ChromiumWebBrowser("https://google.com");
}
public string getAuthSource(string url)
{
string source = String.Empty;
bro.Load(url);
while (bro.IsLoading)
{
}
bro.SelectAll();
bro.Copy();
string result = Clipboard.GetText();
Clipboard.Clear();
return result;
}
}
What's the problem? The ChromiumWebBrowser seems well-initialized to me...

Serilog sending blank CorrelationId to Seq logger

I'm using Serilog and Seq in a .net core web api to handle the logging. I've added a reference to Steve Gordon's CorrelationId Middleware to get the X-Correlation-ID from the headers (or create a new one) to update the TraceIdentifier.
I've then added another middleware class to push the correlation id into the log context, but this isn't working correctly:
public class LogCorrelationIdMiddleware
{
private readonly RequestDelegate _next;
public LogCorrelationIdMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
// doesn't work - blank CorrelationId in Seq
using (LogContext.PushProperty("CorrelationId", context.Request.HttpContext.TraceIdentifier)) { return _next(context); }
// works - correct CorrelationId2 in Seq
//using (LogContext.PushProperty("CorrelationId2", context.Request.HttpContext.TraceIdentifier)) { return _next(context); }
}
}
Any ideas why?
It's working for me when I do the following (not as middleware):
using (LogContext.PushProperty("CorrelationId", "This is a test..."))
{
Log.Write(level, exception, messageTemplate, propertyValues);
}
So I suspect that it's your CorrelationId being overwritten by ASP.NET Core MVC as eluded to here:
https://github.com/serilog/serilog-aspnetcore/issues/59
Some background to the issue and their plan to deal with it in 3.0 is also here:
https://github.com/aspnet/AspNetCore/issues/5918
Apologies that this isn't a "fix", however I had the same issue and was able to work around it by adding a level of indirection between the log call (in my code) and the call to Log.Write (as shown above).

Nancyfx using Json.net, registering dependencies error

I'm trying to use nancy with JSON.net, follow the 2 ways that i found to register the dependencies but all way get me to an InvalidOperationException with a message "Something went wrong when trying to satisfy one of the dependencies during composition, make sure that you've registered all new dependencies in the container and inspect the innerexception for more details." with an inner exection of {"Unable to resolve type: Nancy.NancyEngine"}.
I'm using self hosting to run nancy and jeep everything really simple to been able just to test.
public static void Main(string[] args)
{
try
{
var host = new NancyHost(new Uri("http://localhost:8888/"));
host.Start(); // start hosting
Console.ReadKey();
host.Stop(); // stop hosting
}
catch
{
throw;
}
}
First I create a customSerializer
public class CustomJsonSerializer : JsonSerializer
{
public CustomJsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver();
Formatting = Formatting.Indented;
}
}
and then i tried 2 ways of registering
Using IRegistrations:
public class JsonRegistration : IRegistrations
{
public IEnumerable<TypeRegistration> TypeRegistrations
{
get
{
yield return new TypeRegistration(typeof(JsonSerializer), typeof(CustomJsonSerializer));
}
}
public IEnumerable<CollectionTypeRegistration> CollectionTypeRegistrations { get; protected set; }
public IEnumerable<InstanceRegistration> InstanceRegistrations { get; protected set; }
}
And also using Bootstrapper
public class NancyBootstrapper : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
base.ConfigureApplicationContainer(container);
container.Register<JsonSerializer, CustomJsonSerializer>();
}
}
Which means that when self hosting I add the custom bootstrapper
var host = new NancyHost(new Uri("http://localhost:8888/"), new NancyBootstrapper());
Both way return the same error.
Problem is actually the versions, the nancy json.net package is using Newton.Json 6.0.0.0, BUT when installing the package it will install automatically newer version that will create this problem. Not sure what has change in the Newton.JSON that will actually create this.
https://github.com/NancyFx/Nancy.Serialization.JsonNet/issues/27
Just to add my hard won knowledge in this area, after a greatly frustrating few hours using Nancy 1.4.1.
If you use a custom bootstrapper, make sure you make the call to base.ConfigureApplicationContainer(container); before you start your custom registrations.
So, not:
public class MyCustomBootstrapper : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
// MY BITS HERE...
base.ConfigureApplicationContainer(container);
}
}
but,
public class MyCustomBootstrapper : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
base.ConfigureApplicationContainer(container); // Must go first!!
// MY BITS HERE...
}
}
If you don't do this you will get the following error:
Something went wrong when trying to satisfy one of the dependencies
during composition, make sure that you've registered all new
dependencies in the container and inspect the innerexception for more
details.
with a helpful inner exception of:
Unable to resolve type: Nancy.NancyEngine
The solution of changing the order of these C# statements was actually alluded to in #StevenRobbins' excellent answer here (which I could have saved myself several hours of pain if I'd only read properly the first time).
Says Steven:
By calling "base" after you've made a manual registration you are
effectively copying over your original registration by autoregister.
Either don't call base, or call it before you do your manual
registrations.

Test ControllerFactory (pre-start initialization stage)

I want to write a unit test that verifies my route registration and ControllerFactory so that given a specific URL, a specific controller will be created. Something like this:
Assert.UrlMapsToController("~/Home/Index",typeof(HomeController));
I've modified code taken from the book "Pro ASP.NET MVC 3 Framework", and it seems it would be perfect except that the ControllerFactory.CreateController() call throws an InvalidOperationException and says This method cannot be called during the application's pre-start initialization stage.
So then I downloaded the MVC source code and debugged into it, looking for the source of the problem. It originates from the ControllerFactory looking for all referenced assemblies - so that it can locate potential controllers. Somewhere in the CreateController call-stack, the specific trouble-maker call is this:
internal sealed class BuildManagerWrapper : IBuildManager {
//...
ICollection IBuildManager.GetReferencedAssemblies() {
// This bails with InvalidOperationException with the message
// "This method cannot be called during the application's pre-start
// initialization stage."
return BuildManager.GetReferencedAssemblies();
}
//...
}
I found a SO commentary on this. I still wonder if there is something that can be manually initialized to make the above code happy. Anyone?
But in the absence of that...I can't help notice that the invocation comes from an implementation of IBuildManager. I explored the possibility of injecting my own IBuildManager, but I ran into the following problems:
IBuildManager is marked internal, so I need some other authorized derivation from it. It turns out that the assembly System.Web.Mvc.Test has a class called MockBuildManager, designed for test scenarios, which is perfect!!! This leads to the second problem.
The MVC distributable, near as I can tell, does not come with the System.Web.Mvc.Test assembly (DOH!).
Even if the MVC distributable did come with the System.Web.Mvc.Test assembly, having an instance of MockBuildManager is only half the solution. It is also necessary to feed that instance into the DefaultControllerFactory. Unfortunately the property setter to accomplish this is also marked internal (DOH!).
In short, unless I find another way to "initialize" the MVC framework, my options now are to either:
COMPLETELY duplicate the source code for DefaultControllerFactory and its dependencies, so that I can bypass the original GetReferencedAssemblies() issue. (ugh!)
COMPLETELY replace the MVC distributable with my own build of MVC, based on the MVC source code - with just a couple internal modifiers removed. (double ugh!)
Incidentally, I know that the MvcContrib "TestHelper" has the appearance of accomplishing my goal, but I think it is merely using reflection to find the controller - rather than using the actual IControllerFactory to retrieve a controller type / instance.
A big reason why I want this test capability is that I have made a custom controller factory, based on DefaultControllerFactory, whose behavior I want to verify.
I'm not quite sure what you're trying to accomplish here. If it's just testing your route setup; you're way better off just testing THAT instead of hacking your way into internals. 1st rule of TDD: only test the code you wrote (and in this case that's the routing setup, not the actual route resolving technique done by MVC).
There are tons of posts/blogs about testing a route setup (just google for 'mvc test route'). It all comes down to mocking a request in a httpcontext and calling GetRouteData.
If you really need some ninja skills to mock the buildmanager: there's a way around internal interfaces, which I use for (LinqPad) experimental tests. Most .net assemblies nowadays have the InternalsVisibleToAttribute set, most likely pointing to another signed test assembly. By scanning the target assembly for this attribute and creating an assembly on the fly that matches the name (and the public key token) you can easily access internals.
Mind you that I personally would not use this technique in production test code; but it's a nice way to isolate some complex ideas.
void Main()
{
var bm = BuildManagerMockBase.CreateMock<MyBuildManager>();
bm.FileExists("IsCool?").Dump();
}
public class MyBuildManager : BuildManagerMockBase
{
public override bool FileExists(string virtualPath) { return true; }
}
public abstract class BuildManagerMockBase
{
public static T CreateMock<T>()
where T : BuildManagerMockBase
{
// Locate the mvc assembly
Assembly mvcAssembly = Assembly.GetAssembly(typeof(Controller));
// Get the type of the buildmanager interface
var buildManagerInterface = mvcAssembly.GetType("System.Web.Mvc.IBuildManager",true);
// Locate the "internals visible to" attribute and create a public key token that matches the one specified.
var internalsVisisbleTo = mvcAssembly.GetCustomAttributes(typeof (InternalsVisibleToAttribute), true).FirstOrDefault() as InternalsVisibleToAttribute;
var publicKeyString = internalsVisisbleTo.AssemblyName.Split("=".ToCharArray())[1];
var publicKey = ToBytes(publicKeyString);
// Create a fake System.Web.Mvc.Test assembly with the public key token set
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "System.Web.Mvc.Test";
assemblyName.SetPublicKey(publicKey);
// Get the domain of our current thread to host the new fake assembly
var domain = Thread.GetDomain();
var assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule("System.Web.Mvc.Test", "System.Web.Mvc.Test.dll");
AppDomain currentDom = domain;
currentDom.TypeResolve += ResolveEvent;
// Create a new type that inherits from the provided generic and implements the IBuildManager interface
var typeBuilder = moduleBuilder.DefineType("Cheat", TypeAttributes.NotPublic | TypeAttributes.Class, typeof(T), new Type[] { buildManagerInterface });
Type cheatType = typeBuilder.CreateType();
// Magic!
var ret = Activator.CreateInstance(cheatType) as T;
return ret;
}
private static byte[] ToBytes(string str)
{
List<Byte> bytes = new List<Byte>();
while(str.Length > 0)
{
var bstr = str.Substring(0, 2);
bytes.Add(Convert.ToByte(bstr, 16));
str = str.Substring(2);
}
return bytes.ToArray();
}
private static ModuleBuilder moduleBuilder;
private static Assembly ResolveEvent(Object sender, ResolveEventArgs args)
{
return moduleBuilder.Assembly;
}
public virtual bool FileExists(string virtualPath) { throw new NotImplementedException(); }
public virtual Type GetCompiledType(string virtualPath) { throw new NotImplementedException(); }
public virtual ICollection GetReferencedAssemblies() { throw new NotImplementedException(); }
public virtual Stream ReadCachedFile(string fileName) { throw new NotImplementedException(); }
public virtual Stream CreateCachedFile(string fileName) { throw new NotImplementedException(); }
}

rso between flex and red5. I can create but cant read

so im still stuck on this that i can create remote shared object but cant read while im notified about changes. im using trunk version of red5, and flex 4.0 with flash builder. in debug i can see that changeLog has name of the changed value of rso, but object itself has undefined value.
Currently im working on local windows machine, but tried everything on ubuntu server 10.04 and got the same results. i can connect to the room, create a shared object and all client are notified about that, but only the user who changed the value of rso can read the value that one time, other just get undefined value.
Does anybody has any experience with this issue? I would really appreciate any help, because this is just driving me crazy, im for about three weeks, read all tutorials about rso and cant get any solution. I tried with persistent and non-persistent, initiated by server and by client, but all the time get the same results.
there is my code on the client side:
protected function application1_creationCompleteHandler(event:FlexEvent):void {
var room_id:Number = vars("room");
connection = new NetConnection();
connection.connect("rtmp://127.0.0.1/video/" + room_id);
connection.addEventListener(NetStatusEvent.NET_STATUS, onConnected);
connection.client = this;
}
private function onConnected(event:NetStatusEvent) : void {
if(event.info.code == "NetConnection.Connect.Success") {
so = SharedObject.getRemote("video", connection.uri, true);
so.addEventListener(SyncEvent.SYNC, onSync);
so.connect(connection);
} else {
Alert.show("Unsuccessful Connection", "Information");
}
private function onSync(event:SyncEvent):void {
if(so.data["video"] != undefined)
Alert.show(so.data["video"].toString(), "Information");
}
on the server side i have:
ISharedObject so;
IServiceCapableConnection iconn;
public static IScope iroom;
/** {#inheritDoc} */
#Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
iconn = (IServiceCapableConnection)conn;
if (!super.connect(conn, scope, params)) {
return false;
}
System.out.println("Connected True");
return true;
}
/** {#inheritDoc} */
#Override
public void disconnect(IConnection conn, IScope scope) {
super.disconnect(conn, scope);
}
#Override
public boolean roomStart(IScope room) {
if (!super.roomStart(room))
return false;
createSharedObject(room, "video", true);
so = getSharedObject(room, "video");
System.out.println("Room created succesfully");
ISharedObjectListener listener = new SOEventListener();
so.addSharedObjectListener(listener);
return true;
}
with listener on the client side i cant make output in console and see that rso is changed and what is current value, although im checking the persistence rso file on red5 server and the that look like everything is working and the only thing what is missing is opportunity to read value for all clients.
I will appreciate any help. Thanks
big problem appears not such a big. Problem was with encoding, which is AMF3 by default since AS3 and all i need to do, just change the encoding to AMF0.
connection = new NetConnection();
connection.objectEncoding = ObjectEncoding.AMF0;
connection.connect("rtmp://127.0.0.1/video/" + room_id);
Hope that helps for anybody, because somehow there is not a lot information about things like these on the net.

Resources