POST 到 WCF 服务

Posted

技术标签:

【中文标题】POST 到 WCF 服务【英文标题】:POST To WCF Service 【发布时间】:2011-02-06 14:07:02 【问题描述】:

我正在尝试将一个序列化对象发布到我的 WCF 服务。但是,我不断收到“NotFound”错误。三天以来,我一直在为此苦苦挣扎。有人可以告诉我我做错了什么吗?下面是我的客户端代码、我的 WCF 服务操作以及我尝试序列化的类定义。

客户端代码

// Build a wrapper exception that will be serialized
Exception ex = e.ExceptionObject;
MyException exception = new MyException(ex.Message, ex.StackTrace, "silverlight app", ex.GetType().FullName, string.Empty);

string json = string.Empty;
using (MemoryStream memoryStream = new MemoryStream())

  // Serialize the object 
  DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectType);
  serializer.WriteObject(memoryStream, objectToSerialize);

  // Convert the data to json
  byte[] bytes = memoryStream.ToArray();
  int count = (int)(memoryStream.Length);
  json = Encoding.UTF8.GetString(bytes, 0, count);


 // Submit the information to log
string url = "http://localhost:90/services/MyService.svc/LogError";
WebClient loggingService = new WebClient();
loggingService.UploadStringCompleted += new UploadStringCompletedEventHandler(loggingService_UploadStringCompleted);
loggingService.Headers["Content-type"] = "application/json";
loggingService.Encoding = Encoding.UTF8;
loggingService.UploadStringAsync(new Uri(logExceptionUrl), "POST", json);

MyException(客户端版本)

public class MyException : Exception

  private readonly string stackTrace;
  public override string StackTrace
  
    get 
      return base.StackTrace;
    
  

  private readonly string message;
  public override string Message
  
    get 
      return base.Message;
    
  

  private readonly string component;
  public string Component
  
    get  return component; 
  

  private readonly string typeName;
  public string TypeName
  
    get  return typeName; 
  

  private readonly string miscellaneous;
  public string Miscellaneous
  
    get  return miscellaneous; 
  

  public MyException()
   

  public MyException(string message) : base(message)
   

  public MyException(string message, Exception inner) : base(message, inner)
   

  public MyException(string message, string stackTrace) : base()
  
    this.message = message;
    this.stackTrace = stackTrace;
  

  public MyException(string message, string stackTrace, string component, string typeName, string miscellaneous) : base()
  
    this.message = message;
    this.stackTrace = stackTrace;
    this.component = component;
    this.typeName = typeName;
    this.miscellaneous = miscellaneous;
  

WCF 服务

[OperationContract]
[WebInvoke(UriTemplate = "/LogError", BodyStyle=WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public string LogError(MyException exc)

  try
   
    // Write the details of exc to the database 
    return "ok";
  
  catch (Exception ex)
  
    return "error";
  

WCF 项目中的 MyException

[Serializable]
public class MyException : Exception

  public override string StackTrace
  
    get  return base.StackTrace; 
  
  private readonly string stackTrace;

  public override string Message
  
    get  return base.Message; 
  
  private readonly string message;

  public string Component
  
    get  return component; 
    set  /* */ 
  
  private readonly string component;

  public string TypeName
  
    get  return typeName; 
    set  /* */ 
  
  private readonly string typeName;

  public string Miscellaneous
  
    get  return miscellaneous; 
    set  /* */ 
  
  private readonly string miscellaneous;

  public MyException() 
  

  public MyException(string message) : base(message)
   

  public MyException(string message, Exception inner) : base(message, inner)
   

  public MyException(string message, string stackTrace) : base()
  
    this.message = message;
    this.stackTrace = stackTrace;
  

  public MyException(string message, string stackTrace, string component, string typeName, string miscellaneous) : base()
  
    this.message = message;
    this.stackTrace = stackTrace;
    this.component = component;
    this.typeName = typeName;
    this.miscellaneous = miscellaneous;
     

  protected MyException(SerializationInfo info, StreamingContext context) : base(info, context)
  
    component = info.GetString("component");
    typeName = info.GetString("typeName");
    miscellaneous = info.GetString("miscellaneous");
  

  public override void GetObjectData(SerializationInfo info, StreamingContext context)
  
    base.GetObjectData(info, context);
    info.AddValue("component", component);
    info.AddValue("typeName", typeName);
    info.AddValue("miscellaneous", miscellaneous);
  

感谢您的帮助!

【问题讨论】:

当您说“未找到”时,您能否详细说明确切的 HTTP 错误。是 404 还是 400(错误请求)? 【参考方案1】:

为了在 .NET 中调用 Web 服务,您通常会生成一个客户端代理。您可以在 Visual Studio 中使用svcutil.exe 实用程序或Add Service Reference... 对话框。拥有强类型客户端代理后,您只需调用服务即可,无需使用任何 WebClients、MemoryStreams、DataContractJsonSerializers...

using (var client = new MyWebServiceClient())

    var result = client.SomeMethod();

WCF 基础架构负责其余的工作。

【讨论】:

嗨达林,我理解这种方法。但是,我也想稍后从 android 应用程序调用此方法。因此,我现在正在尝试了解如何在客户端正确序列化对象。 @user208662,至少当您拥有 .NET 客户端时,为什么不简化您的生活呢?当您必须编写一个 Android 客户端时,您将没有与 .NET 中相同的类来调用它,因此您在此处编写的代码将无法重用。方法将完全不同。所以这就是我的建议。如果您想查看确切的数据,请在 .NET 中正确执行此操作,并使用 Wireshark 等网络分析工具准确查看通过网络交换的内容。 +1 除非您 (@user208662) 需要在 .NET 之外调用它。该服务似乎是 RESTful 的,在这种情况下,您可以在没有强类型代理的情况下调用,但除非您有需要,否则只需构建一个代理类。如果您需要仅使用 webClient 进行调用,则需要使用 DataContract 属性标记 MyException 类,并真正修饰您的序列化以确保 Json 网络上的 Json 与端点期望的完全匹配。 (这是代理将在其他方面为您提供帮助的内容) 100% 同意达林的最后评论。 @ user208662,要正确序列化,您需要对数据进行按摩以与您的服务层期望的 DataContract 完全匹配。最简单的方法是获得一些帮助(.net 代理),使其工作,然后使用序列化类将您从您所在的位置(您上面的示例)带到您想要的位置(over-the- .net 代理为您提供的有线版本) 也许我在做一个不恰当的假设。我想编写一个 iphone、wp7 或 android 应用程序可以发布到的服务操作。您是说我需要为每个客户端编写单独的操作吗?或者有没有办法构建我的操作,以便可以从每个客户端调用它?

以上是关于POST 到 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

HTML 表单 POST 到 WCF 服务

启用从 jQuery ajax 到不在 IIS 中托管的 WCF 服务的 CORS POST

Angular 4 POST 到 WCF REST 服务返回 NULL 响应

自托管 WCF REST 服务 JSON POST 方法不允许

JsonWriter POST 在 Android 中无法工作到 WCF Web 服务

将字符串从 android 传递到 wcf restful 服务变得空