#c# #rest #wcf
Вопрос:
Недавно я разработал службу WCF rest, единственной целью которой является обработка запросов Get и возврат данных.
Я (в основном) успешно сделал это, однако я сталкиваюсь с проблемой, когда хочу отправить в запросе более 200-300 символов. Всякий раз, когда я пытаюсь это сделать, я в конечном итоге получаю сообщение об ошибке 400 на веб-странице. Сначала я думал, что столкнулся с каким-то ограничением персонажа, но после прочтения многих веб-страниц и других вопросов я в тупике относительно того, что действительно терпит неудачу.
Я пытался изменить привязки, такие как maxReceivedMessageSize, MaxStringContentLength, MaxBufferSize и MaxBufferPoolSize, надеясь, что один из них был виновником, но, увы, я ошибся. Я также попытался добавить трассировку, чтобы посмотреть, смогу ли я прочитать какие-либо ошибки в журнале, но когда я делаю длинный запрос, в журнал ничего не добавляется. В настоящее время я не могу использовать браузер, отличный от edge, поэтому я создал приложение, которое использует HttpClient для связи с моим сервером, и я все еще получаю сообщение об ошибке 400, когда делаю «длинный» запрос.
Примером запроса, который отлично работает, является http://IP:PORT/POINTINFO/DBNAME/{"User":"testuser","Pc":"testpc","Data":["Point01","Point02"]}
Примером запроса, который приведет к ошибке 400, является http://IP:PORT/POINTINFO/DBNAME/{"User":"testuser","Pc":"testpc","Data":["U1R0011AS","U1R0012AS","U1R0012BS","U1R0041AS","U1R0041BS","U1R0041CS","U1R0044AS","U1R0044BS","U1R0046AS","U1R0046BS","U1R0046CS","U1R0046DS","U1R11A-AV","U1R12A-AV","U1R12B-AV","U1R41A-AV","U1R41B-AV","U1R41C-AV","U1R44A-AV","U1R44B-AV","U1R46A-AV","U1R46B-AV","U1R46C-AV","U1R46D-AV","U1R46E-AV","U1RCSCOLDEST","U1RCSPRESS","U1RXPCNTBE"]}
Как вы можете видеть, запрос длинный (по крайней мере, для ввода), но он не должен наносить никаких ограничений. Это также совершенно правильный JSON, так что это не может быть причиной его смерти. Я также попытался установить точку останова в своей функции GetPointList, чтобы проверить, нет ли чего-то неправильного в моем коде, но это даже не вызывается. Это мое единственное знакомство с услугами WCF rest, поэтому я уверен, что совершаю ошибку новичка, но я не вижу, что я делаю неправильно. Любая помощь будет оценена по достоинству.
Вот мой главный:
static void Main(string[] args)
{
WebServiceHost hostWeb = new WebServiceHost(typeof(ConsoleApp1.Service));
ServiceEndpoint ep = hostWeb.AddServiceEndpoint(typeof(ConsoleApp1.IService), new WebHttpBinding(), "");
ServiceDebugBehavior stp = hostWeb.Description.Behaviors.Find<ServiceDebugBehavior>();
stp.HttpHelpPageEnabled = false;
hostWeb.Open();
Console.WriteLine("Service Host started @ " DateTime.Now.ToString());
Console.Read();
}
Это интерфейс, который у меня есть:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "POINTINFO/{database}/{pointlist}")]
[return: MessageParameter(Name = "Data")]
List<PointData> GetPointList(string pointlist, string database);
}
Вот моя конфигурация, которая испорчена предыдущими попытками исправить мою проблему:
<!--tracing for error detection-->
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Information, ActivityTracing">
<listeners>
<add name="log"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:UsersAdministratorDocumentsmessages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<bindings>
<!--<wsHttpBinding>-->
<basicHttpBinding>
<binding name="basicHttp" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="01:00:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<security mode="None">
<!--<transport clientCredentialType="None" />-->
</security>
<readerQuotas maxStringContentLength="2147483647"/>
<!--<reliableSession enabled="true" />-->
</binding>
</basicHttpBinding>
<!--</wsHttpBinding>-->
<webHttpBinding>
<binding name="webHttp" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="01:00:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<security mode="None">
<!--<transport clientCredentialType="None" />-->
</security>
<readerQuotas maxStringContentLength="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="ConsoleApp1.Service">
<endpoint address="rest" binding="webHttpBinding" bindingConfiguration="webHttp" contract="ConsoleApp1.IService" behaviorConfiguration="web"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:12345" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<!-- rest api-->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="300"
maxSizeOfMessageToLog="20000"/>
</diagnostics>
</system.serviceModel>
Комментарии:
1. Вы можете проверить запрос вашего клиента.ContentType и попробовать использовать application/json.
Ответ №1:
Я понял это благодаря этому сайту: https://www.codeproject.com/Questions/847265/WCF-How-to-overcome-urllength-restriction
Оказывается, что ограничение символов по умолчанию для каждого параметра в URL-адресе REST равно 260. Поэтому вам нужно зайти в реестр и изменить значение UrlSegmentMaxLength в HEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesHTTPParameters на REG_DWORD любого значения, которое вам нужно.
Комментарии:
1. С какой стати вы передаете JSON в URL-адресе?