TinyMCE Spellchecker in ASP .NET MVC - asp.net

I followed the tutorial described here, in order to make the TinyMCE Spellchecker work on a Webforms application. But I tried to do the very same thing on a MVC project and keep getting errors every time I try to use the spellchecker.
I'd like to know what changes or adjustments I need to make in order to make this word on an ASP .NET MVC project.
The error I'm getting is the following:
[HttpException]: The controller for path '/TinyMCE.ashx' could not be found or it does not implement
IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String
controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext)
at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute
()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Well its a bit hard to know what the problem is without knowing what the error you're getting is, but I'm guessing that its because you need to ignore the route to the spell checker in your MVC. Do this by adding something like this to your MVC route definitions:
//ignore just the TinyMCE spell checker service:
routes.IgnoreRoute("TinyMCE.ashx");
//or if you want to be more general & ignore all ashx's:
routes.IgnoreRoute("{resource}.ashx{*pathInfo}");
Without the above it would be interpreting the spellcheck request url (TinyMCE.ashx...) as an MVC route & try to find a matching Controller (& obviously fail).
If that's not the issue, I'd suggest posting some more info about the specific error you're seeing.

I'm pretty new to MVC (a little over a year) and was pretty interested in spell check for a specific page in my solution. The above options may work for some folks, but didn't work for me (I'm not very patient, and in all honesty didn't want to ignore any routes, or modify my the system.web section of my config for something that only 5% of my solution consumers are going to use, so I didn't spend a whole lot of time on those options).
So:
I copied the Moxiecode.TinyMCE.dll file to a directory in my project so future contributors will have the dll without having to search google.
I added a reference to the above dll to my project.
I created a new controller called SpellCheckController.cs that contains the following:
public void CheckSpelling()
{
SpellCheckerModule spellChecker = new SpellCheckerModule();
spellChecker.ProcessRequest(System.Web.HttpContext.Current);
}
(don't forget the using Moxiecode.TinyMCE.SpellChecker;)
and just referenced the controller like this in the setup options for TinyMCE in my view:
spellchecker_rpc_url: "#Url.Action("CheckSpelling","SpellCheck")/?module=SpellChecker"
I haven't ignored any routes. I haven't added another httphandler to the what I am assuming is a pretty long list of handlers for .net, and spell check works for me now.
I also have the ability to go with something different without changing too much (assuming I figure out what TinyMCE's spellchecker is doing with the http context.
P.S.
Stack Overflow's rich text editor doesn't seem to have a spell check feature, so there are no guaranties on the above spelling :)

Related

Rename AntiForgeryToken Hidden Input Name from __RequestVerificationToken

(Doing this to obfuscate ASP.NET MVC Framework in web app.)
Have renamed the cookie name with static AntiForgeryConfig class via Helpers in Application_Start.
Global.asax:
AntiForgeryConfig.CookieName = "Test";
But still obvious AntiForgeryToken is being used due to input name:
Front End:
<input name="__RequestVerificationToken" type="hidden" value="blahblahblah" />
Arguably the value smells of MVC with encoding but not really sure what to about this. (Different issue really but comments/other approaches welcomed and appreciated regardless.)
After checking the source code on CodePlex, it appears that this value is hard-coded as a constant. So there's no easy way of changing this value. You can see this here: http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/Helpers/AntiForgeryConfig.cs
I'm surprised it's not configurable. Anyways, it appears that what you want to do is not possible.
However, I advice you create a feature request on Codeplex and hope they will implement it.
Note: If you want to go really hardcore, you could always download the code and make the modification, but this will probably give you more problems than it solves.
The answer to this StackOverflow question should get you started.
Changing the input name is non-trivial. Both the Html.AntiForgeryToken helper and the ValidationAntiforgeryToken attribute rely on the input name being "__RequestVerificationToken". If you want it to be something else, you will need to drop down into using the AntiForgery API and create your own versions of both helper and attribute to validate against your chosen name.

best approach to implement getRealPath()

I am working on struts 2.0 . I am designing a web application.
I am using Jasper Report in my application. I want to access the *.jrxml files in my action class. I don't want to give hard coded path to the files. So to get the path dynamically I googled it and got the solution that I can get the path using getRealPath() method. But I found two implementation of doing this:
Using HttpSession to get object of ServletContext and using the getRealPath() method of the ServletContext object.
Like this:
HttpSession session = request.getSession();
String realPath = session.getServletContext().getRealPath("/");
The second approach to do it directly using the static method getServletContext() of ServletActionContext. And then we can get the real path of the application using the getRealPath() method.
Like this:
String realPath = ServletActionContext.getServletContext().getRealPath("/");
Please tell me, is there any difference between the above two and also please tell me whether there is any other way to get the path?
Neither is "better", really, and I'd argue that neither is particularly good, either.
I might try getting the context path in an initialization servlet and stick it into the application context, then make your action(s) ApplicationAware and retrieve the value from the map.
This has the added benefit of aiding testability and removing the static references in the action.
That said, I see zero reason to go through the extra mechanics of your first approach: it adds a lot of noise for no perceivable benefit; I'm not even sure why it wuld be considered.
I'd also be a little wary of tying your actions to a path like this unless there's a real need, what's the specific use? In general you shouldn't need to access intra-app resources by their path.

Strongly-Typed Route Testing

If I understand the example correctly, MvcContrib TestHelper has a strongly-typed test of a route mapping to a particular controller. The down-side is that again, if I understand the example, the route being tested does not come from the global.asax file; It instead comes from the test setup.
In contrast, the book "Pro ASP.NET MVC3 Framework" shares route-test helpers that actually do leverage the routes in the global.asax file. These helpers, however, are not strong typed (or even loose-typed) to a particular controller:
[TestMethod] //sample from the book...
public void TestIncomingRoutes() {     
// check for the URL that we hope to receive     
TestRouteMatch("~/Admin/Index", "Admin", "Index");
}
I'd like to have the best of both worlds. Has anyone a link to helper code that (1) expressly identifies a particular controller, (2) uses the routes in the global.asax for the tests and (3) is not married to Rhino Mocks - as I prefer MOQ.
Thanks.
It seems like you want to test your HttpApplication subclass (global.asax.cs code) to ensure it calls the code to register the routes. I'm not sure that's really necessary, as it will be pretty apparent that nothing works if you fail to do so. OTOH, the MvcContrib is allowing you to test that the URLs you want actually map to something, which has a lot of value if you've carefully designed your urls to be SEO friendly. That is worth testing, IMO.

Using embedded WebResources throughout Webresource.axd

The question's simple: how could one use embedded resources in asp.net applications? What are the steps to include a resource in the assembly, and how to reference it? What are the gotchas that could be encountered?
Edit: For a version without referencing Page and ClientScript, see What is the right way to handle Embedded Resources on a Razor View?
After spending a half of a day I've learned these:
to embed a resource one needs to set it's Build Action to Embedded Resource (in VS Solution Explorer rightclick the file -> Properties)
next AsssemblyInfo.vb must be modified to make this resources available for WebResource queries. Add [Assembly: System.Web.UI.WebResource("MyWebResourceProj.Test.css", "text/css")] to AssemblyInfo.vb located in MyProject folder of the project.
The name consists of root namespace/assembly name +'.'+filename. To be 100% sure of the name, use the following code snippet to look it up:
Dim resNames = Assembly.LoadFile("YourDll.dll").GetManifestResourceNames()
Note that the assembly's Root Namespace must be the same as the Assembly Name (this took me about 4 hours to realize. At least with .Net v4 that is the case)
If there are references inside the css ( <%=WebResource("NS.image.jpg")%> ) than pass PerformSubstitution:=true for that css's WebResource attribute.
Referencing the resource can be done with Page.ClientScript.GetWebResourceUrl(GetType(MyWebResourceProj.ConssumingPage), "MyWebResourceProj.Test.css")
Note that instead of GetType(Typename) one could use Me.GetType(), but again, that won't work if the class is inherited, so beware!
Resources:
Debugging ASP.NET 2.0 Web Resources: Decrypting the URL and Getting the Resource Name
Using embedded resources through WebResource.axd is a pain in the neck, as you can see from your own answer. You have to keep assemblyinfo.vb|cs in sync, and it always seems damn near impossible to get all the namespace & assembly names right in all the right places.
When you finally get it to work, your reward is an include script line that that looks like a core memory dump.
I suggest an alternative. Write yourself a very simple web handler (e.g. MyResourceLoader.ashx. Then add a method to your class that simply serves it's own embedded resources, in whatever way you think is meaningful. You can use reflection to get the classes, like WebResource does, or just hardcode whatever you need into your loader, if it's just for a specific purpose. A public method in your class might look like:
public static Stream GetResource(string resourceName) {
// get the resource from myself, which is easy and doesn't require
// anything in assemblyinfo, and return it as a stream. As a bonus,
// you can parse it dynamically or even return things that aren't
// just embedded, but generated completely in code!
}
Or if you decide to make something more general purpose, you can get all fancy and return more data using a class, e.g.
class ResourceInfo
{
public Stream Data;
public string MimeType;
public string FileName;
}
Now you have the ability to serve up your embedded resources any way you want, e.g.
<script language="javascript" src="/MyResourceLoader.ashx/MyControlScript.js">
I think MS made a mess of that WebResource business. Luckily its' pretty straightforward to do your own thing.

ASP.NET Localized web site -- updating on the fly

I think I have a solution to this, but is there a better way, or is this going to break on me?
I am constructing a localized web site using global/local resx files. It is a requirement that non-technical users can edit the strings and add new languages through the web app.
This seems easy enough -- I have a form to display strings and the changes are saved with code like this snippet:
string filename = MapPath("App_GlobalResources/strings.hu.resx");
XmlDocument xDoc = new XmlDocument();
XmlNode xNode;
xDoc.Load(filename);
xNode = xDoc.SelectSingleNode("//root/data[#name='PageTitle']/value");
xNode.InnerText = txtNewTitle.Text;
xDoc.Save(filename);
Is this going to cause problems on a busy site? If it causes a momentary delay for recompilation, that's no big deal. And realistically, this form won't see constant, heavy use. What does the community think?
I've used a similar method before for a very basic "CMS". The site wasn't massively used but it didn't cause me any problems.
I don't think changing a resx will cause a recycle.
We did something similar, but used a database to store the user modified values. We then provided a fallback mechanism to serve the overridden value of a localized key.
That said, I think your method should work fine.
Have you considered creating a Resource object? You would need to wrap your settings into a single object that all the client code would use. Something like:
public class GuiResources
{
public string PageTitle
{
get return _pageTitle;
}
// Fired once when the class is first created.
void LoadConfiguration()
{
// Load settings from config section
_pageTitle = // Value from config
}
}
You could make it a singleton or a provider, that way the object is loaded only one time. Also you could make it smart to look at the current thread to get the culture info so you know what language to return.
Then in your web.config file you can create a custom section and set restartOnExternalChanges="true". That way, your app will get the changed when they are made.

Resources