首页 > 解决方案 > WCF Restful 服务(WebHttpBinding)-“System.Net.WebException”类型的异常-远程服务器返回错误:(404)未找到

问题描述

我正在尝试使用没有 https 的 WebHttpBinding 创建 WCF RESTful 服务。下面是和的IUserMgmtService代码

[ServiceContract]
public interface IUserMgmtService
{
    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest, UriTemplate = "AddUsers")]
    ResponseUser AddUsers(RequestUser requestUser);
}

下面是UserMgmtService.svc将用户添加到 SQL 数据库的代码

[ServiceBehavior(Namespace = "http://localhost:30158/Services/")]
public class UserMgmtService : IUserMgmtService
{
    public ResponseUser AddUsers(RequestUser objData)
    {
        ResponseUser response = new ResponseUser();
        try
        {
            using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["WCFData"].ConnectionString))
            {
                connection.Open();
                string sql = "WCFData_Insert_User";
                SqlCommand cmd = new SqlCommand(sql, connection);
                cmd.Parameters.Add("@UserKey", SqlDbType.BigInt).Value = objData.UserKey;
                cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 100).Value = objData.FirstName;
                cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 100).Value = objData.LastName;
                cmd.Parameters.Add("@EmailAddress", SqlDbType.VarChar, 255).Value = objData.EmailAddress;
                cmd.Parameters.Add("@UserType", SqlDbType.VarChar, 20).Value = objData.UserType;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.ExecuteNonQuery();
            }
            response.Status = "Success - Record Inserted Successfully";
            response.Success = true;
        }
        catch (Exception ex)
        {
            response.Status = "Failure - " + ex.InnerException;
            response.Success = true;
        }
        return response;
    }
}

下面是 RESTful 服务的 Web.Config 配置

 <system.serviceModel>
<extensions>
  <behaviorExtensions>
    <add name="crossOriginResourceSharingBehavior" type="WCFServices.EnableCrossOriginResourceSharingBehavior, WCFServices" />
  </behaviorExtensions>
</extensions>
<bindings>
  <basicHttpBinding>

    <binding name="secureBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
      <!--<readerQuotas maxDepth="200" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />-->
      <readerQuotas maxDepth="200" maxStringContentLength="8388608" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <security mode="Transport" />
    </binding>
  </basicHttpBinding>
  <webHttpBinding>
    <binding name="RestBindingConfiguration" maxReceivedMessageSize="2147483647" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" maxBufferPoolSize="2147483647">
      <!--<security mode="Transport">
        --><!--<transport clientCredentialType="None" proxyCredentialType="None"></transport>--><!--
      </security>-->
    </binding>
  </webHttpBinding>
</bindings>
<services>
  <service name="WCFServices.UserMgmtService" behaviorConfiguration="MyServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:30158/Services/" />
      </baseAddresses>
    </host>
    <endpoint address="WCFServices.UserMgmtService" behaviorConfiguration="RestBehavior" binding="webHttpBinding" bindingConfiguration="RestBindingConfiguration" contract="WCFServices.IUserMgmtService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="RestBehavior">
      <webHttp />
    </behavior>
    <behavior name="jsonBehavior">
      <webHttp />
      <crossOriginResourceSharingBehavior />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<protocolMapping>
  <add binding="basicHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

下面是客户端中的调用代码

RequestUser requestUser = new RequestUser();
requestUser.UserKey = user.UserKey;
requestUser.FirstName = user.FirstName;
requestUser.LastName = user.LastName;
requestUser.EmailAddress = user.EmailAddress;
requestUser.UserType = user.UserType;

string url = "http://localhost:30158/Services/UserMgmtService.svc/";
string requestMethod = "AddUsers";

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(url + requestMethod));
req.ContentType = "application/json";
req.Method = "POST";    //GET, POST etc

var contentBytes = JSONHelper.SerializeToBytes<RequestUser>(requestUser);
using (Stream dataStream = req.GetRequestStream())
{
    // Write the data to the request stream.
    dataStream.Write(contentBytes, 0, contentBytes.Length);
}

HttpWebResponse webResponse = (HttpWebResponse)req.GetResponse();

//Set the status code            
string resStatus = string.Empty;
using (StreamReader responseStreamReader = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8, true))
{
    string content = responseStreamReader.ReadToEnd();
    response = JSONHelper.Deserialize<ResponseUser>(content);
}

下面是 RequestUser 的代码

[DataContract(Namespace = "http://localhost:30158/Services/RequestUser/")]

 public class RequestUser
 {
    [DataMember(Order = 1)]
    public long? UserKey { get; set; }


    [DataMember(Order = 2)]
    public string FirstName { get; set; }


    [DataMember(Order = 3)]
    public string LastName { get; set; }


    [DataMember(Order = 4)]
    public string EmailAddress { get; set; }


    [DataMember(Order = 5)]
    public string UserType { get; set; }
}

下面是 ResponseUser 的代码

[DataContract(Namespace = "http://localhost:30158/Services/ResponseUser/")]
public class ResponseUser
{
    [DataMember]
    public string Status { get; set; }

    [DataMember]
    public bool Success { get; set; }
}

以下是 WSDL 文件内容

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- 
wssecurity-utility-1.0.xsd" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
xmlns:tns="http://localhost:30158/Services/" 
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" 
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" 
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" 
xmlns:i0="http://tempuri.org/" 
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
xmlns:wsa10="http://www.w3.org/2005/08/addressing" 
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
name="UserMgmtService" targetNamespace="http://localhost:30158/Services/">
<wsdl:import namespace="http://tempuri.org/" 
location="http://localhost:30158/Services/UserMgmtService.svc? 
wsdl=wsdl0"/>
<wsdl:types/>
<wsdl:service name="UserMgmtService"/>
</wsdl:definitions>

当我在客户端中运行代码时,它会抛出HttpWebResponse webResponse = (HttpWebResponse)req.GetResponse();如下错误

An exception of type 'System.Net.WebException' occurred in Service.dll but was not handled in user code

Additional information: The remote server returned an error: (404) Not Found.

标签: c#wcf

解决方案


推荐阅读