我第一次尝试实现Restful WCF服务,但不能让它发布我的对象:( 它在客户端代码中崩溃(见下文)。什么可以解决? 感谢
部分web.config
<system.serviceModel>
<services>
<service name="MyRest.Service1" behaviorConfiguration="ServBehave">
<!--Endpoint for REST-->
<endpoint address="XMLService" binding="webHttpBinding" behaviorConfiguration="restPoxBehavior" contract="MyRest.IService1" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServBehave">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<!--Behavior for the REST endpoint for Help enability-->
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
客户代码:
public string ClientStuff()
{
var ServiceUrl = "http://localhost/MyRest/Service1.svc/XMLService/";
var empserializer = new DataContractSerializer(typeof(MyRest.Employee));
var url = new Uri(ServiceUrl + "PostEmp");
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/XML";
var emp = new MyRest.Employee { DeptName = "sale", EmpName = "ted", EmpNo = 11112 };
using (var requeststream = request.GetRequestStream())
{
empserializer.WriteObject(requeststream, emp);
}
var response = (HttpWebResponse)request.GetResponse();// crashes here with error in title
var statuscode = response.StatusCode;
return statuscode.ToString();
}
service1.svc.cs
public bool PostEmp(Employee employee)
{
//something
return true;
}
的ServiceContract
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/PostEmp", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
bool PostEmp(Employee employee);
// TODO: Add your service operations here
}
答案 0 :(得分:1)
您应该修复几件事。第一个当然是使用正确的内容类型标题,没有application/XML
这样的东西:
request.ContentType = "text/xml";
和另一个,更重要的是确保您在服务器和客户端中引用完全相同的Employee
类,否则客户端数据协定序列化程序将在XML中发出不同的命名空间,从而构成服务器崩溃。基本上,这个Employee
类应该在服务器和客户端应用程序之间的共享类库中声明。
顺便说一下,将来您可以更轻松地自行调试此类问题,而不是在服务方面enable tracing仅发布问题:
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\log\Traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
然后使用内置于.NET SDK跟踪查看器(SvcTraceViewer.exe)来简单地加载生成的日志文件,所有内容都将通过GUI显示和解释(看起来像来自90年代但是这个工作。)
啊,顺便说一句,您可能需要通过从web.config中删除以下行来禁用ASP.NET兼容性:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
我不是百分百肯定,但是对于启用REST的服务,这是必要的(尽管在这个问题上可能会出错)。
答案 1 :(得分:0)
非常感谢,花了几天的时间,现在我可以使用以下代码获得正确的响应:
var ServiceUrl = "http://localhost/MyRest/Service1.svc/XMLService/";
var empserializer = new DataContractSerializer(typeof(MyRest.Employee));
var url = new Uri(ServiceUrl + "PostEmp");
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/XML";
var emp = new MyRest.Employee { DeptName = "sale", EmpName = "ted", EmpNo = 11112 };
using (var requeststream = request.GetRequestStream())
{
empserializer.WriteObject(requeststream, emp);
}
var response = (HttpWebResponse)request.GetResponse();// crashes here with error in title
var statuscode = response.StatusCode;
return statuscode.ToString();
在代码行下面添加此附录:
StreamReader reader = new StreamReader(response.GetResponseStream());
string ResponseMessage = reader.ReadToEnd();