Вопрос по wcf, rest – Обработка неверного URI, переданного службе WCF
У меня есть атрибуты WebGet и WebInvoke, описывающие мой контракт, но каков наилучший метод обработки недействительных URI? Прямо сейчас, если пользователь передает URI, который не соответствует моим текущим операциям, он получает «конечную точку не найдена». сообщение. Я хочу передать более описательное сообщение.
Например, мой шаблон URI выглядит так:
/Stuff/{ID}/subStuff
но говорят, что они печатают
/Stuff/{ID}/OtherStuff
OtherStuff не существует, и у меня нет шаблона для этого.
Есть ли способ покрыть все не отображенные URI одним контрактом?
Спасибо!
они давали намек на то, что мне нужно. Ответы, которые были связаны, на самом деле не отвечали на мой первоначальный вопрос.
Я был в состоянии следовать за шагами, и я хотел перечислить свои шаги, чтобы решить эту проблему также в этом вопросе.
Чтобы создать собственный ответ на любой URI, который не был сопоставлен с методом в моем контракте, я создал следующее:
A custom ServiceHostFactory Behavior that I mapped to my end points within the custom ServiceHostFactory a dispatcher that would handle all unmapped uri's that were provided to the service.Ниже приведены полные определения объекта, который я создал:
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 & quot; разметке & quot ;:
<%@ ServiceHost Language="C#" Debug="true" Service="your.service.namespace.here" CodeBehind="myservice.svc.cs"
Factory="your.namespace.here.CustomServiceHostFactory" %>
И это должно быть. пока ваш объект & quot; YourResponseObject & quot; может быть сериализовано, его сериализованное представление будет отправлено обратно клиенту.
уровне в WCF REST, вам нужно создать пользовательскийWebHttpBehavior
и обычайIOperationInvoker
как описано в этомсообщение.
Если вы хотите вернуть пользовательский текст ошибки с пользовательским кодом состояния (404), вы также можете посмотреть вWebOperationContext.OutgoingResponse
свойство как описаноВот.