DynamicProxy as a Service is not found at runtime - wcf

I'm trying to develop a WCF Service to be used as a Proxy of an already defined Web Service from a Provider.
Here is the steps that i followed to acomplish this goal:
Create a WCF Service Application
Added a Service reference to the Provider Web Service
Added Global.asax to the project.
Added Castle.Core (v3.2) reference via NuGet to the project.
Added some code to the Global.asax
Here is the code in my Global.asax
/// <summary>
/// Contiene eventos globales ejecutados
/// </summary>
public class Global : HttpApplication
{
private static readonly ProxyGenerator generator = new ProxyGenerator();
private static List<object> proxies = new List<object>();
/// <summary>
/// Evento que se ejecuta cuando se inicializa la aplicacion
/// </summary>
/// <param name="sender">Objeto que origna el evento</param>
/// <param name="e">Argumentos del evento</param>
protected void Application_Start(object sender, EventArgs e)
{
ConfigurarServicios();
}
/// <summary>
/// Busca los servicios registrados en el proyecto
/// </summary>
/// <returns>Coleccion de servicios registrados y que extienden
/// la clase ServiceBase</returns>
private static IEnumerable<Type> BuscarServicios()
{
ConfigurarProxies();
var list = new List<Type>();
foreach (var proxy in proxies)
{
list.Add(proxy.GetType());
}
return list;
}
/// <summary>
/// Configura los servicios del proyecto para ser accedidos
/// a traves de REST y SOAP
/// </summary>
private static void ConfigurarServicios()
{
var soapFactory = new ServiceHostFactory();
var services = BuscarServicios();
foreach (var serviceType in services)
{
string serviceName = "xm";
var soapEndpoint = new ServiceRoute("Servicios/" + serviceName, soapFactory, serviceType);
RouteTable.Routes.Add("Servicios/" + serviceName,soapEndpoint);
}
}
private static void ConfigurarProxies()
{
var interceptor = new Interceptor();
var proxy1 = generator.CreateInterfaceProxyWithoutTarget(typeof(ExternalServices.XpressMoney.XMSendTxnServicePortType), interceptor);
proxies.Add(proxy1);
}
}
When I run the project, everything just work fine, but when I try to access to the ServiceRoute /Servicios/xm, it shows me the next error:
The type 'Castle.Proxies.XMSendTxnServicePortTypeProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null', provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found.
And this is the stack:
[InvalidOperationException: The type 'Castle.Proxies.XMSendTxnServicePortTypeProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null', provided a the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found.]
System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +59318
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +1434
System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +52
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +598
[ServiceActivationException: The service '/Servicios/xm' cannot be activated due to an exception during compilation. The exception message is: The type 'Castle.Proxies.XMSendTxnServicePortTypeProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null', provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found..]
System.Runtime.AsyncResult.End(IAsyncResult result) +499812
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +178
System.ServiceModel.Activation.AspNetRouteServiceHttpHandler.EndProcessRequest(IAsyncResult result) +6
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129
I guess that the problem occurs when the .NET Framework try to dynamically instantiate the DynamicProxy, but I really don't know. Maybe the Next Lines is a clue:
var soapEndpoint = new ServiceRoute("Servicios/" + serviceName, soapFactory, serviceType);
RouteTable.Routes.Add("Servicios/" + serviceName,soapEndpoint);
Hope you can help me.

Related

Error activating IProductRepository, ninject issue learning With Apress Pro ASP.NET MVC 5

Hello I'm Reading the book "Apress Pro ASP.NET MVC 5" I have downloaded chapter 7, that is a running application using ninject.
The first Issue was
1st issue snagit
I read it was an Ninject issue versiĆ³n solved adding this code to the SportsStoreWebUI web.config:
enter code here
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Now when I try to run the App I get this Issue.
Error activating IProductRepository
No matching bindings are available, and the type is not self-bindable.
Activation path:
1) Injection of dependency IProductRepository into parameter productRepository of constructor of type ProductController
2) Request for ProductController
Suggestions:
1) Ensure that you have defined a binding for IProductRepository.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
The Content of NinjectWebCommon.cs is
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(SportsStore.WebUI.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(SportsStore.WebUI.App_Start.NinjectWebCommon), "Stop")]
namespace SportsStore.WebUI.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}
}
I have looked for but I don't found the error.
Thank you very much.
You didn't add a RegisterServices in NinjectWebCommon:
System.Web.Mvc.DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
Listing 7-2: Integrating Ninject in the NinjectWebCommon.cs File (pg 166)
private static void RegisterServices(IKernel kernel) {
System.Web.Mvc.DependencyResolver.SetResolver(new SportsStore.WebUI.Infrastructure.NinjectDependencyResolver(kernel));
}

MVC4 / Ninject - How to change bindings after Authentication

I am using MVC4 with Ninject (4.0.30319) and NinjectWebCommon.cs. I have Ninject set up and working with a common set of bindings for MVC and the WebAPI.
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
// Install our Ninject-based IDependencyResolver into the Web API config
GlobalConfiguration.Configuration.DependencyResolver = new NinjectWebAPIDependencyResolver(kernel);
// Install our Ninject-based IDependencyResolver into the MVC config
DependencyResolver.SetResolver(new NinjectMVCDependencyResolver(kernel));
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<DBDataContext>().To<DBDataContext>();
kernel.Bind<IChecksRepository>().To<ChecksRepository>();
kernel.Bind<IDepartmentsRepository>().To<DepartmentsRepository>();
kernel.Bind<IEmployeesRepository>().To<EmployeesRepository>();
kernel.Bind<IScheduleRepository>().To<ScheduleRepository>();
kernel.Bind<IVacanciesRepository>().To<VacanciesRepository>();
kernel.Bind<IVacancyTypes>().To<VacancyTypesRepository>();
}
public static void RegisterAuthenticatedServices()
{
bootstrapper.Kernel.Bind<DBDataContext>().To<DBDataContext>().WithPropertyValue("ChangedByPKID", Globals.UserPKID);
}
In Global.asax I have some one-shot code to determine when the user is authenticated and it calls RegisterAuthenticatedServices to change the binding and it executes without an exception. The problem is that after the binding is changed and a controller is requested MVC complains that "No parameterless constructor defined for this object" which I am guessing means the DBDataContext binding is trashed in Ninject. Not sure what I am doing wrong.
Unbind the context and then bind it back with the changes:
public static void RegisterAuthenticatedServices()
{
bootstrapper.Kernel.Unbind<DBDataContext>();
bootstrapper.Kernel.Bind<DBDataContext>().To<DBDataContext>().WithPropertyValue("ChangedByPKID", Globals.UserPKID);
}

SignalR dependency injection via Spring.Net

I'm trying to inject dependencies via Spring.NET.
First I created a custom DependencyResolver:
public class SignalRSpringNetDependencyResolver : DefaultDependencyResolver
{
private IApplicationContext _context;
public SignalRSpringNetDependencyResolver(IApplicationContext context)
{
_context = context;
}
/// <summary>
/// Gets the application context.
/// </summary>
/// <value>The application context.</value>
public IApplicationContext ApplicationContext
{
get
{
if (_context == null || _context.Name != ApplicationContextName)
{
if (string.IsNullOrEmpty(ApplicationContextName))
{
_context = ContextRegistry.GetContext();
}
else
{
_context = ContextRegistry.GetContext(ApplicationContextName);
}
}
return _context;
}
}
/// <summary>
/// Gets or sets the name of the application context.
/// </summary>
/// <remarks>
/// Defaults to using the root (default) Application Context.
/// </remarks>
/// <value>The name of the application context.</value>
public static string ApplicationContextName { get; set; }
/// <summary>
/// Resolves singly registered services that support arbitrary object creation.
/// </summary>
/// <param name="serviceType">The type of the requested service or object.</param>
/// <returns>The requested service or object.</returns>
public override object GetService(Type serviceType)
{
System.Diagnostics.Debug.WriteLine(serviceType.FullName);
if (serviceType != null && !serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
{
var services = ApplicationContext.GetObjectsOfType(serviceType).GetEnumerator();
services.MoveNext();
try
{
return services.Value;
}
catch (InvalidOperationException)
{
return null;
}
}
else
{
return base.GetService(serviceType);
}
}
/// <summary>
/// Resolves multiply registered services.
/// </summary>
/// <param name="serviceType">The type of the requested services.</param>
/// <returns>The requested services.</returns>
public override IEnumerable<object> GetServices(Type serviceType)
{
var services = ApplicationContext.GetObjectsOfType(serviceType).Cast<object>();
services.Concat(base.GetServices(serviceType));
return services;
}
Note that i escape interfaces and abstract classes so that I will get the default implementations of SignalR from the base DefaultDependencyResolver
and here I assigned the resolver using WebActivator:
public static void PostStart()
{
// Inject Dependencies to SignalR, should be always come before ASP.NET MVC configuration
var dependecyResolver = new SignalRSpringNetDependencyResolver(ContextRegistry.GetContext());
GlobalHost.DependencyResolver = dependecyResolver;
RouteTable.Routes.MapHubs();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
However, SignalR is always trying to resolve it's own dependencies using the Resolver i assigned and i get the following error:
'myhub' hub could not be resolved.
I only need the resolver to be aware of other dependencies(my Repository for example) and keep the default implementation of SignalR services.
I think it's hard to get Spring.Net working with SignalR
for the current version (Spring.Net 1.3.2) it's difficult to support asynchronous programming. Spring.Net session management doesn't play well with Task<T> types.
I ended up injecting my dependencies in 2 steps:
1- registering the required type on WebActivator PostStart:
GlobalHost.DependencyResolver.Register(
typeof(IUserService),
() => (UserService)ctx.GetObject("UserService"))
2- picking them up in my Hub constructor:
public MyHub()
{
_userService =
DependencyResolver.Current.GetService<IUserService>();
}

Content-Type header value missing after upgrade to WCF Data Services 5.0

After upgrading to WCF Data Services 5.0 for OData V3 i can't make insert or updates.
The only thing that is possible are selects.
EDIT
Exception in overridden method HandleException:
Exception:
System.Data.Services.DataServiceException: Content-Type header value missing.
at System.Data.Services.HttpProcessUtility.ReadContentType(String contentType, String& mime, Encoding& encoding)
at System.Data.Services.Serializers.Deserializer.CreateDeserializer(RequestDescription description, IDataService dataService, Boolean update, UpdateTracker tracker)
at System.Data.Services.DataService1.HandlePostOperation(RequestDescription description, IDataService dataService)
at System.Data.Services.DataService1.ProcessIncomingRequest(RequestDescription description, IDataService dataService)
at System.Data.Services.DataService1.HandleNonBatchRequest(RequestDescription description)
at System.Data.Services.DataService1.HandleRequest()
ResponseStatusCode: 400
Client-Code
I set a token in the HTTP-Request-Header...
/// <summary>
/// Initializes a new instance of the <see cref="ServiceBase"/> class.
/// </summary>
/// <param name="uri">service uri</param>
protected ServiceBase(Uri uri)
{
this.Context = new Entities(uri) { MergeOption = MergeOption.OverwriteChanges };
this.Context.SendingRequest += new EventHandler<SendingRequestEventArgs>(this.ContextSendingRequest);
}
/// <summary>
/// OnSendingRequest
/// </summary>
/// <param name="sender">source</param>
/// <param name="e">event args</param>
private void ContextSendingRequest(object sender, SendingRequestEventArgs e)
{
e.RequestHeaders["token"] = "xyassdfdfdfdf";
}
Service-Code:
The Service parses this Header and checks the token
public XYDataService()
{
this.ProcessingPipeline.ProcessingRequest += this.ProcessingPipelineProcessingRequest;
}
/// <summary>
/// OnProcessingRequest
/// </summary>
/// <param name="sender">source</param>
/// <param name="e">event args</param>
private void ProcessingPipelineProcessingRequest(object sender, DataServiceProcessingPipelineEventArgs e)
{
var authHeader = HttpContext.Current.Request.Headers["token"];
if (string.IsNullOrEmpty(authHeader) || !authHeader.Equals("xyassdfdfdfdf"))
{
throw new DataServiceException(401, "401 Unauthorized");
}
}
Thanks for your help.
Andi
Using answer since I need to put more text here.
I tried a very similar code to yours, but it works just fine:
DemoService ctx = new DemoService(new Uri("http://services.odata.org/(S(jcemln1vp0u1gqtoyqqpwrc1))/OData/OData.svc/"));
ctx.UsePostTunneling = true;
ctx.SendingRequest += (sender, ea) => { ea.RequestHeaders["token"] = "value"; };
ctx.UpdateObject(ctx.Products.First());
ctx.SaveChanges();
Running this using the latest WCF DS 5.0 bits from NuGet works. I also verified with Fiddler that it does send the Content-Type header.
Your request on the other hand doesn't have the Content-Type header. Can you please verify that you're using the latest NuGet packages and that the code you posted above is really what you're testing?

WCF - A web service running in IIS but through a factory doesn't keep up the original exception thrown

A web service running in IIS but through a factory doesn't keep up the original exception thrown.
For example:
My web service has been marked up with FaultContractAttribute like this way:
public interface IMyService
{
[FaultContract(typeof(MyCustomException))]
[OperationContract]
bool IsAuthorized();
}
My web service implementation has throws out a custom exception like this way:
public class MyService : IMyService
{
public bool IsAuthorized()
{
throw new FaultException<MyCustomException>(fault, fr);
}
}
Then:
If my WCF - NOT using any factory - is similar to <%# ServiceHost Language="C#" Debug="true" Service="MyService" %>, then on client side I CAN pick up the original exception (MyCustomException)
If my WCF - USING some factory - is similar to <%# ServiceHost Language="C#" Debug="true" Service="MyService" Factory="MyFactory" %>, then on client side I CAN'T pick up the original exception (MyCustomException) but only SOAP exception (FaultException) with useless general trace & message
Note:
WCF factory MyFactory is implemented with its SERVICE HOST contains a SERVICE BEHAVIOR initiated from IErrorHandler
In this service behavior, method ProvideFault does nothing (I haven't known how to keep up the original exception by this way)
In summary, I beg answers from expects: How to keep up the original exception (MyCustomException) while using some WCF factory ?
Thanks.
In my recent project (WCF REST services) I use WebServiceHostFactory and I still was able to achieve this using IErrorHandler. Find below a sample
I created a class ExceptionInfo that could be serialized and sent back to the client.
[Serializable]
public class ExceptionInfo
{
public string ExceptionType { get; set; }
public string ExceptionMessage { get; set; }
public string StackTrace { get; set; }
}
And implementing a custom error handler
[DataContract]
public class MyCustomServiceErrorHandler : IErrorHandler
{
#region IErrorHandler Members
/// <summary>
/// This method will execute whenever an exception occurs in WCF method execution
/// </summary>
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var exceptionInfo = new ExceptionInfo();
if (error is MyCustomException)
exceptionInfo.ExceptionType = error.Type.ToString();;
else
exceptionInfo.Type = "Unhandled Exception";
exceptionInfo.ExceptionMessage = error.Message;
exceptionInfo.StackTrace = error.StackTrace;
var faultException = new FaultException<ExceptionInfo>(exceptionInfo);
object detail = faultException.GetType().GetProperty("Detail").GetGetMethod().Invoke(faultException, null);
fault = Message.CreateMessage(version, "", detail, new DataContractSerializer(detail.GetType()));
var webBodyFormatMessageProp = new WebBodyFormatMessageProperty(WebContentFormat.Xml);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProp);
var httpResponseMessageProp = new HttpResponseMessageProperty();
httpResponseMessageProp.Headers[HttpResponseHeader.ContentType] = "application/xml";
httpResponseMessageProp.StatusCode = HttpStatusCode.BadRequest;
httpResponseMessageProp.StatusDescription = exceptionInfo.ExceptionMessage;
fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponseMessageProp);
}
/// <summary>
/// Performs error related behavior
/// </summary>
/// <param name="error">Exception raised by the program</param>
/// <returns></returns>
public bool HandleError(Exception error)
{
// Returning true indicates that an action(behavior) has been taken (in ProvideFault method) on the exception thrown.
return true;
}
Now you can decorate your services using the above handler.
[ServiceContract]
[ServiceErrorBehavior(typeof (MyCustomServiceErrorHandler))]
public class LoginService : ServiceBase
{}
On the client side, you can check if the HttpStatusCode of the response != Ok and deserialize the response to ExceptionInfo type and display in a message box or handle per requirement.
Hope this helps.