C# WCF post方法实现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9802644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 08:56:13  来源:igfitidea点击:

WCF post method implementation

c#sqlajaxwcfpost

提问by moikey

I have a WCF service which is connected to an sql server database which is called from a mobile application. I have the following method which helps create bookings.

我有一个 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();
    }

Markup:

标记:

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

Config File:

配置文件:

<?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>

Interface:

界面:

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

    void CreateBooking(Booking booking); 
}

Booking class:

预订舱位:

[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; }

}

However, whenever I call the method I am getting a 405 error. My question is, is the method above causing the error or is it something in the connection end of things? Thanks.

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

采纳答案by Rajesh

I have tried the above scenario and with few changes i got it working as shown below:

我已经尝试了上面的场景,经过很少的改动,我得到了它的工作,如下所示:

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

You can remove the WrappedRequest setting as you just have only 1 param.

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

When i perform a POST from Fidder with the below request i get a successful response:

当我使用以下请求从 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}

You can remove the name attribute in the OperationContract as well. If you are hosting in IIS then the address can be empty as the address is assigned by IIS.

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

回答by Darin Dimitrov

When you are hosting a WCF service in IIS the addressattribute is inferred from the location to the .svcfile as hosted in IIS so it should either empty or a relative address:

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

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

The base address will be provided by IIS and the site where you are hosting your application under. So it will point to the location of the RoomBookingService.svcfile as hosted in IIS.

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

Also when I look at the following code:

此外,当我查看以下代码时:

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

SqlCommand cmd = new SqlCommand(command, sql);

my eyes start to bleed. You should absolutely never write any code like that. Always use parametrized queries when dealing with SQL. Your code is vulnerable to SQL injection.

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

So:

所以:

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();
    }
}

And now you could invoke this service. For example using jQuery AJAX:

现在您可以调用此服务。例如使用 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) {

    }
});