В Dynamics CRM Online у нас есть сборка Custom Solution, которая хранит большие файлы в виде блобов в хранилище BLOB-объектов Azure.Когда я пытаюсь загрузить файл размером 40 МБ, я получаю сообщение об ошибке тайм-аута.Журнал ошибок ниже.
Я прочитал, что
Загрузка блочного большого двоичного объекта размером не более 256 МБ (64 МБ для запросов с использованием версий REST до 2016-05-31) может быть одной операцией записи с использованием Put Blob.Однако загрузка большого двоичного объекта требует дополнительных усилий.Разбейте его на блоки максимум по 4 или 100 МБ в зависимости от используемой вами версии API REST.
Редактировать: Я провел еще несколько мозговых штурмов с некоторыми Трейл и ошибками.Что я обнаружил, так это то, что из CRM с помощью (c #) плагина я мог легко отправить файл размером до 80 МБ, и это хорошая сумма.В любом случае CRM имеет ограничение на размер файла до 128 МБ.
Что касается моей конкретной проблемы, я также обнаружил, что основная проблема вызвана HTML-страницей, которая используется как перетаскивание для добавления файла в CRM, а затемв свою очередь, к BLOB-объекту Azure.
Резюме: RESTAPI для Azure - это не проблема, а скорее лежит на стороне Dynamics CRM.Мы должны уважать время ожидания эффективным способом извлечения байтов из файла и загрузки его в Azure.
Как уже упоминалось выше, файл размером 256 МБ не должен разбивать его, но все равно я получаю время ожидания.Вот метод, который, по моему мнению, является причиной проблемы.
public HttpWebRequest CreateRESTRequest(string method, string resource, byte[] requestBody, SortedList<string, string> headers = null,
string ifMatch = "", string md5 = "")
{
DateTime now = DateTime.UtcNow;
string uri = Endpoint + resource;
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = method;
request.ContentLength = 0;
request.Headers.Add("x-ms-date", now.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2017-04-17");
if (IsTableStorage)
{
request.ContentType = "application/atom+xml";
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
}
if (headers != null)
{
foreach (KeyValuePair<string, string> header in headers)
{
// This control requires that we set the ContentType through its property.
if (header.Key.Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase))
{
request.ContentType = header.Value;
}
else
{
request.Headers.Add(header.Key, header.Value);
}
}
}
if (requestBody?.Length > 0)
{
request.Headers.Add("Accept-Charset", "UTF-8");
request.ContentLength = requestBody.Length;
}
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, ifMatch, md5));
if (requestBody?.Length > 0)
{
request.GetRequestStream().Write(requestBody, 0, requestBody.Length);
request.GetRequestStream().Close();
}
return request;
}
Uploading Test File.pptx failed Reason: "The plug-in execution failed because no Sandbox Hosts are currently available. Please check that you have a Sandbox server configured and that it is running.\r\nSystem.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:03:30'. ---> System.IO.IOException: The write operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:03:30'. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine\r\n at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)\r\n at System.ServiceModel.Channels.SocketConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)\r\n --- End of inner exception stack trace ---\r\n at System.ServiceModel.Channels.SocketConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)\r\n at System.ServiceModel.Channels.BufferedConnection.WriteNow(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, BufferManager bufferManager)\r\n at System.ServiceModel.Channels.BufferedConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)\r\n at System.ServiceModel.Channels.ConnectionStream.Write(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.Net.Security.NegotiateStream.StartWriting(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.NegotiateStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n --- End of inner exception stack trace ---\r\n at System.Net.Security.NegotiateStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.NegotiateStream.Write(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)\r\n --- End of inner exception stack trace ---\r\n\r\nServer stack trace: \r\n at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)\r\n at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout, BufferManager bufferManager)\r\n at System.ServiceModel.Channels.FramingDuplexSessionChannel.OnSendCore(Message message, TimeSpan timeout)\r\n at System.ServiceModel.Channels.TransportDuplexSessionChannel.OnSend(Message message, TimeSpan timeout)\r\n at System.ServiceModel.Channels.OutputChannel.Send(Message message, TimeSpan timeout)\r\n at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout)\r\n at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)\r\n at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)\r\n at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)\r\n\r\nException rethrown at [0]: \r\n at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)\r\n at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)\r\n at Microsoft.Crm.Sandbox.ISandboxHost.ExecuteAndReturnTraceInfo(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, String assemblyContents, Boolean returnTraceInfo)\r\n at Microsoft.Crm.Sandbox.SandboxPlugin.Execute(SandboxClient client, SandboxCallTracker callTracker, IExecutionContext requestContext, String assemblyContents, Boolean returnTraceInfo)\r\n at Microsoft.Crm.Sandbox.SandboxCodeUnit.ExecuteInternal(SandboxClient client, IExecutionContext context, SandboxTraceContext sandboxTraceContext, SandboxCallTracker callTracker, Guid parentExecutionId, String assemblyContents, Boolean& isSafeToRetry, Boolean& executeDone)\r\n at Microsoft.Crm.Sandbox.SandboxCodeUnit.<>c__DisplayClass24_0.<Execute>b__0(): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #D2641555"