私は提供されたリンクマークをたどりましたが、それらは私が必要なもののヒントを与えてくれました。リンクされた回答は、実際には私の元の質問に答えていませんでした。
手順を実行することができたので、この質問にもこの問題を解決するための手順をリストしたいと思いました。
コントラクトのメソッドにマップされていないURIに対する独自の応答を作成するために、次を作成しました。
- カスタムServiceHostFactory
- カスタムServiceHostFactory内のエンドポイントにマップした動作
- サービスに提供されたすべてのマッピングされていないURIを処理するディスパッチャ。
以下は、私が作成したオブジェクトの完全な定義です。
using System.ServiceModel;
using System.ServiceModel.Activation;
namespace your.namespace.here
{
public class CustomServiceHostFactory : WebServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
//note: these endpoints will not exist yet, if you are relying on the svc system to generate your endpoints for you
// calling host.AddDefaultEndpoints provides you the endpoints you need to add the behavior we need.
var endpoints = host.AddDefaultEndpoints();
foreach (var endpoint in endpoints)
{
endpoint.Behaviors.Add(new WcfUnkownUriBehavior());
}
return host;
}
}
}
上記のように、新しい動作WcfUnknownUriBehaviorを追加しています。この新しいカスタム動作の主な義務は、UnknownDispatcherを置き換えることです。以下はその実装です:
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
namespace your.namespace.here
{
public class UnknownUriDispatcher : IOperationInvoker
{
public object[] AllocateInputs()
{
//no inputs are really going to come in,
//but we want to provide an array anyways
return new object[1];
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
var responeObject = new YourResponseObject()
{
Message = "Invalid Uri",
Code = "Error",
};
Message result = Message.CreateMessage(MessageVersion.None, null, responeObject);
WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
outputs = new object[1]{responeObject};
return result;
}
public System.IAsyncResult InvokeBegin(object instance, object[] inputs, System.AsyncCallback callback, object state)
{
throw new System.NotImplementedException();
}
public object InvokeEnd(object instance, out object[] outputs, System.IAsyncResult result)
{
throw new System.NotImplementedException();
}
public bool IsSynchronous
{
get { return true; }
}
}
}
これらのオブジェクトを指定すると、svcの「マークアップ」内で新しいファクトリを使用できるようになります。
<%@ ServiceHost Language="C#" Debug="true" Service="your.service.namespace.here" CodeBehind="myservice.svc.cs"
Factory="your.namespace.here.CustomServiceHostFactory" %>
そしてそれはそれであるはずです。オブジェクト「YourResponseObject」をシリアル化できる限り、そのシリアル化された表現がクライアントに返送されます。