I am stuck with reading data from HttpListener. Data arrives, I verify it with request.ContentLength64 that is usually over 8000 and it increases as the server generates more and more data.
The server sends data as HTTP post and the content type is text/plain.
When I try to check whether streamreader got some data via its length attribute I get 0.
The code is a little bit messy as I was trying different ways to make it work but unfortunatelly I had no luck.
Does anyone got an idea what I'm doing wrong?
Thanks!
HttpListener listener2 = new HttpListener();
listener2.Prefixes.Clear();
listener2.Prefixes.Add("http://+:4200/");
listener2.Prefixes.Add("http://XXX.XXX.eu/");
listener2.Start();
LogWriteLine("http listener started listening to: " +listener2.Prefixes);
try
{
while (true)//change to match end check
{
LogWriteLine("http listener waiting");
HttpListenerContext context = listener2.GetContext();
LogWriteLine("http request arrived");
HttpListenerRequest request = context.Request;
// Obtain a response object.
HttpListenerResponse response = context.Response;
System.IO.Stream body = request.InputStream;
System.Text.Encoding encoding = request.ContentEncoding;
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
if (!request.HasEntityBody)
{
LogWriteLine("No client data was sent with the request.");
Thread.Sleep(300);
//return;
}
if (request.ContentType != null)
{
LogWriteLine("Client data content type " + request.ContentType);
}
LogWriteLine("Client data content length " + request.ContentLength64); //Works fine
LogWriteLine("Start of client data:");
// Convert the data to a string and display it on the console.
Console.WriteLine(body.CanSeek);
string s = reader.ReadToEnd();
var ahoj = new StreamReader(context.Request.InputStream).ReadToEnd();
Console.WriteLine("ahoj length " + ahoj.Length); //0
Console.WriteLine(s); //nothing
string text;
var bytes = default(byte[]);
using (var reader1 = new StreamReader(request.InputStream,
request.ContentEncoding))
{
text = reader1.ReadToEnd();
Console.WriteLine(text + text.Length); //output: 0
using (var memstream = new MemoryStream())
{
reader1.BaseStream.CopyTo(memstream);
bytes = memstream.ToArray();
}
Console.WriteLine("bytes:" + bytes.Length); //output: bytes: 0
}
LogWriteLine("End of client data:");
//write to console file
sw.Write(s);
body.Close();
reader.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Related
I'm trying to access a file on the server via an api that is behind Basic Auth. I then want to download that to a client's PC.
I've got the following code which does GET the url from behind the basic auth, however the image never downloads properly. I either get a failed network error message or I get a message saying I can't download it because my machine doesn't have an app installed to open it. It's a png so it definitely does!
It goes the whole way through the code and doesn't error so I'm confused as to why it's not downloading correctly to the clients machine (my pc while I'm testing!)
In the code I am specifying one file and I have specified it's length as bytes just to try and narrow down where I'm going wrong. Normally this could be any file that's being access of any length!
This is the code I have:
//Create a stream for the file
Stream stream = null;
var size = fileResp.ContentLength; //I used this to determine the file was 64196 in size
//This controls how many bytes to read at a time and send to the client
int bytesToRead = 64196;
// Buffer to read bytes in chunk size specified above
byte[] buffer = new Byte[bytesToRead];
string url= "https://myURL/images/image-2019-04-02-16-25-18-458.png";
WebRequest myReq = WebRequest.Create(url);
string credentials = "username:pwd";
CredentialCache mycache = new CredentialCache();
myReq.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
myReq.Method = "GET";
// The number of bytes read
try
{
//Create a response for this request
HttpWebResponse fileResp = (HttpWebResponse)myReq.GetResponse();
if (myReq.ContentLength > 0)
fileResp.ContentLength = myReq.ContentLength;
//Get the Stream returned from the response
stream = fileResp.GetResponseStream();
// prepare the response to the client. resp is the client Response
var resp = HttpContext.Current.Response;
//Indicate the type of data being sent
string contentType = MimeMapping.GetMimeMapping("new.png");
resp.ContentType = contentType;
string fileName = "new.png";
//Name the file
resp.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());
int length;
do
{
// Verify that the client is connected.
if (resp.IsClientConnected)
{
// Read data into the buffer.
length = stream.Read(buffer, 0, bytesToRead);
// and write it out to the response's output stream
resp.OutputStream.Write(buffer, 0, length);
// Flush the data
resp.Flush();
//Clear the buffer
buffer = new Byte[bytesToRead];
}
else
{
// cancel the download if client has disconnected
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
}
}
The output from here: fileResp.GetResponseStream();
At first, please try to test if the following code works on your computer.
private bool DownloadImage(string imgurl, string filename)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(imgurl);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch
{
response = null;
return false;
}
if (response != null && response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
Bitmap bitmap = new Bitmap(receiveStream);
if (bitmap != null)
{
bitmap.Save(filename);
}
receiveStream.Flush();
receiveStream.Close();
response.Close();
return true;
}
else
{
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
string imgurl = "https://upload.wikimedia.org/wikipedia/commons/4/42/Cute-Ball-Go-icon.png";
string filename = "D:\\download_test.png";
bool bIsDownloadSuccess = DownloadImage(imgurl, filename);
}
This code works on me well.
It doesn't have error, but returns false.
Please check where false is returned.
If it has some error, the problem will be on Windows System.
Please try and let me know.
Thanks.
I have a simple part of the code that creates a http listener for a specific url. Everything works perfectly, untill I turn on Xampp - Apache Web Server. At that moment, whenever I try to run the listener, I get Address already in use exeption.
I did some research and found a possible cause: I guess it won't work because Apache is listening to http port(idk if it is a proper term, it is what I got from running lsof-i:http command.), therefore my app cannot start the listener on http. But it is weird, since I have full url specified, so I suppose if request matches the url, Apache should stay away from it... Maybe I am wrong...
Does anyone know a solution how I could run Apache and my http listener at the same time?
Also I am running Debian 10 if it helps. Thanks in advance!
HttpListener listener2 = new HttpListener();
listener2.Prefixes.Clear();
listener2.Prefixes.Add("http://xxxx.xxxx.eu/");
listener2.Start();
LogWriteLine("http listener started listening to: " +listener2.Prefixes);
try
{
while (true)
{
HttpListenerContext context = listener2.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
System.IO.Stream body = request.InputStream;
System.Text.Encoding encoding = request.ContentEncoding;
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
if (!request.HasEntityBody)
{
LogWriteLine("No client data was sent with the request.");
Thread.Sleep(300);
}
if (request.ContentType != null)
{
LogWriteLine("Client data content type " + request.ContentType);
}
LogWriteLine("Client data content length " + request.ContentLength64);
LogWriteLine("Start of client data:");
string s = reader.ReadToEnd();
var bytes = default(byte[]);
using (var reader1 = new StreamReader(request.InputStream,
request.ContentEncoding))
{
text = reader1.ReadToEnd();
using (var memstream = new MemoryStream())
{
memstream.Position = 0;
reader1.BaseStream.CopyTo(memstream);
bytes = memstream.ToArray();
memstream.Position = 0;
Console.WriteLine("memstream length: " + memstream.Length);
}
Console.WriteLine("bytes:" + bytes.Length); //output: bytes: 0
}
LogWriteLine("End of client data:");
response.StatusCode = (int)HttpStatusCode.OK;
response.Close();
body.Close();
reader.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
I want to send some json data using this code to a distant server (Rest, outside my control), following the way I'm sending it :
I create the url and the request method first :
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(gUrlDot);
request.Method = "POST";
Dictionary<String, String> lDictionary = new Dictionary<String, String>();
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Dot lDot= new Dot();
serviceContext lserviceContext = new serviceContext();
items litems = new items();
lDot.rad = pClient;
lDictionary.Add("companyId", "00230");
lDictionary.Add("treatmentDate", lGlobals.FormatDateYYYYMMDD());
lDictionary.Add("country", "FR");
lDictionary.Add("language", "fr");
lDictionary.Add("Id", "test");
litems.contextItem = lDictionary;
lDot.serviceContext = lserviceContext;
lDot.serviceContext.items = litems;
String Input=_Tools.JsonSerializer(lDot);
log.Debug("Input Dot " + Input);
Byte[] byteArray = encoding.GetBytes(Input);
request.ContentLength = byteArray.Length;
request.ContentType = #"application/json";
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
long length = 0;
When i'm getting here it crashes with an execption : Error 500 !
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
length = response.ContentLength;
string output = response.ToString();
lTrace.AppendLine("-Flux Json recu => " + response.StatusCode + " " + length);
log.Debug("Output Dot " + output);
}
log.Info(LogsHelper.LogHeader("End processing Get list ", pClient, Service.SrvGetList, "", lResponse.StatusCode, lResponse.StatusLabel, lResponse.ResponseObject, ref lTrace));
}
catch (Exception ex)
{
lResponse.StatusCode = StatusCodes.ERROR_COMMUNICATION;
log.Error(LogsHelper.LogHeader("End processing Get list", pClient, Service.SrvGetList, "", lResponse.StatusCode, ex.Message, lResponse.ResponseObject, ref lTrace));
}
return lResponse;
}
what am i missing here?
A 500 error means there's a problem on the server you're making the request to. You'll need to check to make sure two things;
1) Make sure your request is properly formatted, and doesn't have any surprises or invalid values for the requested resource.
2) that the server you want to talk to CAN get requests, and that its up-to-date (if you control the client).
In either case, the most common reason for a 500 is that something outside of your control has gone wrong on the client server.
I'm trying to make a proxy server with C#.
Here's my code:
static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
WebRequest request;
WebResponse response;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
String[] input;
// Loop to receive all the data sent by the client.
while (stream.DataAvailable)
{
data = null;
i = stream.Read(bytes, 0, bytes.Length);
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
input = data.Split();
Console.WriteLine("\n\r\n input[1]" + input[1] + "\n");
Stream dataStream;
StreamReader reader;
string responseFromServer;
try
{
request = WebRequest.Create(input[1]);
response = request.GetResponse();
// Process the data sent by the client.
data = data.ToUpper();
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(dataStream);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Display the content
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
byte[] msg = System.Text.Encoding.ASCII.GetBytes(responseFromServer);
// Send back a response.
stream.Write(msg, 0, msg.Length);
// Console.WriteLine("Sent: {0}", data);
//stream.Write();
reader.Close();
response.Close();
}
catch (System.UriFormatException e)
{
Console.WriteLine("Exception due to" + e.Data);
Console.WriteLine("Input[1] = " + input[1]);
}
data = null;
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
It does not work for ssl requests but seems to work for http.
However, it does not load any images.
I'm using Firefox as the browser.
Any ideas why?
Also is this the best way to make a proxy server? Are there any other methods?
After a bit of testing, I wrote my own code.
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Text;
namespace SharpProxy
{
class MainClass
{
private static void StartAcceptingClient(IAsyncResult ar)
{
var tcpClient = server.EndAcceptTcpClient(ar);
server.BeginAcceptTcpClient(new AsyncCallback(StartAcceptingClient), null);
// Read the data stream from the client.
NetworkStream stream = tcpClient.GetStream();
byte[] buffer = new byte[256];
Console.WriteLine("====== GOT A NEW TCP CLIENT ====== " + tcpClient.Client.RemoteEndPoint.ToString());
int read = stream.Read(buffer, 0, 1);
MemoryStream saved = new MemoryStream();
saved.Write(buffer, 0, read);
bool isValid = false;
while (read > 0 )
{
read = stream.Read(buffer, 0, 1);
saved.Write(buffer, 0, read);
//Check if the last four bytes were a double \r\n.
var aBytes = saved.ToArray();
int len = aBytes.Length;
if (aBytes.Length >= 4 && aBytes[len - 1] == '\n' && aBytes[len - 2] == '\r' && aBytes[len - 3] == '\n' && aBytes[len - 4] == '\r')
{
isValid = true;
break;
}
}
Console.WriteLine("End of receive.");
string originalRequest = Encoding.ASCII.GetString(saved.ToArray());
byte[] origBytes = saved.ToArray();
saved.Close();
Console.WriteLine(originalRequest);
if (!isValid)
{
Console.WriteLine("This wasn't a valid request");
return;
}
//Find the hoster and do our own request.
string host = originalRequest.Split(new char[] { '\n' }).First(line => line.StartsWith("Host:"));
host = host.Substring(5).Trim(); //Cut of rest.
Console.WriteLine("The host is: " + host);
//Do our own request.
try
{
Socket sProxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sProxy.Connect(host, 80);
sProxy.Send(origBytes);
//Now route everything between the tcpclient and this socket...
//create the state object
var state = new ProxyState() { ourSocket = sProxy, incomingClient = stream };
sProxy.BeginReceive(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(Receiver), state);
stream.BeginRead(state.SendBuffer, 0, state.SendBuffer.Length, new AsyncCallback(SendToHTTPServer), state);
}
catch (Exception) { Console.WriteLine("Exception while doing our own request"); }
}
static TcpListener server = null;
public static void Main(string[] args)
{
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("0.0.0.0");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
Console.WriteLine("Server started on " + server.LocalEndpoint.ToString());
server.BeginAcceptTcpClient(new AsyncCallback(StartAcceptingClient), null);
while (true)
Thread.Sleep(10);
}
catch (Exception) { Console.WriteLine("Setting up the server failed"); }
}
private static void SendToHTTPServer(IAsyncResult ar)
{
try
{
ProxyState back = (ProxyState)ar.AsyncState;
int rec = back.incomingClient.EndRead(ar);
//Push this content to the server
back.ourSocket.Send(back.SendBuffer.Take(rec).ToArray());
back.incomingClient.BeginRead(back.SendBuffer, 0, back.SendBuffer.Length, new AsyncCallback(SendToHTTPServer), back);
}
catch (Exception e) { Console.WriteLine("Exc. when sending to server: " + e.ToString()); }
}
static void Receiver(IAsyncResult state)
{
try
{
ProxyState back = (ProxyState)state.AsyncState;
int rec = back.ourSocket.EndReceive(state);
//Set up the back and forth connections
back.incomingClient.Write(back.ReceiveBuffer, 0, rec);
back.ourSocket.BeginReceive(back.ReceiveBuffer, 0, back.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(Receiver), back);
}
catch (Exception e) { Console.WriteLine("Exc. when receiving from client: " + e.ToString()); }
}
//Every proxy connection has an end an and a beginning, plus a
//Sending buffer and a receive buffer
class ProxyState
{
public NetworkStream incomingClient { get; set; }
public Socket ourSocket { get; set; }
private byte[] buffReceive = new byte[512];
private byte[] buffSend = new byte[512];
public byte[] ReceiveBuffer { get { return buffReceive; } set { buffReceive = value; } }
public byte[] SendBuffer { get { return buffSend; } set { buffSend = value; } }
}
}
}
Here's how it works: I listen on a port, and wait for a HTTP request. This is ended by a double carriage return and a linefeed, a \r\n\r\n. As soon as that happens, I try to parse the original host from the request with a Linq statement. I open my own socket to the server, and make use of the asynchronous callbacks. Basically, you need to write everything that comes from the proxy-iniator to the HTTP-Server, and everything that the HTTP-Server sends back needs to be pushed back to the original client aswell. This is why I set up my own state-object, which just saves the incomming client and the Socket, which is connected to the original HTTP server. And as such, communication can happen and I act as a proxy server.
Here's a screenshot with all the connections done right:
This proxy server is far from perfect, but the basic concept should be clear. This gave me some inspiration.
You use a streamreader on binary image data, that is not going to work. Not every binary is a valid ASCII encoded string. You should read the response as binary, and write it to the other stream as binary as well. You can try to convert it to ascii to print it to the console, but do not use the converted text to respond, because all the non-valid ascii characters will be converted to ?-s. I did modify your code to first read the response in a MemoryStream, and write that back. The data written to the console is still converted, but not user anywhere else.
static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
WebRequest request;
WebResponse response;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
String[] input;
// Loop to receive all the data sent by the client.
while (stream.DataAvailable)
{
data = null;
i = stream.Read(bytes, 0, bytes.Length);
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
input = data.Split();
Console.WriteLine("\n\r\n input[1]" + input[1] + "\n");
Stream dataStream;
StreamReader reader;
string responseFromServer;
try
{
request = WebRequest.Create(input[1]);
response = request.GetResponse();
// Process the data sent by the client.
data = data.ToUpper();
dataStream = response.GetResponseStream();
MemoryStream ms = new MemoryStream();
dataStream.CopyTo(ms);
ms.Position = 0;
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(ms);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Display the content
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
byte[] msg = ms.ToArray();
// Send back a response.
stream.Write(msg, 0, msg.Length);
// Console.WriteLine("Sent: {0}", data);
//stream.Write();
reader.Close();
response.Close();
}
catch (System.UriFormatException e)
{
Console.WriteLine("Exception due to" + e.Data);
Console.WriteLine("Input[1] = " + input[1]);
}
data = null;
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
I am writing to Solr using JSON via HTTP/POST from a C#/Winforms/.NET4.0 app to speed up indexing and using the code below. I write a document to solr (based on these instructions) but keep getting a '400 bad request'. The JSON appears to be clean and no issues.
It seems to be a syntax issue but I have been wrestling with this for last many hours to no avail. Any ideas on what is awry? All help appreciated.
Here is the URI string being posted
"http://localhost:8080/solr/update/json -H 'Content-type:application/json' -d ' [ {\"UUID\":\"d2a174e4-81d6-487f-b68d-392be5d3d47a\",\"Extension\":\".AVI\",\"VideoFileName\":\"Clip 1.avi\"} ' ]"
string uri = http://localhost:8080/solr/update/json;
public bool WriteJSONToSolr(string uri, string json)
{
WebRequest request = WebRequest.Create(uri + " -H 'Content-type:application/json' -d ' [ " + json + " ' ]" );
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(json);
Stream stream = null;
try
{ // send the Post
request.ContentLength = bytes.Length; //Count bytes to send
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length); //Send it
}
catch
{
return false;
}
finally
{
if (stream != null)
{
stream.Close();
}
}
System.Net.WebResponse response = request.GetResponse();
if (response == null) return false;
return true;
}
If you are inserting then you will need to use add and doc in your json element. You'll also want to add a commit so that the index is updated. You can also remove the parameters from your uri as you can add them in the web request object. Lastly, you should have your collection name in the uri.
string json = "{\"add\":{\"doc\":{"
+ "\"UUID\":\"d2a174e4-81d6-487f-b68d-392be5d3d47a\","
+ "\"Extension\":\".AVI\","
+ "\"VideoFileName\":\"Clip 1.avi\"}},";
+ "\"commit\":{}}";
string uri = "http://localhost:8080/solr/collection/update";
WebRequest request = WebRequest.Create(uri);
request.ContentType = "application/json";
request.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(json);
Stream stream = null;
try {
request.ContentLength = bytes.Length;
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
}
catch {
return;
}
finally {
if (stream != null) {
stream.Close();
}
}
System.Net.WebResponse response = request.GetResponse();
if (response == null) {
return;
}
If you are inserting multiple objects to solr you can add multiple add objects or doc objects to the json. For example...
json = "{add:{doc:{keys:values}}, add:{doc:{keys:values}}, commit:{}}"
or
json = "{add:{doc:{keys:values}, doc:{keys:values}}, commit:{}}"
While your debugging this watch the log for solr. It will alert you to any problems with that may be happening on the solr side.
First of all, I don't think you are passing a correct json data with -d option.. Look at the following formatting code in your code.
" -H 'Content-type:application/json' -d ' [ " + json + " ' ]"
Assume, your json data is {"name":"sam"} Then, the above formatting results to
-H 'Content-type:application/json' -d ' [{"name":"sam"} ' ]
You are passing a json data with missing ].
Apart from that, your approach for updating a document in solr index is wrong. Take a look at the following simple code.
[BTW: You may pass the 'commit' argument in the url].
public async Task PostAsync()
{
string json = "{\"add\": {\"doc\": {"
+ "\"id\":\"12345\","
+ "\"firstname\":\"Sam\","
+ "\"lastname\":\"Wills\","
+ "\"dob\":\"2016-12-14T00:00:00Z\""
+ "}}}";
using (var client = new HttpClient())
{
string uri = "http://localhost:8983/solr/people/update/json?wt=json&commit=true";
var jsonContent = new StringContent(json);
await client.PostAsync(new Uri(uri), jsonContent);
}
}
If you want to update a specific field instead of whole document [partial update], use the following code snippet.
public async Task PartialPostAsync()
{
string json = "{\"add\": {\"doc\": {"
+ "\"id\":\"12345\","
+ "\"lastname\":{\"set\":\"George\"}"
+ "}}}";
using (var client = new HttpClient())
{
string uri = "http://localhost:8983/solr/people/update/json?wt=json&commit=true";
var jsonContent = new StringContent(json);
await client.PostAsync(new Uri(uri), jsonContent);
}
}
'id' field is an unique field.
did you forget putting a space char before -H?
The reasong that your code isn't working, is because you are using cURL syntax in .Net.
cURL is an executable that sends and receives HTTP requests and .Net is a framework for programming applications.
They are not the same.
To make it work with .Net you first should post to the correct uri, and you need to set the correct ContentType property like such:
var uri = "http://localhost:8080/solr/update/json";
using (var r = WebRequest.Create(uri))
{
r.ContentType = "application/json";
r.Method = "POST";
using (var rs = r.GetRequestStream())
rs.Write // your data
// get response
// return response data
}
That said, why inflict pain upon yourself? Just use a SolR connector that already has a typed API for SolR operations!
https://code.google.com/p/solrnet/ for example!
But if you don't want to use that, then at least use a modern HTTP API like https://nuget.org/packages/RestSharp
I ran into this same problem today.
Try these two things
1) Keep in mind that you can NOT send a json string like
[{"A":"1","B":"0","C":"","D":"Washington"}]
instead you may have to massage the json to be more like
[{"A":"1","B":"0","D":"Washington"}]
Solr does not like empty values.
2) This second trick that helps (when sending data to solr via 'curl') : Try replacing all Double Quotes in your json string with two Double Quotes before you send the request to solr.
json = json.Replace(#"""", #"""""");
Please try below code after convert json to stream bytes
protected override void Append(LoggingEvent loggingEvent)
{
byte[] bodyBytes;
try
{
string body = BodyFormatter.CreateBody(loggingEvent, _parameters);
bodyBytes = Encoding.UTF8.GetBytes(body);
}
catch (Exception e)
{
ErrorHandler.Error("Failed to create body", e);
return;
}
HttpWebRequest request = BuildRequest();
request.BeginGetRequestStream(r =>
{
try
{
using (Stream stream = request.EndGetRequestStream(r))
{
stream.BeginWrite(bodyBytes, 0, bodyBytes.Length, c =>
{
try
{
stream.EndWrite(c);
request.BeginGetResponse(a =>
{
try
{
var response = request.EndGetResponse(a);
if (((HttpWebResponse)response).StatusCode != HttpStatusCode.OK)
ErrorHandler.Error("Got failed response: " + ((HttpWebResponse)response).StatusDescription);
response.Close();
}
catch (Exception e)
{
ErrorHandler.Error("Failed to get response", e);
}
}, null);
}
catch (Exception e)
{
ErrorHandler.Error("Failed to write", e);
}
}, null);
}
}
catch (Exception e)
{
ErrorHandler.Error("Failed to connect", e);
}
}, null);
}