Добрый день, коллеги!
Есть задача: сделать веб-сервис, принимающий на вход сложное json-тело.
В ходе реализации столкнулась с двумя проблемами:
1. Не нашла, как описать прием сложного параметра в сервисе, кроме робкого указания на модификаторы [DataContract] и [DataMember]. Подскажите, где-нибудь есть информация об этом?
2. При вызове из Postman сервис возвращает ответ "403 - Вы не имеете разрешения на просмотр этого каталога пли страницы." (скриншот ниже). Нужно ли где-то отдельно прописывать права на доступ к сервисам?
Скриншот ошибки:
![]()
Листинг пример json тела запроса.
{
"scoring_events" : [
{
"type" : "pageview",
"page_url" : "https://bpmonline.com/",
"datetime_utc" : "2018-08-08 12:00:12",
"responsible_user" : {
"name" : "Иван Иванов",
"email" : "i.ivanov@yandex.ru",
"type" : "user"
},
"partner" : {
"name" : "ООО Ромашка"
"bpm_id" : "783967ef-c629-4f1d-8cd4-3b3dba955ffc",
"contact_email" : "n.ivanova@yandex.ru"
}
},
...
{
...
}
]
}
листинг сервиса:
namespace Terrasoft.Configuration.WScoringService
{
using System;
<...>
#region Class: WScoringService
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class WScoringService : BaseService
{
private WScoringServiceResponse wScoringServiceResponse;
#region Methods: Public
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
public string AddScoringEvent(List scoring_events)
{
if (scoring_events.IsEmpty()) wScoringServiceResponse = new WScoringServiceResponse(true, "empty");
else wScoringServiceResponse = new WScoringServiceResponse(true, scoring_events[0].ToString());
return wScoringServiceResponse.ToJsonString();
}
#endregion
#region DataContract
[DataContract]
public class ScoringEvent
{
[DataMember]
public string type;
[DataMember]
public string page_url;
[DataMember]
public string datetime_utc;
[DataMember]
public ResponsibleUser responsible_user;
[DataMember]
public Partner partner;
public override string ToString()
{
string result;
result = "type=" + type + ";";
result += "page_url=" + page_url + ";";
result += "datetime_utc=" + datetime_utc + ";";
result += "responsible_user_name=" + responsible_user.name + ";";
result += "partner_name=" + partner.name + ";\n";
return result;
}
}
[DataContract]
public struct ResponsibleUser
{
[DataMember]
public string name;
[DataMember]
public string email;
[DataMember]
public string type;
}
[DataContract]
public struct Partner
{
[DataMember]
public string name;
[DataMember]
public string bpm_id;
[DataMember]
public string contact_email;
}
#endregion
}
#endregion
#region Class: WScoringServiceResponse
public class WScoringServiceResponse
{
private bool success;
private string message;
public WScoringServiceResponse() { }
public WScoringServiceResponse(bool success, string message = null)
{
this.success = success;
this.message = message;
}
public string ToJsonString()
{
string result = "{\"status\":\"";
if (success) result += "ok\",";
else result += "error\",";
result += "\"message\":\"" + message+ "\"}";
return result;
}
}
#endregion
}
Нравится
Примеры сервисов можно найти в конфигурации. Например, [DataContract] и [DataMember] применяют в CurrentUserService так:
[DataContract]
public class UserCultureInfo
{
[DataMember(Name = "timeZoneCode")]
public string TimeZoneCode { get; set; }
[DataMember(Name = "timeZoneName")]
public string TimeZoneName { get; set; }
[DataMember(Name = "timeZoneId")]
public Guid TimeZoneId { get; set; }
[DataMember(Name = "cultureId")]
public Guid CultureId { get; set; }
[DataMember(Name = "cultureName")]
public string CultureName { get; set; }
[DataMember(Name = "cultureLanguage")]
public string CultureLanguage { get; set; }
[DataMember(Name = "dateTimeFormatId")]
public Guid DateTimeFormatId { get; set; }
[DataMember(Name = "dateTimeFormatName")]
public string DateTimeFormatName { get; set; }
}По поводу 403, такое бывает, если при отправке запроса к сервису не передать CSRF-токен.
И вот я пишу другой подобный сервис, привожу пример, который у меня заработал
Данные, которые отправляются в сервис:
{
"WCases": [{
"message": "webinar test",
"user_crm_id": "CFAC23D8-8EEA-4EB6-A257-0001538F0723"
}, {
"message": "webinar test 2",
"user_crm_id": "CFAC23D8-8EEA-4EB6-A257-0001538F0723"
}
]
}
Код сервиса:
namespace Terrasoft.Configuration.WCaseService
{
using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using Terrasoft.Core;
using Terrasoft.Web.Common;
using Terrasoft.Configuration.Slack;
using System.Runtime.Serialization;
#region WCaseService
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class WCaseService : BaseService
{
#region init
private SystemUserConnection _systemUserConnection;
private SystemUserConnection SystemUserConnection
{
get
{
return _systemUserConnection ?? (_systemUserConnection = (SystemUserConnection)AppConnection.SystemUserConnection);
}
}
#endregion
#region main: endPoints
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
public string ImportData(List<WCaseTemplate> WCases)
{
string result = "";
if (WCases != null)
{
foreach (WCaseTemplate wCasein WCases)
{
result += "message: " + wCase.UserMessage + "\nuser_crm_id: " + wCase.UsrLoginId.ToString() + "\n";
}
}
else result = "NULL";
return result;
}
#endregion
}
#endregion
[DataContract]
public class WCaseTemplate
{
[DataMember(Name = "message")]
public string UserMessage { get; set; }
[DataMember(Name = "user_crm_id")]
public Guid UsrLoginId { get; set; }
}
}