使用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();
}
如在评论中提及@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 Primer为LifetimeScope
。
看起来像一个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
@Nicholas,感谢您看到这个,希望这不是一个WCF的问题,所以它很容易解决。 – 2011-04-21 01:52:55
@neontapir也许你应该发布你的代码作为答案,因为我放弃了这一点,并没有得到它的工作;) – 2011-10-04 12:12:39