【问题标题】:WCF REST Post Complex ObjectWCF REST 发布复杂对象
【发布时间】:2016-09-14 20:27:16
【问题描述】:

由于某种原因,我的 AttributeContract 对象没有正确地从我的客户端传递到我的服务方法。我可以通过调用成功访问该方法,但对象为空。关于我在这里做错了什么有什么建议吗?

客户

using (var client = new HttpClient())
{
    string serviceCall = string.Format("{0}AttributeService.svc/AttributeDefinition/", _serviceLocation);

    int attributeIdInt = Convert.ToInt32(attributeId);
    int objectIdInt = Convert.ToInt32(objectId);

    AttributeContract attributeContract = new AttributeContract()
    {
        AttributeId = attributeIdInt,
        AttributeValue = attributeValue,
        ObjectId = objectIdInt,
        ObjectType = objectType
    };

    string attributeString = JsonConvert.SerializeObject(attributeContract);
    string requestJsonString = "{ \"attribute\" : " + attributeString + " }";

    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, serviceCall);
    request.Content = new StringContent(requestJsonString, Encoding.UTF8, "application/json");

    HttpResponseMessage response = client.SendAsync(request).Result;

}

数据合同

[DataContract(Name = "AttributeContract")]
public class AttributeContract
{
    [DataMember(Name = "AttributeId")]
    public int AttributeId { get; set; }

    [DataMember(Name = "Attribute")]
    public string Attribute { get; set; }

    [DataMember(Name = "AttributeValue")]
    public string AttributeValue { get; set; }

    [DataMember(Name = "ObjectId")]
    public int ObjectId { get; set; }

    [DataMember(Name = "ObjectType")]
    public string ObjectType { get; set; }

    [DataMember(Name = "LastModifiedDate")]
    public DateTime LastModifiedDate { get; set; }

    [DataMember(Name = "LastModifiedUser")]
    public string LastModifiedUser { get; set; }
}

服务合同

[OperationContract]
[WebInvoke(Method = "PUT", 
    RequestFormat = WebMessageFormat.Json, 
    ResponseFormat = WebMessageFormat.Json, 
    UriTemplate = "AttributeDefinition/")]
void UpdateAttributes(AttributeContract attribute);

服务方式

[OperationBehavior(TransactionScopeRequired = true)]
public void UpdateAttributes(AttributeContract attribute)
{
    attribute.LastModifiedDate = DateTime.Now;    
}

【问题讨论】:

    标签: c# json rest wcf


    【解决方案1】:

    您的方法不匹配:在服务合同上输入为 PUT,但在客户端上输入为 POST。您的对象名称也不匹配:属性=!属性契约

    【讨论】:

    • 是的 - 该方法是一个错误,该方法已被纠正并得到相同的结果。哪些对象名称需要相同。 JSON 中的对象名称和服务合同、服务方法...?我尝试了几种不同的命名约定,因为这似乎是最明显的问题。
    • 不重要,不要使用对象名或方法变量名。仅发送属性:{ AttributeId: 1, Attribute: "ss"}
    • 首先使用工具而不是 c# 代码进行服务测试。例如 chrome 浏览器有一个扩展名为 Postman 是最好的。
    • 好的 - 我尝试发送没有“属性”包装器的 JSON,但它返回 400 - 错误请求。我将研究 Chrome,但是,我正在使用 MVC,并且在视图中我正在对控制器进行 jQuery AJAX 调用,该控制器转身并通过上述方法调用服务。所以,在使用浏览器工具时,我经常只得到第一个 jQuery AJAX 调用。
    【解决方案2】:
    string serviceCall = string.Format("{0}AttributeService.svc/AttributeDefinition/", _serviceLocation);
    
        int attributeIdInt = Convert.ToInt32(attributeId);
        int objectIdInt = Convert.ToInt32(objectId);
    
        AttributeContract attributeContract = new AttributeContract()
        {
            AttributeId = attributeIdInt,
            AttributeValue = attributeValue,
            ObjectId = objectIdInt,
            ObjectType = objectType
        };
    
                        var request =
                            (HttpWebRequest)
                                WebRequest.Create(new Uri(serviceCall );
                        request.ContentType = "application/json";
                        request.Method = "PUT";
                        var itemToSend = JsonConvert.SerializeObject(
                            attributeContract 
                            );
                        using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
                        {
                            streamWriter.Write(itemToSend);
                            streamWriter.Flush();
                            streamWriter.Dispose();
                        }
    

    试试这个代码

    【讨论】:

    • 我希望使用 HttpClient 来做所有事情。但是,我正在审查这个,可能会切换到 WebRequest/WebResponse。
    • 我记得我在使用 httpclient 时也遇到了问题,我使用了这种方式
    • 当您这样做时,您能够将 JSON 反序列化为服务端的对象并访问其成员?
    • 如果我们发送没有“属性”包装器的 JSON,我们会得到一个 400 的 WebResponse - 错误请求。如果我们使用 wrapper 发送对象仍然永远不会到达服务,但是,我们可以使用 200 到达服务。
    【解决方案3】:

    事实证明,您不需要 JSON 中的对象包装器(根据 mkysoft)。对fiddler 的一点挖掘表明,我在反序列化我的数据合同上的 datetime 属性时遇到了问题。在确定最佳前进路径时,我将属性从 DateTime 更改为字符串。

    【讨论】:

      猜你喜欢
      • 2014-01-06
      • 2011-01-04
      • 2016-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      相关资源
      最近更新 更多