我尝试使用MSDN中的这个Converting between RTF and HTML库将一些RTF文本转换为HTML。我的设置的主旨是从JavaScript到C#处理程序的AJAX调用,它调用此MarkupConverter
库来进行转换,然后回写HTML。
这是我的JavaScript:
$.ajax({
type: "POST",
url: "MyHandler.ashx",
data: richTextData,
success: function (html) {
alert('success, html: ' + html);
},
error: function (msg) {
alert("error: " + msg);
}
});
来自我的处理程序的代码,这也非常简单:
public void ProcessRequest(HttpContext context)
{
if (context.Request.Form.Count > 0)
{
string rtf = context.Request.Form[0];
string html = "";
if (rtf != "")
{
markupConverter = new MarkupConverter.MarkupConverter();
html = markupConverter.ConvertRtfToHtml(rtf);
}
if (html != "")
{
context.Response.ContentType = "text/html";
context.Response.Write(html);
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("Error from RTF2HTML");
}
}
}
问题是,每次运行时都会抛出异常,因为RichTextBox
控件是在后台线程上创建的:
[InvalidOperationException:调用线程必须是STA,因为 许多UI组件都需要这个。]
System.Windows.Input.InputManager..ctor()+11032206
System.Windows.Input.InputManager.GetCurrentInputManagerImpl()+125
System.Windows.Input.KeyboardNavigation..ctor()+ 185 System.Windows.FrameworkElement.EnsureFrameworkServices()+ 109 ch System.Windows.FrameworkElement..ctor()+504
System.Windows.Controls.Control..ctor()+87
System.Windows.Controls.RichTextBox..ctor(FlowDocument document)+56
MarkupConverter.RtfToHtmlConverter.ConvertRtfToXaml(String rtfText) +67 MarkupConverter.RtfToHtmlConverter.ConvertRtfToHtml(String rtfText)+23 MyHandler.ProcessRequest(HttpContext context)+416
我想也许是因为AJAX调用是异步的,调用会放在后台线程上。所以我改成了这个:
var postText = $.ajax({
type: "POST",
url: "RTF2HTML.ashx",
data: textData,
async: false
}).responseText;
alert(postText);
但是当我在我的处理程序中检查当前线程时仍然是这样:
context.Response.Write("thread: " + System.Threading.Thread.CurrentThread.GetApartmentState().ToString());
它仍然返回MTA。
有没有办法挂钩主STA线程,还是我必须创建一个新线程并指定STA?如果是这种情况,我如何设置回调函数以Response.Write
目前的方式返回我的HTML?
答案 0 :(得分:3)
这可能有用:
How to run something in the STA thread?
也许你可以打电话给......
html = markupConverter.ConvertRtfToHtml(rtf);
...以同样的方式在另一个线程上?
string rtf;
public void ProcessRequest(HttpContext context)
{
if (context.Request.Form.Count > 0)
{
rtf = context.Request.Form[0];
string html = "";
if (rtf != "")
{
Thread thread = new Thread(ConvertMarkup);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
if (html != "")
{
context.Response.ContentType = "text/html";
context.Response.Write(html);
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("Error from RTF2HTML");
}
}
}
void ConvertMarkup()
{
markupConverter = new MarkupConverter.MarkupConverter();
html = markupConverter.ConvertRtfToHtml(rtf);
}
答案 1 :(得分:0)
using System.Threading;
Thread t = new Thread(new ThreadStart(ProcessRequest));
// Make sure to set the apartment state BEFORE starting the thread.
t.ApartmentState = ApartmentState.STA;
t.Start();
public void ProcessRequest(HttpContext context)
{
if (context.Request.Form.Count > 0)
{
string rtf = context.Request.Form[0];
string html = "";
if (rtf != "")
{
markupConverter = new MarkupConverter.MarkupConverter();
html = markupConverter.ConvertRtfToHtml(rtf);
}
if (html != "")
{
context.Response.ContentType = "text/html";
context.Response.Write(html);
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("Error from RTF2HTML");
}
}
}