#wcf
#wcf
Вопрос:
Я пытаюсь загрузить большие файлы в службу WCF, размещенную в IIS.
Я использую Restful и потоковый метод.
Но я не могу загружать файлы размером более 64 КБ.
Я много перепробовал, изменив все связанные с размером элементы в web.config
файле, но проблему устранить не удалось.
Вот мой код и конфигурация, пожалуйста, дайте мне знать, если кто-нибудь обнаружит какие-либо проблемы в коде и как я могу исправить.
Контракт на эксплуатацию
[OperationContract]
[WebInvoke(UriTemplate = "/UploadImage/{filename}")]
bool UploadImage(string filename, Stream image);
Реализация операционного контракта
public bool UploadImage(string filename, Stream image)
{
try
{
string strFileName = ConfigurationManager.AppSettings["UploadDrectory"].ToString() filename;
FileStream fileStream = null;
using (fileStream = new FileStream(strFileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 1024;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = image.Read(buffer, 0, bufferLen)) > 0)
{
fileStream.Write(buffer, 0, count);
}
fileStream.Close();
image.Close();
}
return true;
}
catch (Exception ex)
{
return false;
}
}
web.config
<system.serviceModel>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<endpoint address="http://localhost/WCFService1" behaviorConfiguration="web"
binding="webHttpBinding" bindingConfiguration="webBinding"
contract="IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding"
transferMode="Streamed"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
openTimeout="00:25:00" closeTimeout="00:25:00" sendTimeout="00:25:00"
receiveTimeout="00:25:00" >
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
и
<httpRuntime maxRequestLength="2097151"/>
Служба размещена в размещенном в IIS
Код на стороне клиента (консольное приложение)
private static void UploadImage()
{
string filePath = @"F:SharathTestImageTextFilesSampleText2.txt";
string filename = Path.GetFileName(filePath);
string url = "http://localhost/WCFService1/Service.svc/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url "UploadImage/" filename);
request.Accept = "text/xml";
request.Method = "POST";
request.ContentType = "txt/plain";
FileStream fst = File.Open(filePath, FileMode.Open);
long imgLn = fst.Length;
fst.Close();
request.ContentLength = imgLn;
using (Stream fileStream = File.OpenRead(filePath))
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0)
{
requestStream.Write(buffer, 0, byteCount);
}
}
string resu<
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
Console.WriteLine(result);
}
С таким большим объемом кода я могу загрузить файл размером 64 КБ, но когда я пытаюсь загрузить файл размером более 64 КБ, я получаю ошибку типа,
The remote server returned an error: (400) Bad Request
я сделал то, что вы сказали, но все равно я получаю ту же проблему, вот как сейчас выглядит моя конфигурация, не могли бы вы, пожалуйста, сказать мне, чего здесь все еще не хватает
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<endpoint address="http://localhost/WCFService1" behaviorConfiguration="web"
binding="webHttpBinding" bindingConfiguration="webBinding"
contract="IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding transferMode="Streamed"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
openTimeout="00:25:00" closeTimeout="00:25:00" sendTimeout="00:25:00" receiveTimeout="00:25:00"
name="webBinding">
<readerQuotas maxDepth="64"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
Комментарии:
1. Каково имя и пространство имен вашего класса?
2. какое-либо окончательное решение с полным примером исходного кода работает над этим?
Ответ №1:
Проблема с передачей больших данных в wcf:
У меня есть служба wcf 4.0, размещенная на IIS 7, Windows 2008 server. Когда я вызываю свою службу с небольшими данными, скажем, 4K или 5K байт, тогда запрос обрабатывается легко, но при попытке загрузить большой размер это выдало мне следующие ошибки
- Неверный запрос 400
- Файл не найден 404 13, как видно из журналов IIS 7
- Отсутствует конечная точка, прослушивающая сервис «myservice url»
Во всех случаях я смог передать небольшой запрос данных с помощью моего клиентского приложения на сервер, но для сообщения большого размера. Ошибка запроса.
Я перепробовал все доступные методы для решения этой проблемы, но у меня ничего не получилось.
Неделю ломал голову и читал все статьи и блоги, наконец, я понял следующее
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="myBinding" closeTimeout="00:10:00" maxBufferPoolSize="250000000" maxReceivedMessageSize="250000000" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" messageEncoding="Text">
<readerQuotas maxDepth="4500000" maxStringContentLength="4500000" maxBytesPerRead="40960000" maxNameTableCharCount="250000000" maxArrayLength="4500000"/>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
<system.web>
<httpRuntime executionTimeout="4800" maxRequestLength="500000000"/>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="500000000"></requestLimits>
</requestFiltering>
</security>
</system.webServer>
<!-- other useful setting -->
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Поэтому я думаю, что это может помочь кому-то в ближайшие дни….
Комментарии:
1. Осталась только одна информация: имя сервиса должно быть в форме «YourNamespace. Classname» файла .svc. Благодарим вас за публикацию этой информации.
2. не знаю, как вас отблагодарить .. у меня тоже была такая же проблема.. теперь это работает как заклинание
3. Являются системой. веб и системные.настройки веб-сервера также применимы к приложению Windows Forms, кто-нибудь? Я также выполняю передачу больших файлов, но использую приложение Windows Forms
4. какое-либо окончательное решение с полным примером исходного кода работает над этим?
5. Спасибо за этот ответ. Но, может быть, просто для того, чтобы немного прояснить, какой из параметров необходимо увеличить. Для нас нам нужно было только увеличить параметр MaxStringContentLength, чтобы все прошло гладко.
Ответ №2:
Судя по указанному вами размеру, это ошибка из-за превышения предела на уровне привязки, т. Е. значений readerQuota. Вы можете подтвердить, вызван ли отказ сервера превышением лимита на уровне привязки, захватив трассировки WCF. Мы не можем видеть конфигурацию, которую вы опубликовали таким образом, предоставляя наше лучшее предположение, основанное на информации, которая видна.
Я бы записал трассировки WCF на подробном уровне, чтобы устранить проблему.
Кстати, вы пробовали увеличить maxRequestLength? http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.maxrequestlength.aspx
HTH, Амит Бхатия
Ответ №3:
то, что исправленный размер сообщения 404 слишком большая проблема для меня, было частью примера WaseemM:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="500000000"></requestLimits>
</requestFiltering>
</security>
Ответ №4:
Смотрите…все мы, кто сталкивается с проблемой загрузки 64 КБ, упускаем из виду самый основной момент. Мы устанавливаем высокие значения для maxAllowedContentLength, maxReceivedMessageSize…бла-бла-бла, но все равно ничего не работает :). Мы все упускаем самый основной момент (… ну, по крайней мере, я был), независимо от того, какую конфигурацию привязки мы установили, мы где-нибудь упоминаем, что наша КОНЕЧНАЯ ТОЧКА ДОЛЖНА СЛЕДОВАТЬ КОНФИГУРАЦИИ ПРИВЯЗКИ ????…неизвестно где…Таким образом, в принципе, мы должны сообщить КОНЕЧНОЙ ТОЧКЕ, что она должна следовать нашей КОНФИГУРАЦИИ ПРИВЯЗКИ.
<endpoint address=""
binding="webHttpBinding"
behaviorConfiguration="Your behaviour config name"
bindingConfiguration="YOUR BINDING CONFIG NAME"
contract="Your contract service" />
Ответ №5:
Если вашей задачей является передача больших данных, вам следует использовать MTOM. Просто найдите «MTOM WCF».
Комментарии:
1. какое-либо окончательное решение с полным примером исходного кода работает над этим? Я получаю ошибки при использовании MTOM и big file
Ответ №6:
Чандрачур прав, что бы вы ни указали в своем <binding/>
или <readerQuotas/>
, вам нужно добавить "bindingConfiguration="my binding config name"
в свой <endpoint/>
. В противном случае это не сработает, даже если ваша конфигурация привязки верна. вам нужно убедиться, что ваши конфигурации применены к вашей конечной точке. для этого вам нужно "bindingConfiguration"
правильно установить.