我有WebGet和WebInvoke属性描述我的合同,但处理无效URI的最佳方法是什么?现在,如果用户传递的URI与我当前的操作不匹配,则会收到“未找到端点”。信息。我想传回一条更具描述性的信息。
例如,我的URI模板如下所示:
/Stuff/{ID}/subStuff
但是说他们输入
/Stuff/{ID}/OtherStuff
没有OtherStuff这样的东西,我也没有这个模板。
有没有办法用单一合约覆盖所有非映射的URI?
谢谢!
答案 0 :(得分:1)
如果要在WCF REST中捕获全局级别的所有未处理请求,则必须按照此post中的说明创建自定义WebHttpBehavior
和自定义IOperationInvoker
。
如果您想要返回带有自定义状态代码的自定义错误文本(404),您还可以按照here所述查看WebOperationContext.OutgoingResponse
属性。
答案 1 :(得分:1)
虽然我确实按照提供的链接标记进行了操作,但确实给出了我需要的提示。链接的答案实际上并没有回答我原来的问题。
我能够按照这些步骤操作,我想列出我在这个问题上解决这个问题的步骤。
要创建我自己对任何未映射到合同中方法的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”可以被序列化,它的序列化表示将被发送回客户端。