【问题标题】:WCF post method implementationWCF post方法实现
【发布时间】:2012-03-21 10:25:30
【问题描述】:

我有一个 WCF 服务,它连接到从移动应用程序调用的 sql server 数据库。我有以下方法可以帮助创建预订。

public void CreateBooking(Booking booking)
    {
        Booking newbooking = new Booking();
        sql = new SqlConnection("Data Source=comp;Initial Catalog=BookingDB;Integrated Security=True");
        sql.Open();

        string command =
            ("INSERT INTO Bookings( BookingName, BookingStart, BookingEnd, RoomID ) " +
             "VALUES ("
                + "'" + booking.BookingName + "'" + ", "   
                + "'" + booking.BookingStart  + "'" + ", " 
                + "'" + booking.BookingEnd + "'" + ", "
                        + booking.RoomID + ")");

        SqlCommand cmd = new SqlCommand(command, sql);                
        cmd.ExecuteNonQuery();            
    }

    public void Close()
    {
        sql.Close();
    }

标记:

<%@ ServiceHost Language="C#" Debug="true" Service="BookingServices.BookingService" CodeBehind="BookingService.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

配置文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <!--<authentication mode="None"/>-->
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      </assemblies>
    </compilation>
  </system.web>
  <system.serviceModel>
<services>
  <service name="RoomBookingServices.RoomBookingService" behaviorConfiguration="RoomBookingServiceBehaviour">
    <endpoint address="http://192.168.0.4:6321/RoomBookingServices/RoomBookingService.svc" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="RoomBookingServices.IRoomBookingService" behaviorConfiguration="webHttpBehavior">
      <identity>
        <servicePrincipalName value=""/>
      </identity>
    </endpoint>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="RoomBookingServiceBehaviour">
      <!-- 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="true" />
       </behavior>
     </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
         <webHttp />
    </behavior>
  </endpointBehaviors>
</behaviors>
<bindings>
  <webHttpBinding>
    <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"></binding>
  </webHttpBinding>
</bindings>
<!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />-->
<!--<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />-->
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
  <connectionStrings>
    <add name="RoomBookingDatabaseEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=HAL;initial catalog=RoomBookingDatabase;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    <add name="RoomBookingDatabaseEntities1" connectionString="metadata=res://*/RoomBookingDB.csdl|res://*/RoomBookingDB.ssdl|res://*/RoomBookingDB.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=HAL;initial catalog=RoomBookingDatabase;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>

界面:

[OperationContract(Name="postmethod")]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, UriTemplate = "postmethod/new")]

    void CreateBooking(Booking booking); 
}

预订舱位:

[DataContract]
public class Booking
{
    [DataMember]
    public int BookingID { get; set; }

    [DataMember]
    public string BookingName { get; set; }

    [DataMember]
    public DateTime BookingStart { get; set; }

    [DataMember]
    public DateTime BookingEnd { get; set; }

    [DataMember]
    public int RoomID { get; set; }

}

但是,每当我调用该方法时,都会收到 405 错误。我的问题是,上面的方法是导致错误还是在事物的连接端?谢谢。

【问题讨论】:

  • 你能不能把你的配置文件和服务的接口贴出来。你的服务是 RESTful 还是 SOAP 服务
  • 嗨 Rajesh,我已将配置和界面上传到主要问题中。谢谢!
  • 如果这不是问题,您能否也为您的 Booking 课程发布骨架
  • 顺便说一句,您确实需要考虑参数化您的 SQL 查询 - 否则您将面临允许 SQL 注入攻击的风险。这里的简单示例:dotnetperls.com/sqlparameter
  • 更新预订等级和 svc 标记。

标签: c# sql ajax wcf post


【解决方案1】:

我已经尝试了上述方案,并且只进行了一些更改,如下所示:

[OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "postmethod/new")]
        Booking CreateBooking(Booking booking); 

您可以删除 WrappedRequest 设置,因为您只有 1 个参数。

当我使用以下请求从 Fidder 执行 POST 时,我得到了成功的响应:

POST http://localhost/SampleApp/Service1.svc/postmethod/new HTTP/1.1
Content-Type: application/json
Host: localhost
Content-Length: 144
Expect: 100-continue

{"BookingEnd":"\/Date(1332420656202+0000)\/","BookingID":1,"BookingName":"client sent","BookingStart":"\/Date(1332334256202+0000)\/","RoomID":2}

您也可以删除 OperationContract 中的 name 属性。如果您在 IIS 中托管,则地址可以为空,因为该地址是由 IIS 分配的。

【讨论】:

    【解决方案2】:

    当您在 IIS 中托管 WCF 服务时,address 属性会从位置推断为 IIS 中托管的 .svc 文件,因此它应该为空或相对地址:

    <service name="RoomBookingServices.RoomBookingService" behaviorConfiguration="RoomBookingServiceBehaviour">
        <endpoint 
            address="" 
            binding="webHttpBinding" 
            bindingConfiguration="webHttpBindingWithJsonP"
            contract="RoomBookingServices.IRoomBookingService" 
            behaviorConfiguration="webHttpBehavior">
        </endpoint>
    </service>
    

    基本地址将由 IIS 和您托管应用程序的站点提供。因此它将指向托管在 IIS 中的 RoomBookingService.svc 文件的位置。

    当我查看以下代码时:

    string command =
            ("INSERT INTO Bookings( BookingName, BookingStart, BookingEnd, RoomID ) " +
             "VALUES ("
                + "'" + booking.BookingName + "'" + ", "   
                + "'" + booking.BookingStart  + "'" + ", " 
                + "'" + booking.BookingEnd + "'" + ", "
                        + booking.RoomID + ")");
    
    SqlCommand cmd = new SqlCommand(command, sql);
    

    我的眼睛开始流血。你绝对不应该写任何这样的代码。处理 SQL 时始终使用参数化查询。您的代码容易受到SQL injection 的攻击。

    所以:

    public void CreateBooking(Booking booking)
    {
        using (var conn = new SqlConnection("Data Source=comp;Initial Catalog=BookingDB;Integrated Security=True"))
        using (var cmd = conn.CreateCommand())
        {
            conn.Open();
            cmd.CommandText = 
            @"INSERT INTO 
              Bookings( BookingName, BookingStart, BookingEnd, RoomID ) 
              VALUES ( @BookingName, @BookingStart, @BookingEnd, @RoomID )";
    
            cmd.Parameters.AddWithValue("@BookingName", booking.BookingName);
            cmd.Parameters.AddWithValue("@BookingStart", booking.BookingStart);
            cmd.Parameters.AddWithValue("@BookingEnd", booking.BookingEnd);
            cmd.Parameters.AddWithValue("@RoomID", booking.RoomID);
            cmd.ExecuteNonQuery();
        }
    }
    

    现在你可以调用这个服务了。例如使用 jQuery AJAX:

    $.ajax({
        url: '/RoomBookingService.svc/postmethod/new',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({ 
            booking: {
                BookingID: 1,
                BookingName: 'bn',
                BookingStart: '/Date(1232739449000+0000)/',
                BookingEnd: '/Date(1232776449000+0000)/',
                RoomID: 2
            }
        }),
        success: function (result) {
    
        }
    });
    

    【讨论】:

    • 嗨,达林,感谢您的提示。这对我来说是全新的,所以了解这些东西很好!谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 2018-07-21
    相关资源
    最近更新 更多