2011-04-20 45 views
2

我有一個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

回答

2

如在評論中提及@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