|
BillWoodruff wrote: I have been struggling with what Jeff Atwood calls VS's "bastardized regular expression syntax"
That only applies to VS2008 and earlier. Since VS2012, the search & replace uses standard .NET regular expressions[^].
Visual Studio uses .NET Framework regular expressions to find and replace text.
Before Visual Studio 2012, Visual Studio used custom regular expression syntax in the Find and Replace windows.
BillWoodruff wrote: how to select files that have specific text (keyword) content, and then apply S&R to only the matching files.
I don't think there's any way to do that in a single step, unless the content you're searching for is the content you want to replace.
You might need to do a "find in files" to find and open the matching files, and then a S&R targeting the open files.
Or were you wanting to limit the S&R based on the file names? I don't think they support regex; you'd need to use DOS-style wildcards instead.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks, Richard,
My impression is that VS 2017 is using some form of JavaScript related regex syntax, which is still as non-standard as when Atwood made his comments in 2006. Of course, you can say it's .NET standard
It took me two days to figure out one multi-line RegEx solution in VS. The MSDN docs were (as so often) useless.
Thanks to Macej's extension ... which will generate a multi-line RegEx for you based on your selection in a code window ... this can be speeded up nicely.
The tricky part of my goal here is applying the S&R recursively to folders/files that contain the "keyword" ... but, applying only to open files may have to suffice.
It ought to be this simple:
Solution.Files.Search(SearchOption.Recursive)
.Where(file => file.Extension == ".cs")
.Select(file => file.StartsWith(@"//Keyword\r\n"))
.ReplaceInFiles(ReplaceOption.All)(@"stuff", @"newstuff);
Yes, that is wishful thinking
best, Bill
«Beauty is in the eye of the beholder, and it may be necessary from time to time to give a stupid or misinformed beholder a black eye.» Miss Piggy
|
|
|
|
|
BillWoodruff wrote: The tricky part of my goal here is applying the S&R recursively to folders/files that contain the "keyword" ... but, applying only to open files may have to suffice.
In VS, you can select files with a name pattern. In Find/replace dialog, define it in Look at these file types.
Moreover, you can select folders (and save this selection for later use) with [...] button next to Look in.
And you can apply the search to open documents only. Select All Open Documents in Look in.
|
|
|
|
|
Thanks, I am familiar with the uses of 'Find/Replace in Files you mention. But, what I am looking for is a way to apply a RegEx find/replace pattern recursively to files in nested folders with a keyword ... without having to open them all, or re-configure the current open code files in VS.
«Beauty is in the eye of the beholder, and it may be necessary from time to time to give a stupid or misinformed beholder a black eye.» Miss Piggy
|
|
|
|
|
BillWoodruff wrote: Solution.Files.Search(SearchOption.Recursive)
.Where(file => file.Extension == ".cs")
.Select(file => file.StartsWith(@"//Keyword\r\n"))
.ReplaceInFiles(ReplaceOption.All)(@"stuff", @"newstuff);
Yes, that is wishful thinking Simple. Write your own VS Add-In.
There are two kinds of people in the world: those who can extrapolate from incomplete data.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
Hi Ryan,
I'm curious ... have you written any VS extensions yourself that operated on open project files ?
A reasonable suggestion, but one I just don't have time to pursue. And, I can achieve what I want with UltraEdit. In my research on multi-line replacement, I came across a reference saying NotePad++ also has multi-line find.replace.
thanks, Bill
«Beauty is in the eye of the beholder, and it may be necessary from time to time to give a stupid or misinformed beholder a black eye.» Miss Piggy
|
|
|
|
|
Hi Friends.
i have more then 1 ComboBox to add items.
items are...
Makam
Sukam
Bhunte
Amma
Tantan
Toit
Hawa
Sanga
Jowan... so how to add these items same tiime in comboBox?
Pradeep Adhikari
|
|
|
|
|
|
Try:
string[] items = { "Makam", "Sukam", "Bhunte", "Amma", "Tantan", "Toit", "Hawa", "Sanga", "Jowan" };
myComboBox.Items.AddRange(items);
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hi, I am new to c# coding. The scenario for my problem is:
The outlook is hosted on a windows 2008 r2 server there are 12 mailboxes added in it, I want to fetch the details (like the sender name, when was the email recieved, the attachment name etc) of each emails recieved on each mailboxes everyday. The emails are in deleted folder of each mailbox. But there is a catch I dont have the password of any of the mailboxes, I need the extracted information in a CSV. Is it possible via C# if yes please guide then.
|
|
|
|
|
If you don't have the password, then what you are trying to do is wrong - and possibly illegal in some countries - you are authorized to access information via the username / password combo, and without both of those items you should not and cannot access the mails.
Contact the owners of the mailboxes and get their permission and passwords: then you should have no problem.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
So there is this guy called Member 13245972 who has an email account. I want to access his emails but I don't have his password, how can I do this.
Seriously? Exactly what kind of answer are you expecting to see?
|
|
|
|
|
it's working.
Thank you so much Richard MacCutchan.
|
|
|
|
|
Hello,
i am trying to analyze the issue of missing data over my Datagridview in C#.
I am receiving data from Serial port with 5250000 (5,25 Mbps)& Splitting it over datagridview (Datatable). Simultaneously i am saving this data over PC using Binarywriter.
However when i am analysing my dumped data file over pc, i found almost 30% of data is missing between two intervals. My timer Event is 1 milisec & i am updating datagridview in timer tick.
So how i can get contineous stream of data both over datagrid view & write it in file to save over PC?
Possible Error is use of Serialport.BytesToRead method as its blocking type.
SO can anybody tell where exactly i am wrong?
My Code is as below:
<pre>using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace DataGridView
{
public partial class DataGridView : Form
{
DataTable table = new DataTable("Sniffer Data Logger");
byte[] buffer = new byte[5 * 1024];
public DataGridView()
{
InitializeComponent();
table.Columns.Add("System Time");
table.Columns.Add("Source");
table.Columns.Add("T.S Begin");
table.Columns.Add("T.S End");
table.Columns.Add("Duration (uS)");
table.Columns.Add("Length");
table.Columns.Add("Data");
table.Columns.Add("CRC");
table.Columns.Add("CRC_PC");
serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.BeginInvoke(new EventHandler(Timer1_Tick));
}
private string ByteArrayToHexString(byte[] data)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in data)
sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
return sb.ToString().ToUpper().Replace(" ", "");
}
private void Timer1_Tick(object sender, EventArgs e)
{
int Bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[5 * 1024];
long read = serialPort1.Read(buffer, 0, Bytes);
BinaryWriter writer = new BinaryWriter(File.Open("c:\\temp\\snifftimetick.dat", FileMode.Append));
writer.Write(buffer);
writer.Close();
if (read == buffer.Length)
{
byte[] newbuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newbuffer, buffer.Length);
newbuffer[read] = (byte)Bytes;
buffer = newbuffer;
read++;
}
}
DataRow row = table.NewRow();
if (ByteArrayToHexString(buffer).Contains("AA"))
{
if (ByteArrayToHexString(buffer).StartsWith("AA"))
{
switch (ByteArrayToHexString(buffer).Substring(6, 2))
{
case "11":
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "ABUS_L/R");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:fff");
row["T.S Begin"] = ByteArrayToHexString(buffer).Substring(8, 8);
row["T.S End"] = ByteArrayToHexString(buffer).Substring(16, 8);
row["Length"] = ByteArrayToHexString(buffer).Substring(24, 2);
row["Data"] = ByteArrayToHexString(buffer).Substring(26, 2);
row["CRC"] = ByteArrayToHexString(buffer).Substring(28, 2);
row["CRC_PC"] = crc8.ComputeChecksum(buffer);
break;
case "12":
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "ABUS_RK");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:fff");
row["T.S Begin"] = ByteArrayToHexString(buffer).Substring(8, 8);
row["T.S End"] = ByteArrayToHexString(buffer).Substring(16, 8);
row["Length"] = ByteArrayToHexString(buffer).Substring(24, 2);
row["Data"] = ByteArrayToHexString(buffer).Substring(26, 2);
row["CRC"] = ByteArrayToHexString(buffer).Substring(28, 2);
row["CRC_PC"] = crc8.ComputeChecksum(buffer);
break;
case "13":
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "DataBus");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:ffffff");
string ts1 = ByteArrayToHexString(buffer).Substring(8, 8);
UInt32 number = Convert.ToUInt32(ts1, 16);
UInt32 time1 = swap(number);
double tmil1 = ((double)time1 / (double)1000);
string res1_tmil = tmil1.ToString();
string ts2 = ByteArrayToHexString(buffer).Substring(16, 8);
UInt32 number1 = Convert.ToUInt32(ts2, 16);
UInt32 time2 = swap(number1);
double tmil2 = ((double)time2 / (double)1000);
string res2_tmil = tmil2.ToString();
row["T.S Begin"] = time1;
row["T.S End"] = time2;
row["Duration (uS)"] = ((time2 - time1));
row["Length"] = ByteArrayToHexString(buffer).Substring(24, 2);
string len = ByteArrayToHexString(buffer).Substring(24, 2);
int count = int.Parse(len, System.Globalization.NumberStyles.HexNumber);
row["Data"] = ByteArrayToHexString(buffer).Substring(26, count * 2);
row["CRC"] = ByteArrayToHexString(buffer).Substring((26 + count * 2), 2);
row["CRC_PC"] = crc8.ComputeChecksum(buffer).ToString("X2").ToUpper();
break;
case "14":
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "RESET");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:fff");
row["T.S Begin"] = ByteArrayToHexString(buffer).Substring(8, 8);
row["T.S End"] = ByteArrayToHexString(buffer).Substring(16, 8);
break;
default:
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "ERROR_CMD_ID");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:fff");
int startIndex = 0;
string pattern = "AA";
string input = ByteArrayToHexString(buffer);
var regex = new Regex(pattern);
int endIndex = regex.Match(input, startIndex).Index;
int length = endIndex - startIndex;
row["Length"] = length;
break;
}
}
else if (!(ByteArrayToHexString(buffer).StartsWith("AA")))
{
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "ERROR_PA_POS");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:fff");
int startIndex = 0;
string pattern = "AA";
string input = ByteArrayToHexString(buffer);
var regex = new Regex(pattern);
int endIndex = regex.Match(input, startIndex).Index;
int length = endIndex - startIndex;
row["Length"] = length;
}
}
else if (!(ByteArrayToHexString(buffer).Contains("AA")))
{
table.Rows.Add(row);
row["Source"] = string.Format("{0}", "ERROR_PA");
row["System Time"] = DateTime.Now.ToString("HH:mm:ss:fff");
}
dataGridView1.Update();
dataGridView1.DataSource = table;
}
public static UInt32 swap(UInt32 value)
{
return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |
(value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;
}
public static class crc8
{
static byte[] table = new byte[256];
const byte poly = 0xd5;
public static byte ComputeChecksum(params byte[] bytes)
{
byte crc = 0;
if (bytes != null && bytes.Length > 0)
{
foreach (byte b in bytes)
{
crc = table[crc ^ b];
}
}
return crc;
}
static crc8()
{
for (int i = 0; i < 256; i++)
{
int temp = i;
for (int j = 0; j < 8; ++j)
{
if ((temp & 0x80) != 0)
{
temp = (temp << 1) ^ poly;
}
else
{
temp <<= 1;
}
}
table[i] = (byte)temp;
}
}
}
private void btnStart_Click(object sender, EventArgs e)
{
if (txtUser.Text.ToString().CompareTo("test") == 0 & txtPass.Text.ToString().CompareTo("test") == 0)
{
txtUser.PasswordChar = '*';
txtPass.PasswordChar = '*';
MessageBox.Show("Login Successfull", "Start", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (radioButton1.Checked == true)
{
serialPort1.Open();
label4.Visible = true;
label3.Visible = false;
label5.Visible = false;
timer1.Enabled = true;
}
else
{
MessageBox.Show("Choose Online Mode / Data Mode", "Start", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else
{
label3.Visible = true;
MessageBox.Show("Wrong Username/Password! \n Please try again!", "Login", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtPass.Text = "";
txtUser.Text = "";
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked == true)
{
txtPass.PasswordChar = (char)0;
checkBox1.Text = "Show Password";
}
else
{
txtPass.PasswordChar = '*';
checkBox1.Text = "Hide password";
}
}
private void btnStop_Click(object sender, EventArgs e)
{
serialPort1.Close();
timer1.Enabled = false;
label3.Visible = true;
label4.Visible = false;
}
private void btnSave_Click(object sender, EventArgs e)
{
TextWriter writer = new StreamWriter(@"C:\temp\Sniffer_log.txt");
label5.Visible = true;
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
writer.Write("\t" + dataGridView1.Rows[i].Cells[j].Value.ToString() + "\t" + ";");
}
writer.WriteLine("");
}
writer.Close();
MessageBox.Show("Data Saved");
label5.Visible = false;
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void btnclear_Click(object sender, EventArgs e)
{
table.Clear();
table.DefaultView.RowFilter = null;
}
private void button1_Click(object sender, EventArgs e)
{
table.DefaultView.RowFilter = "Length LIKE '*09*'";
dataGridView1.Refresh();
}
private void progressBar1_Click(object sender, EventArgs e)
{
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
btnStart.Enabled = true;
btnLoad.Enabled = false;
}
private void btnLoad_Click(object sender, EventArgs e)
{
}
private void radioButton3_CheckedChanged(object sender, EventArgs e)
{
}
}
}
|
|
|
|
|
Using a timer is a bad idea. Data might get lost if there are more data send between two ticks than the internal buffer can hold (4096 bytes by default) and/or with high system load. The common method is using a thread that reads and processes incoming data (especially which high data rates like in your case). I suggest to use the BackgroundWorker Class (System.ComponentModel)[^].
However, the buffer size can be set with the SerialPort.ReadBufferSize Property (System.IO.Ports)[^].
If you still want to use a timer be aware that the smallest possible timer tick is system dependant (resolution of the system clock) which is used when passing a smaller value. The typical resolution is 15 ms.
There is also a possible buffer overflow in your code:
int Bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[5 * 1024];
long read = serialPort1.Read(buffer, 0, Bytes); The commented line is doing it right.
|
|
|
|
|
Ok. One more Thing is about using Invoke method.
What i want to achieve is :
1. Read data on Serial port
2. Store it in File over PC (as raw data file)
3. Show data in decoded form over datagridview
So how i can invoke this 3 processes? If i solve this it will be done i guess.
I tried possibility like:
1. Read serialport data using serialport.BytetoRead();
2. Write data in File over PC
Both 1 & 2 i called in serialdataEvent handler
3. Invoke Timer from serialdataevent handler
But its giving me exeption handler error.
|
|
|
|
|
3 threads: 1 for the serial port; 1 for the file writer; and one for the "grid worker".
Create 2 concurrent queues; one for the file writer and one for the grid worker.
Serial reader writes to both queues; and invokes other threads if not "awake" at each queue write.
Workers run until their respective queues are exhausted; and restarted for "new work".
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
When using a worker thread there is no need to user a timer. Read the data and write them to file within the worker thread and then pass the data to the GUI thread (using delegate).
You already use a threaded receive function: port_DataReceived() .
Receive the data there instead of starting a timer.
I'm not very good in C# so I can't provide a full solution.
See for example this QA serial port using threading[^] and Basic serial port listening application[^].
|
|
|
|
|
Hi,
your job is quite a challenge: with loads of data incoming at high rate and no way to stop the producer, the consumer (i.e. your PC program) needs to be designed and coded carefully and economically to obtain an acceptable probability of it keeping up with the producer under normal circumstances.
1. I do agree with what others said about using threads, not timers.
2. I do not like your approach of turning all data into strings, such conversion is time consuming and unnecessary, the one positive thing about it is it is easy and quite readable. If incoming data is binary, you should keep it binary at all times IMO. And your file should be binary too, unless there are forcing reasons against that.
3. Moreover, your code seems to be wasting huge amounts of computer cycles; there are dozens of calls to ByteArrayToHexString(buffer) all performing the same expensive job; and then a lot of them only are interested in a small part of the result, e.g. ByteArrayToHexString(buffer).Substring(16, 8); so why convert everything?
If you insist on having a conversion, either perform it once and store the result, or only convert the part you're interested in (i.e. pass startIndex and Length to the conversion method).
4. As you are basically performing two jobs (display and storage) and missing 30% of the data, it must be hard to figure out exactly where it goes wrong when it does. So I would suggest you concentrate on one job until that works perfectly; then do the other job, and finally combine them.
I hope this helps; I do realize my suggestions may imply a lot of work, and the need for a lot more code.
|
|
|
|
|
Hello,
Thank you for Reply.
- I am now changing my Approach from timers to threads. But i want to update my datagridview suppose at every second. So do i just Need to call datagridview thread in timer?
- I will store the result in string & then use same for Splitting. Basically i am sniffing protocol which have defined structure. So either i can use string Approach or i Need to read & check every Byte to match with my protocol structure. So to avoid this i am just converting them in to string & then Splitting in to substrings.
- I will follow same.
|
|
|
|
|
Hi again,
1. There is no such thing as "calling a thread". Every thread is running all the time, provided it isn't blocked and sufficient CPU resources are available. Thread code often consists of one big loop performing some calculations and then either waiting (=being blocked on some object, say a WaitHandle) or just testing for more work (=polling). When polling, make sure not to have it spin all the time, which means when no job is available, block it for at least a fraction of a second (e.g. with a Thread.Sleep). Best is to use an event-driven approach though.
2. A WinForms Control will try and repaint itself as soon as there is a need for that, e.g. when you scroll it, your code adds/modifies data to it, etc. You can request a repaint by calling its Invalidate() method, which does not guarantee an immediate repaint, it merely queues a request. If you insist on having a periodic repaint, just use a Windows.Forms.Timer and in its Tick handler just do myDGV.Invalidate() ; However, a list Control that gets an item added does not need an explicit Invalidate, it will know a repaint is required all by itself.
3. A DataGridView is a complex and expensive Control, that may require a lot of CPU cycles. If all you need is a way to look at some data, without lots of user interaction, sorting, and the like, I would recommend you use a ListBox instead. And assuming you'll have hundreds of items in it, I would suggest you make it hold your byte arrays, not strings; ListBoxes indeed hold items, not just strings, and allocate a rectangular area for displaying each of those items. If you make it userdrawn (myLB.DrawMode = DrawMode.OwnerDrawFixed; ), and provide a DrawItem handler, you can actually paint whatever you want it to paint inside its rectangle; that allows you to create very inexpensive columns and backgrounds. Finally setting myLB.TopIndex=myLB.Items.Count-1; each time you add an item to it will ensure your ListBox keeps scrolling up automatically.
The nice thing about this approach is you only spend CPU resources to rows that are actually visible, all rows that are off-screen or otherwise invisible will not have their DrawItem event firing.
If all this is new to you, I suggest you read up on ListBox, and maybe this could be a good example.
|
|
|
|
|
Hello,
Thank you for Information. I will go thrigh it.
Meanwhile i was checking my Code with Debugger & i found that before completely reading whole buffer, my Byte Array is taking new Bytes due to which i am losing data.
So somwthing is missing or wrong in this Loop:
private void DoUpdate(object s,EventArgs e)
{<br />
/Read Data coming from ComPort Byte by Byte &store in the buffer/
int Bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[Bytes];
serialPort1.Read(buffer, 0, buffer.Length);
<pre>
result = ByteArrayToHexString(buffer);
for (int i = 0; i <= buffer.Length; i++)
{
processData();
return;
}
}</pre>
I tried using while Loop- (Read==buffer.length) but ist not giving me desired Output. Rather ist copying same data again & again.
I am updating my datagridview in processData().
|
|
|
|
|
Hi,
1. the Visual Studio Debugger isn't very good at dealing with real-time applications, when you set breakpoints and are single-stepping, the whole timing of your code is ruined.
I recommend you use logging instead, please read my article: A simple logging scheme[^].
2. I found a better example for userdrawn listboxes: my article: Asynchronous operations run on ThreadPool threads[^]. The topic itself of that article should be of interest to you too.
3. There might be an issue of the DataReceived handler not always executing on the same thread, and hence, one handler execution possibly overlapping a previous one. That too is touched on in the latter article.
4. As far as your latest code goes, you just can't call processData(); for each and every byte; it is bound to include a task switch (some Invoke or BeginInvoke) and Windows cannot possibly be switching threads at the same pace as your serial data bytes are coming in.
5. It might be useful to tweak the data source for now (if doable), so predictable data is being generated e.g. numbered packets containing a fixed number of incrementing byte values; in my experience that facilitates the debugging a lot as any deviation at the reception side would be noticed quite easily.
In summary, I urge you to rely on logging; to include the thread number in every log message (and check they are acceptable); to have a log message at the start and the end of the DataReceived handler (and more); and to be fully aware of your CPU load. And please drop the DGV, just get the reception of your data solved without wasting time in displaying it; when that works, start solving the display problem, at best with a ListBox.
|
|
|
|
|
So I'm storing some images in a file. I get the bytes, and convert the bytes to a Base64 string, that I place in a model that I return as Json.
At first everything was working fine with test images. Then I started using the customer images and pictures off my iPhone 6 and that's where the trouble began.
I get this parser error on the JQuery side, in which I isolated down to the Base64 string of the image.
So I have some bad chars that need to be formatted or converted.
I'm lost here ....
I have the replace statements that I added, but still get the error.
I think the pad right is not required.
I took the plain base64 string and pasted it into Best Online Base64 to Image converter and the image rendered fine.
I searched for JSON encoding, and got the replace chars.
Any point in the right direction would be appreciated.
picture.Base64 is a string
picture.Data is byte[]
public async Task<JsonResult> json_load_portfolio_picture(int PictureID, string PictureName)
{
model_portfolio_image picture = io_portfolio_images.Load_Portfolio_Picture(PictureID);
if (picture != null )
{
picture.Base64 = Convert.ToBase64String(picture.Data, 0, picture.Data.Length).Replace("/", "-").Replace("+", "_").Replace("=", "");
picture.Base64 = picture.Base64.PadRight(picture.Base64.Length + (4 - picture.Base64.Length % 4) % 4, '=');
}
await Task.Delay(1);
return Json(picture, JsonRequestBehavior.AllowGet);
}
If it ain't broke don't fix it
|
|
|
|
|
Well I had a number of issues that just compounded the problem.
First after I posted the page back with the wrong picture data ( A picture in which I used JavaScript to capture page form data and just converted the selected image to a base64 string and stuffed it in a textbox to postback later), I used the wrong data or bytes to store the image in the database (The original and not the copy). I should of used the bytes from the new Graphic after resizing. This got rid of the iPhone data (EXIF stuff) that was in the image stream. So now my Base64 string starts with that
iVBOR instead of
/9
After that, I searched everywhere on how to UTF8 a Base64 string and could not find anything on the subject. So I created a new JsonResult and set the max limit, content type and encoding and returned that object instead.
[HttpPost]
public async Task<JsonResult> json_load_portfolio_picture(int PictureID, string PictureName)
{
model_portfolio_image picture = io_portfolio_images.Load_Portfolio_Picture(PictureID);
if (picture != null)<br />
picture.Base64 = Convert.ToBase64String(picture.Data, Base64FormattingOptions.None).Trim();
JsonResult jResult = new JsonResult()
{
Data = picture,
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
ContentEncoding = Encoding.UTF8,
MaxJsonLength = 50000000,
ContentType = "application/json"
};
await Task.Delay(1);
return jResult;
}
If it ain't broke don't fix it
|
|
|
|
|