@Tequilla

Как передать несколько параметров в WCF REST сервис, используя PUT запрос?

Всем привет!
Пытаюсь передать несколько параметров, используя PUT запрос, но при попытке вызвать сервис через Fiddler
постоянно получаю 400 ошибку (Bad Request).

Метод, который я вызываю имеет следующее определение:
public interface IRestService
    {
        [WebInvoke(Method = "PUT", UriTemplate = "PutData", 
            RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json, 
            BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        [OperationContract]
        bool PutData(User user, string userId);
    }


    [DataContract]
    public class User
    {
        [DataMember]
        public string firstname { get; set; }

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


Запускаю сервис со следующими параметрами:
url: http://localhost:28387/RestService.svc/PutData

body: {"user":{"firstname":"John", "lastname":"Kennex"}, "userId":"15"}


На всякий случай привожу описание конфигурации сервиса:
<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="SimpleRestService.SoapService" behaviorConfiguration="Default">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:28387/SoapService.svc"/>
          </baseAddresses>
        </host>
        <endpoint binding="basicHttpBinding" contract="SimpleRestService.ISoapService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
      </service>
      <service name="SimpleRestService.RestService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:28387/RestService.svc"/>
          </baseAddresses>
        </host>
        <endpoint contract="SimpleRestService.IRestService" binding="webHttpBinding" behaviorConfiguration="restful">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="restful">
          <webHttp helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="Default">
          <!--Чтобы избежать раскрытия метаданных, до развертывания задайте следующему параметру значение "false". -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- Чтобы при сбое получать подробные сведения об исключении для целей отладки, установите для нижеприведенного параметра значение true.  Перед развертыванием установите значение false, чтобы избежать раскрытия информации об исключении -->
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="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>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>
  • Вопрос задан
  • 5296 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Voucik
[WebInvoke(Method = "PUT", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[OperationContract]
bool PutData(User user, string userId);

Вот полностью рабочий пример (я создал для теста, проверил всё работает)

Служба:
Contract
namespace WcfServiceHost
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract()]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        List<Data.Test> GetTestData();

        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        void AddTestData(Data.Test value, String additional);
    }
}


SVC
namespace WcfServiceHost
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1 : IService1
    {
        private static List<Data.Test> _data = new List<Data.Test>() { new Data.Test() { ID = 0, Name = "a" }, new Data.Test() { ID = 1, Name = "B" } };
        public List<Data.Test> GetTestData()
        {
            return _data;
        }

        public void AddTestData(Data.Test value, String additional)
        {
            value.Name = value.Name + additional;
            _data.Add(value);
        }
    }
}

Данные
namespace WcfServiceHost.Data
{
    [DataContract]
    public class Test
    {
        [DataMember(Name = "id")]
        public int ID { get; set; }
        [DataMember(Name = "name")]
        public string Name { get; set; }
    }
}


Global.asax
namespace WcfServiceHost
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {

        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            
            EnableCrossDomainAjaxCall();
        }

        private void EnableCrossDomainAjaxCall()
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }

        


    }
}


Клиетн:
ViewBag.Title = "title";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
    //Get Data
    function GETData() {
        $.ajax({
            type: 'GET',
            url: "http://localhost:10468/Service1.svc/GetTestData",
            async: false,
            cache: false,
            dataType: 'json',
            crossDomain: true,
            success: function (data) {
                ShowData(data);
            },
            error: function (e) {
                console.log(e.message);
            }
        });
    };

    function ShowData(data) {
        RemoveData();
        var str = "<div id='DataSelf'>";
        data.forEach(function (item) {
            str += "<div style=\"float: left; margin-right: 20px;\">" + item.id + "</div><div>" + item.name + "</div>";
        });
        str += "</div>";
        $("#ShowData").append(str);
    }

    function RemoveData() {
        $("#DataSelf").remove();
    }

    //Send Data
    function SendData() {
        var Json = {'value': { 'id': $("#id").val(), 'name': $("#name").val() },'additional':'ffff'};
        $.ajax({
            url: "http://localhost:10468/Service1.svc/AddTestData",
            data: JSON.stringify(Json),
            type: "POST",
            processData: false,
            async: false,
            contentType: "application/json",
            dataType: "text",
            success:
                    function (response) {

                    },
            error: function (er) {

            }
        });
    }
</script>
<div id='ShowData'></div>
<input type="button" onclick="GETData()" value="GetTestData"/>
<br/>
<input id="id" name="id" type="text" width="100" height="30"/>
<input id="name" name="name" type="text" width="100" height="30"/>
<input type="button" onclick="SendData()" value="AddTestData"/>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы