【问题标题】:Return different Object (List or error class) from WCF service [duplicate]从 WCF 服务返回不同的对象(列表或错误类)[重复]
【发布时间】:2016-12-27 18:45:54
【问题描述】:

我正在尝试构建一个 WCF 服务,它有一个方法 getPersonList,它返回这样的人的列表

[
  {"personId":121, "personName":"John Smith"},
  {"personId":953, "personName":"Maggie Johnson"}
]

如果有错误,我想用同样的方法返回这样的错误响应。

{"errorCode":4002,"errorMessage":"invalid request token"}

现在我的服务合同如下:

    [ServiceContract()]
    public interface IPersonContract
    {
        [OperationContract()]
        Object GetPersonList(int requestParam);
    }

和我的示例GetPersonList 方法

Object GetPersonList(int requestParam)
{
  if (requestParam == 1)
  {
    ErrorResponse error = new ErrorResponse();
    error.ErrorCode = 4002;
    error.ErrorMessage = "invalid request token";

    return error;
  }else
  {
    List<Person> returnList = new List<Person>();
    // add Person to returnList
    return returnList;
  }

}

人物类

[DataContract()]
public class Person
{

    [DataMember(Name = "personName")]
    String PersonName{   get;   set;  }

    [DataMember(Name = "personId")]
    String PersonID {   get;   set;  }

}

错误类

[DataContract()]
public class ErrorResponse
{

    [DataMember(Name = "errorCode")]
    int ErrorCode{   get;   set;  }

    [DataMember(Name = "errorMessage")]
    String ErrorMessage{   get;   set;  }

}

我查找了 KnownTypes 的 DataContract 类,但我如何将其应用于 Object

如果我从 ErrorReponse 添加字段并在单个类中添加 List&lt;Person&gt; 并返回该对象,我会在成功的情况下得到这样的响应,这不是我想要的。

{
"Person":[{"personId":121, "personName":"John Smith"},
      {"personId":953, "personName":"Maggie Johnson"}]
}

【问题讨论】:

  • 检查这个链接,你错过了我认为的 [WebMethod...] 装饰stackoverflow.com/questions/2086666/…
  • 将响应序列化为 JSON 并让客户端确定(反序列化后)是否发生错误不是更容易吗?
  • @cFrozenDeath - 这只是一个复杂场景的简单示例。可能有多个错误条件。所以我们需要不同的结构来处理正面和负面的情况
  • @KarouiHaythem - 谢谢,我忘了在这个例子中添加这个
  • 只需利用 WCF 已经提供的机制:使用 FaultContracts 并抛出一个 FaultException。搜索“wcf 故障处理”以查找大量信息。

标签: c# wcf datacontract


【解决方案1】:

更改您的服务合同定义,例如 -

    [OperationContract]
    [WebInvoke(Method = "GET",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    UriTemplate = "/get/{id}")]
    [ServiceKnownType(typeof(RootObject1))]
    [ServiceKnownType(typeof(RootObject2))]
    object GetOrder(string id);

服务实现-

    public object GetOrder(string id)
    {
        if (id.Length == 1)
        {
            return new RootObject1 { errorCode = 4002, errorMessage = "invalid request token" };
        }
        return new RootObject2 { personId = 121, personName = "John Smith" };
    }


2016 年 12 月 27 日更新为列表类型

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, Method = "GET", UriTemplate = "GetOrdersJSON?ClientID={ClientID}&SenderEmail={SenderEmail}&VersionNumber={VersionNumber}")]
    [ServiceKnownType(typeof(List<MyCustomErrorDetail>))]
    [ServiceKnownType(typeof(List<ShipToDetails>))]
    object GetOrdersJSON(int ClientID, string SenderEmail, string VersionNumber);


[DataContract]
public class MyCustomErrorDetail
{
    public MyCustomErrorDetail(string errorInfo, string errorDetails)
    {
        ErrorInfo = errorInfo;
        ErrorDetails = errorDetails;
    }

    [DataMember]
    public string ErrorInfo { get; private set; }

    [DataMember]
    public string ErrorDetails { get; private set; }
}

当没有记录或发生任何其他错误时,根据您的需要从 GetOrdersJSON 返回以下对象!

                MyCustomErrorDetail myCustomErrorObject = new MyCustomErrorDetail("There are no records available", string.Format("There are no records available for user {0}", fstr_UserName));
                List<MyCustomErrorDetail> myCustomErrorList = new List<MyCustomErrorDetail>();
                myCustomErrorList.Add(myCustomErrorObject);
                return myCustomErrorList;

【讨论】:

  • 谢谢,不知道ServiceKnownType。一定会去看看
【解决方案2】:

我刚刚返回了一个标准的 HTTPResponseException,如下所示:

    public clsUserInfo Get(String id, String pwd)
    {
        clsResultsObj<clsUserInfo> retVal = new clsResultsObj<clsUserInfo>();

        retVal = bizClass.GetUserByIDAndPWD(id, pwd);

        if (retVal.IsSuccessful & retVal.Payload != null)
        {
            return retVal.Payload;
        }
        else
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

    }

但您可以更进一步,为您自己的自定义错误消息使用类似这样的内容:

{ 
    throw new WebFaultException<string>(string.Format(“There is no user with the userName ‘{0}’.”, userName), HttpStatusCode.NotFound); 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多