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 服务的主要内容,如果未能解决你的问题,请参考以下文章
启用从 jQuery ajax 到不在 IIS 中托管的 WCF 服务的 CORS POST
Angular 4 POST 到 WCF REST 服务返回 NULL 响应
自托管 WCF REST 服务 JSON POST 方法不允许