0

我有这样的服务合同:

[WebGet(UriTemplate = "getdata?key={key}&format={format}")]
Event[] GetIncidentsXml(string key, string format);

在代码中,我正在切换响应格式,如下所示:

var selectedFormat = ParseWebMessageFormat(format);
WebOperationContext.Current.OutgoingResponse.Format = selectedFormat;

(ParseWebMessageFormat 是一种封装 Enum 类型解析的方法)

这部分按预期工作,我根据传递的参数获得 XML 或 JSON。

当我抛出异常时,它就会崩溃。如果传入的(API)密钥无效,我正在这样做:

var exception = new ServiceResponse
{
    State = "fail", 
    ErrorCode = new ErrorDetail { Code = "100", Msg = "Invalid Key" }
};

throw new WebProtocolException(HttpStatusCode.BadRequest, "Invalid Key.", exception, null);

抛出异常时,返回类型始终为XML:

<ServiceResponse xmlns="http://schemas.datacontract.org/2004/07/IBI.ATIS.Web.ServiceExceptions" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <ErrorCode>
        <Code>100</Code>
        <Msg>Invalid Key</Msg>
    </ErrorCode>
    <State>fail</State>
</ServiceResponse>

返回类型更改是服务方法中的第一行代码,因此在抛出异常之前发生。

我知道我可以根据请求格式将 WCF 设置为返回类型,但必须使用通过查询字符串传入的类型。

自动消息类型在配置中关闭:

<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="false" />
4

1 回答 1

0

因为您需要以某种方式指定默认响应格式。您看到的行为是标准的。您将需要查看特定的标头并确定响应格式应该是什么。然后,您可以实现一个请求拦截器来确定传出响应格式需要是什么。

因此,要回答您的问题,如果未提及或返回错误请求,您将需要坚持使用默认格式类型。与 SOAP 不同,REST 与其说是一种协议,不如说是一种范式。

更新:为了澄清起见。你可以做这样的事情。

[ServiceContract()]
public interface ICustomerService
{
   [OperationContract]
   [WebGet(UriTemplate ="?format={formatType}",BodyStyle = WebMessageBodyStyle.Bare)]
   IResponseMessage GetEmCustomers(string formatType);

}

public class CustomerService : ServiceBase
{
  IResponseMessage GetEmCustomers(string formatType)
  {
    try
    {
      var isValid  = base.validateformatspecification(formatType);// check to see if format is valid and supported
      if(!isValid) return base.RespondWithError(formatType,new Error {Msg= "Dude we dont support this format"});
      var customers = CustomerProvider.GetAll();
      return base.Respond(formatType,customer);// This method will format the customers in desired format,set correct status codes and respond.
    }catch(Exception ex)
    {
      // log stuff and do whatever you want
      return base.RespondWithError(formatType,new Error{Msg = "Aaah man! Sorry something blew up"});// This method will format the customers in desired format,set correct status codes and respond.

    }      
  }    
}

public class ServiceBase
{
  public IResponseMessage Respond<T>(string format,T entity);
  public IResponseMessage RespondWithError<T>(string format, T errorObject);

}

public class Error:IResponseMessage {/*Implementation*/}

public class GetEmCustomerResponseResource:List<Customer>,IResponseMessage {/* Implementation*/}

public class GetEmCustomerErrorResponse: IResponseMessage {/* Implementation   */}
于 2012-05-07T16:06:23.070 回答