0

コントラクトを説明するWebGet属性とWebInvoke属性がありますが、無効なURIを処理するための最良の方法は何ですか?現在、ユーザーが私の現在の操作と一致しないURIを渡すと、「エンドポイントが見つかりません」というメッセージが表示されます。メッセージ。もっとわかりやすいメッセージをお返ししたいと思います。

たとえば、私のURIテンプレートは次のようになります。

/Stuff/{ID}/subStuff

しかし、彼らはタイプすると言います

/Stuff/{ID}/OtherStuff

OtherStuffのようなものはなく、そのためのテンプレートもありません。

マップされていないすべてのURIを単一のコントラクトでカバーする方法はありますか?

ありがとう!

4

2 に答える 2

1

WCF RESTでグローバルレベルですべての未処理の要求をキャッチする場合は、この投稿WebHttpBehaviorで説明されているように、カスタムとカスタムを作成する必要があります。IOperationInvoker

カスタムステータスコード(404)を含むカスタムエラーテキストを返したい場合は、ここでWebOperationContext.OutgoingResponse説明されているようにプロパティを調べることもできます。

于 2012-06-25T17:39:05.877 に答える
1

私は提供されたリンクマークをたどりましたが、それらは私が必要なもののヒントを与えてくれました。リンクされた回答は、実際には私の元の質問に答えていませんでした。

手順を実行することができたので、この質問にもこの問題を解決するための手順をリストしたいと思いました。

コントラクトのメソッドにマップされていない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」をシリアル化できる限り、そのシリアル化された表現がクライアントに返送されます。

于 2012-07-19T22:21:46.970 に答える