使用Autofac通过ChannelFactory注册端点的WCF合同不匹配错误

问题描述:

我有一个WCF服务,在被简单的MVC应用程序访问时工作。使用Autofac通过ChannelFactory注册端点的WCF合同不匹配错误

当我尝试就从不同的MVC应用程序,是连线了Autofac相同终点呼叫我得到绑定/合同匹配异常这样的:

Content Type application/soap+xml; charset=utf-8 was not supported by service http://localhost:6985/ProductService.svc . The client and service bindings may be mismatched.

System.Net.WebException: The remote server returned an error: (415) Unsupported Media Type.

我有理由相信我在配置设置两端没有任何不匹配的地方,我将这种信心建立在对Autofac不存在的WCF + MVC组合测试完全相同的设置的基础上。配置设置在pastebin.com/t7wfR77h

因此,我想一些帮助分析,如果我已经注册与Autofac的依赖性/端点的方式是问题...

* *的Application_Start代码MVC应用程序的Autofac设置:

var builder = new ContainerBuilder(); 
//other registrations... 

builder.Register(c => 
      new ChannelFactory<IProductService>(
       new WSHttpBinding("ProductService_wsHttpBinding"), 
       new EndpointAddress("http://localhost:6985/ProductService.svc") 
      ) 
     ).SingleInstance(); 

builder.Register(c => 
     { 
      var factory = c.Resolve<ChannelFactory<IProductService>>(); 
      return factory.CreateChannel(); 
     } 
    ).InstancePerHttpRequest(); 

var container = builder.Build(); 
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

(为了完整性),我使用的这是一个只有1依赖性ProductController的被注入,很简单:

public class ProductController : AsyncController 
{ 
    private IProductService _service; 

    public ProductController(IProductService ps) 
    { 
     _service = ps; 
    } 

    //... 
    //later simply call 
    _service.SomeMethod(); 
} 
+0

看起来像一个WCF配置问题给我,没有太多建议,虽然 - 一些线索在网上... http://blogs.msdn.com/b/endpoint/archive/2010/11/01/wcf- webhttp-service-returns-http-415-unsupported-media-type.aspx祝你好运! – 2011-04-20 10:04:43

+0

@Nicholas,感谢您看到这个,希望这不是一个WCF的问题,所以它很容易解决。 – 2011-04-21 01:52:55

+0

@neontapir也许你应该发布你的代码作为答案,因为我放弃了这一点,并没有得到它的工作;) – 2011-10-04 12:12:39

如在评论中提及@Nick Josevski,我得到了类似于工作的东西。

在我MVC3应用程序的Application_Start方法中,我有以下代码:

protected void Application_Start() 
{ 
    var builder = new ContainerBuilder(); 
    builder.Register(c => new ChannelFactory<ICartService>("CartService")).SingleInstance(); 
    builder.Register(c => c.Resolve<ChannelFactory<ICartService>>().CreateChannel()).InstancePerHttpRequest(); 
    var container = builder.Build(); 
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

    // other MVC startup activities, like registering areas and routes 
} 

这些注册从Web.config文件收集WCF配置数据。我还注册了与代码中定义的端点一起工作。为了完整起见,这里的一些相关的客户端的Web.config条目:

<system.serviceModel> 
    <bindings> 
    <basicHttpBinding> 
     <binding name="BasicHttpBinding" ... /> 
    </basicHttpBinding> 
    </bindings> 
    <client> 
    <endpoint address="http://localhost:50930/Purchasing/CartService.svc" 
     binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" 
     contract="CartService.ICartService" name="CartService" /> 
    </client> 
</system.serviceModel> 

然后,在我的控制,我有类似下面的代码:

using Autofac.Features.OwnedInstances; 

public class BulkCartController : Controller 
{ 
    private readonly Owned<ICartService> cartService_; 

    public BulkCartController(Owned<ICartService> cartService) 
    { 
     cartService_ = cartService; 
    } 

    protected override void Dispose(bool disposing) // defined in Controller 
    { 
     cartService_.Dispose(); 
     base.Dispose(disposing); 
    } 

    // 
    // GET: /BulkCart/Get/1 
    public ActionResult Get(int id) 
    { 
     var model = new ShoppingCart { ShoppingCartId = id }; 
     using (var cartService = cartService_) 
     { 
      model.Items = cartService.Value.GetCartProductItems(id); 
     } 
     return View("Get", model); 
    } 
} 

单元测试是这样的:

using Autofac.Features.OwnedInstances; 
using Autofac.Util; 
using Moq; 

[TestMethod] 
public void Get_ReturnsItemsInTheGivenCart() 
{ 
    var mock = new Mock<ICartService>(MockBehavior.Strict); 
    mock.Setup(x => x.GetCartProductItems(2)).Returns(new CartProductItemViewObject[0]); 
    var controller = new BulkCartController(new Owned<ICartService>(mock.Object, new Autofac.Util.Disposable())); 
    var result = controller.Get(2); 

    Assert.IsInstanceOfType(result, typeof(ViewResult)); 
    var view = (ViewResult)result; 
    Assert.AreEqual("Get", view.ViewName); 

    Assert.IsInstanceOfType(view.ViewData.Model, typeof(ShoppingCart)); 
    var model = (ShoppingCart)view.ViewData.Model; 
    Assert.AreEqual(2, model.ShoppingCartId); 
    Assert.AreEqual(0, model.Items.Length); 
} 

我验证处理与抽象控制器测试基类中定义一个单元测试:

[TestClass] 
public abstract class ControllerWithServiceTestBase<TController, TService> 
    where TController : Controller 
    where TService : class 
{ 
    [TestMethod] 
    public virtual void Dispose_DisposesTheService() 
    { 
     var disposable = new Mock<IDisposable>(MockBehavior.Strict); 
     disposable.Setup(x => x.Dispose()).Verifiable(); 

     var controller = (TController) Activator.CreateInstance(typeof(TController), new Owned<TService>(null, disposable.Object)); 
     controller.Dispose(); 

     disposable.Verify(); 
    } 
} 

有一件事我还不知道这是利用Owned<T>Dispose()是否给了我充分的处置,还是我需要使用每一个An Autofac Lifetime PrimerLifetimeScope