我有这样的服务合同:
[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" />
答案 0 :(得分: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 */}