public void Start() { _httpRequestParser = new HttpRequestParser(); _listener = new AsyncSocketListener(_endPoint); _listener.BytesReceived += OnBytesReceived; _listener.Start(); }
public void HttpRequestParser_ParsesMultilineHeaders() { var parser = new HttpRequestParser(); var message = parser.Parse(String.Format(@"M-SEARCH * HTTP/1.1 HOST: {0}:{1} MAN: ""ssdp:discover"" MX: 1 ST: {2} ssdp:all ", SsdpConstants.MulticastLocalAdminAddress, SsdpConstants.MulticastPort, SsdpConstants.UpnpDeviceTypeRootDevice)); Assert.AreEqual(2, message.Headers.GetValues("ST").Count()); }
internal static HeaderParsingCase H(this string requestData, string headerName, string headerValue) { var parser = new HttpRequestParser(); var requestBytes = Encoding.ASCII.GetBytes(requestData); parser.AppendData(requestBytes, requestBytes.Length); var request = parser.Request; Assert.IsFalse(request.ContainsError, "Spurious error detected in error free request"); Assert.IsTrue(request.IsHeadComplete, "Request head parsing hasn't been completed"); Assert.IsTrue(request.IsComplete, "Request parsing hasn't been completed"); var testCase = new HeaderParsingCase(requestData, request); return(testCase.H(headerName, headerValue)); }
public void HttpRequestParser_ParsesHeaderWithQuotedSeparatorValue() { var parser = new HttpRequestParser(); var message = parser.Parse(String.Format(@"M-SEARCH * HTTP/1.1 HOST: {0}:{1} MAN: ""ssdp:discover"" MX: 1 ST: ""test, quoted comma"" ", SsdpConstants.MulticastLocalAdminAddress, SsdpConstants.MulticastPort, SsdpConstants.UpnpDeviceTypeRootDevice)); Assert.AreEqual(1, message.Headers.GetValues("ST").Count()); Assert.AreEqual("test, quoted comma", message.Headers.GetValues("ST").First()); }
public void ParseRequestStream_WithoutDataAndHeaders_CompleteRequest() { var s = new HttpRequestParser(); var streamedRequest = new[] { "GET /api/data HTTP/1.1\r\n", //to force double /r/n on string.Join "" }; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); }
public void TestHttpRequestParser() { var index = 0; foreach (var query in queriesHttp) { var querySrc = queriesSrc[index++]; var parser = new HttpRequestParser(query); Assert.AreEqual(parser.records.Count, 2, querySrc + ": all records are parsed"); var doc = parser.records[0].GetXml(); Assert.IsNotNull(doc, querySrc + ": doc is not null"); Assert.IsNotNull(doc.DocumentElement, querySrc + ": doc is not empty"); Assert.AreEqual("3", parser.records[1].FileData, querySrc + ": hidden is parsed OK"); } }
private async void _worker_DoWork(object sender, DoWorkEventArgs e) { while (true) { await Task.Delay(100); var id = await HttpRequestParser.GetId(APIValues.AcceleroAddress); if (id != _acceleroId) { _acceleroId = Convert.ToInt32(id); var values = await HttpRequestParser.GetListedMeasurement(APIValues.AcceleroAddress); OnValuesUpdated(values); } } }
public void DeviceLocator_SearchAsync_SearchesForAllDevices() { var server = new MockCommsServer(); var deviceLocator = new MockDeviceLocator(server); var t = deviceLocator.SearchAsync(); t.Wait(); Assert.IsTrue(server.SentBroadcasts.Any()); var searchRequestData = server.SentBroadcasts.First(); var parser = new HttpRequestParser(); var searchRequest = parser.Parse(System.Text.UTF8Encoding.UTF8.GetString(searchRequestData.Buffer)); Assert.AreEqual("ssdp:all", GetFirstHeaderValue(searchRequest, "ST")); Assert.AreEqual("3", GetFirstHeaderValue(searchRequest, "MX")); }
public void ParseRequestStream_AllDataAtOnce_CompleteRequest() { var s = new HttpRequestParser(); var streamedRequest = "GET /api/data HTTP/1.1\r\nContent-Length: 4\r\n\r\ndata"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(streamedRequest)); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(HttpMethod.GET, request.Method); Assert.AreEqual(new Uri("/api/data", UriKind.Relative), request.Uri); Assert.AreEqual("data", request.Content); Assert.AreEqual(4, request.ContentLength); Assert.AreEqual("HTTP/1.1", request.HttpVersion); Assert.AreEqual(true, request.IsComplete); }
public void ParseRequestStream_ContentLengthNumberMissing_RequestIncomplete() { var s = new HttpRequestParser(); var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: four", "", "data" }; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(false, request.IsComplete); }
public void DeviceLocator_SearchAsync_UsesSpecifiedSearchTimeLess1Second() { var server = new MockCommsServer(); var deviceLocator = new MockDeviceLocator(server); var searchTime = TimeSpan.FromSeconds(2); var t = deviceLocator.SearchAsync(searchTime); t.Wait(); Assert.IsTrue(server.SentBroadcasts.Any()); var searchRequestData = server.SentBroadcasts.First(); var parser = new HttpRequestParser(); var searchRequest = parser.Parse(System.Text.UTF8Encoding.UTF8.GetString(searchRequestData.Buffer)); Assert.AreEqual("ssdp:all", GetFirstHeaderValue(searchRequest, "ST")); Assert.AreEqual((searchTime.TotalSeconds - 1).ToString(), GetFirstHeaderValue(searchRequest, "MX")); }
public void ParseRequestStream_FragmentedData_ValidRequest() { var s = new HttpRequestParser(); var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes("GET /api/data HTTP/1.1\r\n")); byteStreamParts.Add(Encoding.UTF8.GetBytes("Content-Leng")); byteStreamParts.Add(Encoding.UTF8.GetBytes("th: 4\r\n")); byteStreamParts.Add(Encoding.UTF8.GetBytes("\r\nd")); byteStreamParts.Add(Encoding.UTF8.GetBytes("a")); byteStreamParts.Add(Encoding.UTF8.GetBytes("t")); byteStreamParts.Add(Encoding.UTF8.GetBytes("a")); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual("data", request.Content); }
public void DeviceLocator_SearchAsync_SearchesForSpecifiedTarget() { var server = new MockCommsServer(); var deviceLocator = new MockDeviceLocator(server); var searchTarget = "uuid:" + Guid.NewGuid().ToString(); var t = deviceLocator.SearchAsync(searchTarget); t.Wait(); Assert.IsTrue(server.SentBroadcasts.Any()); var searchRequestData = server.SentBroadcasts.First(); var parser = new HttpRequestParser(); var searchRequest = parser.Parse(System.Text.UTF8Encoding.UTF8.GetString(searchRequestData.Buffer)); Assert.AreEqual(searchTarget, GetFirstHeaderValue(searchRequest, "ST")); Assert.AreEqual("3", GetFirstHeaderValue(searchRequest, "MX")); }
public void ParseRequestStream_DataLengthInSecondPart_ValidRequest() { var s = new HttpRequestParser(); var httpHeadersPart1 = "GET /api/data HTTP/1.1\r\n"; var httpHeadersPart2 = "Content-Length: 4\r\n\r\n"; var content = "data"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(httpHeadersPart1)); byteStreamParts.Add(Encoding.UTF8.GetBytes(httpHeadersPart2)); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(Encoding.UTF8.GetBytes(content)); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual(content, request.Content); }
/// <summary> /// на сервер (на ферму) заливаетсяpro файл pxml, содержащий описание портфеля роботов /// вернуть сообщение, которое нужно отобразить в Popup-e /// </summary> private string ProcessFileUpload(HttpListenerContext context) { var xmlDocs = new Dictionary <string, XmlDocument>(); var hiddenFields = new Dictionary <string, string>(); try { string dataText; using (var reader = new StreamReader(context.Request.InputStream, Encoding.UTF8)) { dataText = reader.ReadToEnd(); } var parser = new HttpRequestParser(dataText); foreach (var ctx in parser.records) { try { var doc = ctx.GetXml(); xmlDocs.Add(ctx.FileName, doc); } catch { hiddenFields.Add(ctx.Name, ctx.FileData); } } } catch (Exception ex) { var strError = "Ошибка в ProcessFileUpload(): " + ex; Logger.Error(strError); RobotFarm.Instance.AppendLogMessage(strError); return("Ошибка обработки документа"); } // прочитать номер счета из hidden-поля accountId... // если номер заполнен - это - портфель роботов if (hiddenFields.ContainsKey("accountId") && xmlDocs.Count == 1) { return(UploadRobotPortfolio(hiddenFields["accountId"], xmlDocs.First().Value)); } return(string.Empty); }
public static async ValueTask ProcessWorkItemAsync(Socket tcpClient) { Interlocked.Increment(ref _usersCount); Interlocked.Increment(ref _busyThreads); var finalized = false; try { var stream = Ssl ? await AuthenticateSsl(tcpClient) : new NetworkStream(tcpClient); var requestData = await HttpLineReader.ReadLineSizedBuffered(stream, 2048); if (requestData == null || requestData.Length < 10) { return; } var request = HttpRequestParser.ParseRequest(requestData); if (request == null) { return; } using var holder = new HttpClientHolder(stream, tcpClient, (HttpInitialRequest)request); finalized = true; await HttpClientProcessor.ProcessClient(holder, (HttpInitialRequest)request); } catch (Exception e) { ILogManager.Log("Http work pool error.", "Client.Work.Pool", LogType.Error, true, true, e); } finally { if (!finalized) { HttpClientHolder.Close(tcpClient); } Interlocked.Decrement(ref _busyThreads); } }
public void ParseRequestStream_TooMuchData_RequestIncomplete() { var s = new HttpRequestParser(); var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4", "", "data" }; var extraData = "plusanotherextrafewbytes"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest) + extraData)); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(false, request.IsComplete); }
public void Parse_HttpRequest() { var parser = new HttpRequestParser(); var buffer = Encoding.UTF8.GetBytes(GetRequestText()); HttpRequest request; Assert.AreEqual(true, parser.TryParse(buffer, buffer.Length, out request), "Parse failed."); Assert.AreEqual(HttpMethod.Delete, request.Method); Assert.AreEqual("/Uri%20/lalalo323/_/-/+/%/@/&/./~/:/#/;/,/*", request.Uri); Assert.AreEqual("Body123{}%!(:<>=", request.Body); Assert.AreEqual(new Version(1, 1), request.HttpVersion); Assert.AreEqual("localhost:2400", request.Headers["Host"]); Assert.AreEqual("keep-alive", request.Headers["Connection"]); Assert.AreEqual("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", request.Headers["Accept"]); Assert.AreEqual("1", request.Headers["Upgrade-Insecure-Requests"]); Assert.AreEqual("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36", request.Headers["User-Agent"]); Assert.AreEqual("gzip, deflate, sdch", request.Headers["Accept-Encoding"]); Assert.AreEqual("de,en-US;q=0.8,en;q=0.6,de-DE;q=0.4", request.Headers["Accept-Language"]); }
public void ParseRequestStream_PartedData_ValidRequest() { var s = new HttpRequestParser(); var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4\r\n", //to force double /r/n on string.Join "" }; var content = "data"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); byteStreamParts.Add(Encoding.UTF8.GetBytes(content)); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual(content, request.Content); }
public void TestParseWithNoBaseUri() { // Arrange var data = new List <string> { null, "TargetSite" }; var header = new Header { Name = "HttpRequest Actual", Depth = 1, From = 1, To = 1, Children = new List <Header> { new Header { Name = "Headers", Depth = 2, From = 1, To = 1, Children = new List <Header> { new Header { Name = "User-Agent", Depth = 3, From = 1, To = 1, }, } }, } }; // Act HttpRequestParser.Parse(header, data, "Name"); }
/// <summary> /// Full constructor. /// </summary> /// <param name="socketFactory">An implementation of the <see cref="ISocketFactory"/> interface that can be used to make new unicast and multicast sockets. Cannot be null.</param> /// <param name="localPort">The specific local port to use for all sockets created by this instance. Specify zero to indicate the system should choose a free port itself.</param> /// <param name="multicastTimeToLive">The multicast time to live value for multicast sockets. Technically this is a number of router hops, not a 'Time'. Must be greater than zero.</param> /// <exception cref="System.ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">The <paramref name="multicastTimeToLive"/> argument is less than or equal to zero.</exception> public CommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive) { if (socketFactory == null) { throw new ArgumentNullException("socketFactory"); } if (multicastTimeToLive <= 0) { throw new ArgumentOutOfRangeException("multicastTimeToLive", "multicastTimeToLive must be greater than zero."); } _BroadcastListenSocketSynchroniser = new object(); _SendSocketSynchroniser = new object(); _LocalPort = localPort; _SocketFactory = socketFactory; _RequestParser = new HttpRequestParser(); _ResponseParser = new HttpResponseParser(); _MulticastTtl = multicastTimeToLive; }
public static void Listen(this TcpClient connection, Action <HttpRequestLine> request) { NetworkStream stream = connection.GetStream(); var buffer = BufferPool.Shared.RentBuffer(1024); while (true) { var bytesRead = stream.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { break; } Console.WriteLine("Read {0} bytes, Payload: {1}", bytesRead, Encoding.ASCII.GetString(buffer, 0, bytesRead)); unsafe { fixed(byte *pBuffer = buffer) { var bufferSpan = new ByteSpan(pBuffer, bytesRead); HttpRequestLine requestLine; if (!HttpRequestParser.TryParseRequestLine(bufferSpan, out requestLine)) { Console.WriteLine("request could not be parsed"); } request(requestLine); } } if (bytesRead < buffer.Length) { break; } } BufferPool.Shared.ReturnBuffer(ref buffer); connection.Dispose(); }
public void TestParseWithNullRow() { // Arrange var header = new Header { Name = "HttpRequest Actual", Depth = 1, From = 1, To = 2, Children = new List <Header> { new Header { Name = "BaseUri", Depth = 2, From = 1, To = 1, }, new Header { Name = "Headers", Depth = 2, From = 2, To = 2, Children = new List <Header> { new Header { Name = "User-Agent", Depth = 3, From = 2, To = 2, }, } }, } }; // Act HttpRequestParser.Parse(header, null, "Actual"); }
public void Start() { if (this.listener.IsListening) { throw new ArgumentException("already listening"); } this.listener.Start(); Log.Message($"Web server started at {url}"); CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token; TaskFactory taskFactory = new TaskFactory(token, TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning, TaskScheduler.Default); this.listenerTask = taskFactory.StartNew(() => { while (!token.IsCancellationRequested) { var context = this.listener.GetContextAsync(); var httpRequest = context.Result.Request; var request = new WebHookRequest() { Request = HttpRequestParser.Extract(httpRequest) }; this.requests.Enqueue(request); var response = context.Result.Response; response.StatusCode = 200; var message = System.Text.Encoding.UTF8.GetBytes("OK"); response.ContentLength64 = message.Length; response.ContentType = "text"; var outputstream = response.OutputStream; outputstream.Write(message, 0, message.Length); outputstream.Close(); } }, token); }
public void ParseRequestStream_ThreeEmptyResponses_EmptyRequestString() { var s = new HttpRequestParser(); var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4\r\n", //to force double /r/n on string.Join "" }; var body = "data"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(Encoding.UTF8.GetBytes(body)); var request = s.ParseRequestStream(new TestStream(byteStreamParts)).Result; Assert.AreEqual(false, request.IsComplete); }
public override void StartReceive() { if (IsClosed) { return; } Socket readSocket = null; HttpObjectParser parser = null; if (isClient) { readSocket = this.PipesChain.ChainState.ClientSocket; parser = new HttpRequestParser(); } else { readSocket = this.PipesChain.ChainState.ServerSocket; parser = new HttpResponseParser(); } HttpReaderState httpReaderState = new HttpReaderState(this, readSocket, parser); BeginReceive(httpReaderState); }
/// <summary> /// 收到WebSocket的握手请求 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private async Task OnWebSocketHandshakeRequestAsync(IContenxt context) { try { var result = HttpRequestParser.Parse(context); if (result.IsHttp == false) { await this.Next.Invoke(context); return; } // 数据未完整 if (result.Request == null) { return; } if (result.Request.IsWebsocketRequest() == false) { await this.Next.Invoke(context); return; } context.StreamReader.Clear(result.PackageLength); const string seckey = "Sec-WebSocket-Key"; var secValue = result.Request.Headers[seckey]; this.ResponseHandshake(context, secValue); } catch (Exception) { context.StreamReader.Clear(); context.Session.Close(); } }
private IEnumerable<System.Net.Http.HttpRequestMessage> GetAllSentBroadcasts(MockCommsServer server) { var parser = new HttpRequestParser(); var retVal = new List<System.Net.Http.HttpRequestMessage>(); while (server.SentBroadcasts.Any()) { var sentBroadcast = server.SentBroadcasts.Dequeue(); retVal.Add(parser.Parse(System.Text.UTF8Encoding.ASCII.GetString(sentBroadcast.Buffer))); } return retVal; }
/// <summary> /// Full constructor. /// </summary> /// <param name="socketFactory">An implementation of the <see cref="ISocketFactory"/> interface that can be used to make new unicast and multicast sockets. Cannot be null.</param> /// <param name="localPort">The specific local port to use for all sockets created by this instance. Specify zero to indicate the system should choose a free port itself.</param> /// <param name="multicastTimeToLive">The multicast time to live value for multicast sockets. Technically this is a number of router hops, not a 'Time'. Must be greater than zero.</param> /// <exception cref="System.ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">The <paramref name="multicastTimeToLive"/> argument is less than or equal to zero.</exception> public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive) { if (socketFactory == null) throw new ArgumentNullException("socketFactory"); if (multicastTimeToLive <= 0) throw new ArgumentOutOfRangeException("multicastTimeToLive", "multicastTimeToLive must be greater than zero."); _BroadcastListenSocketSynchroniser = new object(); _SendSocketSynchroniser = new object(); _LocalPort = localPort; _SocketFactory = socketFactory; _RequestParser = new HttpRequestParser(); _ResponseParser = new HttpResponseParser(); _MulticastTtl = multicastTimeToLive; }
/// <summary> /// Initializes a new instance of the <see cref="HttpClientContext"/> class. /// </summary> /// <param name="secured">true if the connection is secured (SSL/TLS)</param> /// <param name="remoteEndPoint">client that connected.</param> /// <param name="stream">Stream used for communication</param> /// <param name="parserFactory">Used to create a <see cref="IHttpRequestParser"/>.</param> /// <param name="bufferSize">Size of buffer to use when reading data. Must be at least 4096 bytes.</param> /// <exception cref="SocketException">If <see cref="Socket.BeginReceive(byte[],int,int,SocketFlags,AsyncCallback,object)"/> fails</exception> /// <exception cref="ArgumentException">Stream must be writable and readable.</exception> public HttpClientContext(bool secured, IPEndPoint remoteEndPoint, Stream stream, IRequestParserFactory parserFactory, int bufferSize, Socket sock) { Check.Require(remoteEndPoint, "remoteEndPoint"); Check.NotEmpty(remoteEndPoint.Address.ToString(), "remoteEndPoint.Address"); Check.Require(stream, "stream"); Check.Require(parserFactory, "parser"); Check.Min(4096, bufferSize, "bufferSize"); Check.Require(sock, "socket"); if (!stream.CanWrite || !stream.CanRead) throw new ArgumentException("Stream must be writable and readable."); _bufferSize = bufferSize; RemoteAddress = remoteEndPoint.Address.ToString(); RemotePort = remoteEndPoint.Port.ToString(); _log = NullLogWriter.Instance; _parser = parserFactory.CreateParser(_log); _parser.RequestCompleted += OnRequestCompleted; _parser.RequestLineReceived += OnRequestLine; _parser.HeaderReceived += OnHeaderReceived; _parser.BodyBytesReceived += OnBodyBytesReceived; _currentRequest = new HttpRequest(); Available = false; IsSecured = secured; _stream = stream; _sock = sock; _buffer = new byte[bufferSize]; // by Fumi.Iseki SSLCommonName = ""; if (secured) { SslStream _ssl = (SslStream)_stream; X509Certificate _cert1 = _ssl.RemoteCertificate; if (_cert1 != null) { X509Certificate2 _cert2 = new X509Certificate2(_cert1); if (_cert2 != null) SSLCommonName = _cert2.GetNameInfo(X509NameType.SimpleName, false); } } }
public void HttpRequestParser_ThrowsOnNull() { var parser = new HttpRequestParser(); parser.Parse(null); }
public void HttpResponseParser_ThrowsOnMisingCrLf() { var parser = new HttpRequestParser(); parser.Parse("HTTP/1.1 200 OK"); }
public void HttpRequestParser_ThrowsOnEmpty() { var parser = new HttpRequestParser(); parser.Parse(String.Empty); }
public void HttpRequestParser_ThrowsOnMisingCrLf() { var parser = new HttpRequestParser(); parser.Parse("GET * HTTP/1.1"); }
/// <summary> /// на сервер (на ферму) заливаетсяpro файл pxml, содержащий описание портфеля роботов /// вернуть сообщение, которое нужно отобразить в Popup-e /// </summary> private string ProcessFileUpload(HttpListenerContext context) { var xmlDocs = new Dictionary<string, XmlDocument>(); var hiddenFields = new Dictionary<string, string>(); try { string dataText; using (var reader = new StreamReader(context.Request.InputStream, Encoding.UTF8)) { dataText = reader.ReadToEnd(); } var parser = new HttpRequestParser(dataText); foreach (var ctx in parser.records) { try { var doc = ctx.GetXml(); xmlDocs.Add(ctx.FileName, doc); } catch { hiddenFields.Add(ctx.Name, ctx.FileData); } } } catch (Exception ex) { var strError = "Ошибка в ProcessFileUpload(): " + ex; Logger.Error(strError); RobotFarm.Instance.AppendLogMessage(strError); return "Ошибка обработки документа"; } // прочитать номер счета из hidden-поля accountId... // если номер заполнен - это - портфель роботов if (hiddenFields.ContainsKey("accountId") && xmlDocs.Count == 1) { return UploadRobotPortfolio(hiddenFields["accountId"], xmlDocs.First().Value); } return string.Empty; }