By Juan Carlos Pazos - 7/25/2008
Hi
I use the RichTextBox control in one form, is bounded to a nvarchar(max) field by the BO. The property is set to RFT.
Works great with text, but for testing I add a picture to the RTF, this because the also have a RichTextBoxToolStrip tah has an Image insert function.
The image is added corrctly and can be showed without problems, but if I try to delete the image or make any chaneg to the text I get this error:
BusinessLayerException
An error occurred while saving an the data to the server.
DataLayerSavingException
String or binary data would be truncated.
The statement has been terminated.
SqlException
String or binary data would be truncated.
The statement has been terminated.
Source : MicroFour StrataFrame Business
Stack Trace:
en System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
en System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
en System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
en System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
en System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
en System.Data.SqlClient.SqlDataReader.get_MetaData()
en System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
en System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
en System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
en System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
en System.Data.Common.DbCommand.ExecuteReader()
en MicroFour.StrataFrame.Data.DbDataSourceItem.InternalExecuteReader(DbCommand Command, Boolean IsTransactional, String TransactionKey)
en MicroFour.StrataFrame.Data.SqlDataSourceItem.UpdateRow(QueryInformation QueryInfo, DataRow RowToUpdate, ConcurrencyExceptionHandler ConcurrencyHandler, AddRowErrorHandler RowErrorHandler, Boolean RecreateCommand)
en MicroFour.StrataFrame.Data.DbDataSourceItem.UpdateRow(QueryInformation QueryInfo, DataRow RowToUpdate, ConcurrencyExceptionHandler ConcurrencyHandler, AddRowErrorHandler RowErrorHandler)
en MicroFour.StrataFrame.Data.DataLayer.UpdateDataTableThread(Object ThreadParams)
en MicroFour.StrataFrame.Data.DataLayer.UpdateDataTable(DataTable TableToUpdate, Boolean Transactional, String TransactionKey)
en MicroFour.StrataFrame.Data.DataLayer.SaveByForm(DataTable TableToSave, Boolean Transactional, String TransactionKey)
en MicroFour.StrataFrame.Business.BusinessLayer.SaveByForm(Boolean Transactional, String TransactionKey)
en MicroFour.StrataFrame.UI.Windows.Forms.BaseForm.Save(Boolean Transactional, String TransactionKey)
en MicroFour.StrataFrame.UI.Windows.Forms.BaseForm.Save()
en MicroFour.StrataFrame.UI.Windows.Forms.MaintenanceFormToolStrip.cmdSave_Click(Object sender, EventArgs e)
en System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
en System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
en System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
en System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
en System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
en System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
en System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
en System.Windows.Forms.Control.WndProc(Message& m)
en System.Windows.Forms.ScrollableControl.WndProc(Message& m)
en System.Windows.Forms.ToolStrip.WndProc(Message& m)
en System.Windows.Forms.Control.ControlNativewindow.OnMessage(Message& m)
en System.Windows.Forms.Control.ControlNativewindow.WndProc(Message& m)
en System.Windows.Forms.Nativewindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Hope you can help me in how to use this?
Regards
|
By Trent L. Taylor - 7/26/2008
Hmmm....the message that is occuring has nothing to do with the image, but rather the size of the text being saved back to the server and what the SQL things is the size limit of the field. First, what version of the framework are you running? Second, ensure that your field is properly setup and mapped and you may want to place the Data source in debug mode so that you can actually see exactly what is going back to the server: MicroFour.StrataFrame.Data.DataBasics.DataSources("").SetDebugOn(...)
|
By Juan Carlos Pazos - 7/27/2008
Hi TrentI'm using last version 1.6.5.3 of StrataFreme. The field is VarCharMax. And in the form is value is RTF. I read in other place that if a RTF is going to have images, should be BinaryMax the field, is this correct? Regards
|
By Trent L. Taylor - 7/28/2008
I read in other place that if a RTF is going to have images, should be BinaryMax the field, is this correct? Well, that would be the first thing you might try. It is possible that the image being inserted is causing the issue. You might try and insert a small test image (other than the one you have been inserting) and see if the problem persists. Really, you should be able to use an NVarChar(MAX) field as the binary data is placed into a Unicode format when saving. So NVarChar(MAX) should work and is in fact what we use (and images work ). Try placing the data source in debug mode as mentioned above and see if you can tell if there is something going on with the UPDATE.
|
By Ralph Rutschmann - 7/29/2008
Hello,could it have something to do with how the 'UpdateConcurrencyType' at the BO is set? If I recall it correctly, using 'OptimisticAllFields' would lead to this type of error. I hope, my guess is right? Friendly greetings, Ralph
|
By Trent L. Taylor - 7/30/2008
That is a good suggestion and could very well cause a problem. Good thinking, Ralph!Ralphs is talking about how StrataFrame manages concurrency exceptions by default. So if you are using the AllFieldsOptimistic (by default this is the settings) then you could get this error. You would want to use a Row Version or Time Stamp for concurrency checking instead.
|
By Juan Carlos Pazos - 7/30/2008
Ralph, TrentThanks, changing the concurrency type all works without problems. Regards
|
By Juan Carlos Pazos - 8/4/2008
Ralph, Trent
Thanks, changing the concurrency type to RowVersion or TimeStamp let save and remove images from the RichTextBoxField.
I take a look about this but as I does not have the experience to create code to manage concurrency for RowVersion or TimeStamp, I need let SF handles concurrency (the window that opens when a concurrency exception hapens is great), maybe in some time I can create code for handle the colisions.
So, I just hide from code the Image button in the RichTextBoxToolStrip and limit the characters to 40000 (the maximum number of characters that can be handled in concurrency optimistic).
Thanks a lot for your help.
|
By Greg McGuffey - 8/5/2008
Juan,
Handling concurrency is very easy. You need to do just a couple of things. Row version is easiest/fastest:
1. Add a column to each table that is a concurrency row version column. The column needs to be an int, be NOT NULL (doesn't allow nulls) and have a default of 0. You can do this in the SQL Server UI (Enterprise Manager or SQL Server Management Studio), in the DDT if you are using it or directly via scripts. Here is an example of the script you'd use.
Alter Table [dbo].[MyTable1]
Add RowVersionID [int] NOT NULL CONSTRAINT [DF_MyTable1_RowVersionID] DEFAULT (0)
where MyTable1 is the name of the table, RowVersionID is the name of the concurrency column (can be any name), and DF_MyTable1_RowVersionID is the name of the default constraint (can by any name).
2. Setup the BO. Open each BOs designer, set the UpdateConcurrencyType to OptimisticRowVersion and set the RowVersionOrTimeStampColumn to the name of the new column added in step 1 (RowVersionID in this example).
Done.
Note: if you're using sprocs, you have to change the sprocs to handle the concurrency also. That isn't too hard either.
Hope that helps!
|
By Juan Carlos Pazos - 8/5/2008
Greg
Thanks for the advise, I did that before, the "problem" is that SF has a nice Window that shows when a concurrrency colission takes place, but is only for Optimistic. I read the forum and found that I have to create my own Window to handle colissions if RowVersion or TimeStamp, tha's where I don't know how to do that.
I test the RowVersion and works great, in fact, many recomend use that type. But as I told you before I don't know howe to handle the colission. May be in some time or if I found some sample (SF samples are all in Optimistic) then I can change my application to use RowVersion.
Kindest regargs
|
By Dustin Taylor - 8/5/2008
Juan, Actually, you can use the standard StrataFrame soft collision form with row versioning or timestamps just fine. If I remember correctly it used to only work with OptomisticAllFields, but we changed it to work with all 3 standard methods a while back. Have you tried setting up a test with row versioning? If not I'd do that if you are running into issues. Isolating the concurrency handling into a little one form test app would probably be the easiest way to better understand how all of that works under the hood. If you run into any problems getting it set up, just give us a shout and we'll be happy to guide you through any rough spots .
|
By Juan Carlos Pazos - 8/5/2008
Hi Dustin
I did that test with the 1.6.5.3 (I use the beta of last month, the last two no, because I use DevExpress controls to the last version and there are not sources in the downloads section, for recompile).
After add a RowStamp column (integer) and setup the Nulls as needed and make this changes in the BO:
ColissionNotificationType: RaiseEvent
RowVersionOrTimeStampColumn: RowVersionColumn (the name of the column in my table)
UpdateConcurrencyType: OptimisticRowVersion
After that I run the app from VS 2008, goes to the form, enter in EditMode and change a value. Also run the exe from Debug directory (at the same time) goes to the form, in the same record also enter to edit mode and change the same value but with different information. The save the first one, and when save the second nothing happens (when doing this using the default concurrency, the Windows of SF comes up. If I close the form and reopen the record is updated to the value that was saved first.
Also I changed the ColissionNotificationType to ThrowException and make the same thing, and yes when I save form the second running application, it presents the error window. That's why I supose the SF only present the colission window for OptimisticAllFilds.
Sure I miss something, hope you can give me some ideas?
Regards
|
By Dustin Taylor - 8/5/2008
No problem, we'll get to the bottom of it First be sure that you open the second instance before you change the value, otherwise you aren't getting a collision detection. Based on it throwing the exception when you change the notification type, however, it sounds like you are doing that correctly. The only other thing to check is that the AutoHandleCollisions property of the Form is set to True, which is the flag that determines whether or not to show the soft collision form. If that appears to be set up correct, try reproducing the collision with the attached sample project. Just point it to your StrataFrameSample database when it asks you for connection information. It is configured to use row versioning and should display the soft collision form when you run it through the collision scenario. Let me know whether the test app works and we can go from there
|
By Juan Carlos Pazos - 8/5/2008
Dustin
Thanks for your help, ¡It's working now!
I go back and add the RowColumnID (Int, Not allow nulls), configure the BO and test my form and works. I think the problem the first time I did is that not define Not allow nulls, I use the BO Mapper to handle this, of course don't do it well.
Thanks a lot for your help.
Regards
|
By Dustin Taylor - 8/6/2008
No problem at all! Glad you got it working
|
|