SpringMVC: Serving XHTML - xhtml

I have a annotated spring-mvc controller which gives some data to a jsp-view.
#RequestMapping(method = RequestMethod.GET)
public ModelAndView editor(){
ModelAndView model = new ModelAndView("editor");
model.addObject("profile", "default");
model.addObject("extString", "[]");
return model;
}
Now, in my application before which worked with classic http-servlets I added this to the responds:
response.setContentType("application/xhtml+xml");
Spring-MVC seems to deliver the content in plan old html. So my web-side has a mayor problem. I didn't find a solution for this on the web.
Help please!

On your jsp, you could put something like this on top:
<%# page language="java" contentType="application/xhtml+xml; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>

Related

Getting context path in a tag library

is it possible to get the context path in a class extending SimpleTagSupport?
or is it actually necessary to pass it as a parameter to my tag?
Try this :
ServletContext servletContext = ((PageContext) getJspContext()).getServletContext();
String appContext = servletContext.getContextPath();
I hope this will help you. In jsp view files
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>

ASP.Net Calling Site.Master method from web page not working

I saw on several web pages how to interface to a public method defined in a master file from a web page call behind code that uses that master file.
(I am using ASP.Net 4.0 on Visual Studio 2012.)
The procedure is (copied from article):
Make sure the function is accessible to the page (i.e. declared
public), and use the MasterType declaration in the ContentPage:
<%# Page .... %>
<%# MasterType VirtualPath="~/masterpage.master" %>
In the page, use Page.Master.MyFunction() to access the function.
*Note: before being able to access the function, you'll need to save & build.
The problem is that I do not see the method. Here is what I have:
Web Page (stored in /MyFolder, so /MyFolder):
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Logout.aspx.cs" Inherits="BvCorpMain.Candidates.Logout" %>
<%# MasterType VirtualPath="/SiteMasters/Site.Master" %>
Site.Master CS file (stored in /SiteMasters folder):
public void UpdateUserBlocksToCookie()
{
}
When I go into the code behind for the logout page and in a method I type in "Page.Master.", I do not see my method.
Your page is inheriting from System.Web.UI.Page, which only knows that its master page is of type System.Web.UI.MasterPage. If you are making modifications to a child class of MasterPage, then you need to cast the Page.Master property to your child class.
public class MyPage : System.Web.UI.Page
{
public new MyMaster Master { get { return base.Master as MyMaster; } }
public void Page_Load(object sender, EventArgs e)
{
Master.MyMasterPageFunction();
}
}
public class MyMaster : System.Web.UI.MasterPage
{
public void MyMasterPageFunction()
{
}
}
The previous answer did educate me, however I believe the resolution was to restart VS2012, maybe cleaning the solution and rebuilding did not hurt. Either way.
Microsoft adds in the following code automatically to the .aspx.designer.cs file.
/// <summary>
/// Master property.
/// </summary>
/// <remarks>
/// Auto-generated property.
/// </remarks>
public new MyNamespace.Site Master {
get {
return ((BvCorpMain.Site)(base.Master));
}
The previous answer conflicts with this definition. Also, the previous answer of MyMaster, although granting access does not give (automatically at least) to needed form information. I checked. Using the existing master file is the cleanest.
The definition for the master.cs file is:
namespace MyNamespace
{
public partial class Site : System.Web.UI.MasterPage
As you can see, Microsoft did give access to MyNamespace.Site, which is what I needed, with "Master.".
I did not think to check the .aspx.designer.cs file for that definition, when I was having the problems. Possibly the definition was lacking and got added later, when either I rebuilt or did a save, which I had previously done, or whatever.
Knowing the addition does simplify things, as I can add that in manually if it does not exist using that construct.

Is there a way to access an object defined on a view in a Master Page in ASP.Net MVC

So I've got a partial in my MVC project that creates a JSON array. I want to move this chuck of code from the top of the html page body to the bottom with the rest of the JS for speed reasons. That is to say I want to store the JSON created as a string in C# and access it on the Site.Master.
What's the best option here?
Thanks,
Denis
When I need to access information in my MasterPage I create a BaseController and set the information in my ViewData :
public abstract class BaseController : Controller
{
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
ViewData["JSonObject"] = "json string";
}
}
Just have to inherit all controller from BaseController and it will work.
All views including MasterPage can access ViewData["JSonObject"] now!
Just call RenderPartial in the MasterPage
Use ViewData to pass information around between the views.
In your partial:
ViewData["JsonString"] = ".....";
In the master page:
<%= ViewData[ "JsonString" ] %>
Seems that ViewData is Top down only. So if you assign a value in the partials parent or a controller that'll work but not the other way round. I managed to get it working using Context.Item
Context.Items["JSONFeatures"] = "test"; on Partial
Context.Items["JSONFeatures"].ToString(); on MasterPage
Hope this helps someone. I'm not sure if this is best practices but it works it I know better!

What are some of the strategy to handle unhandled exception in asp.net mvc applications?

I would like to know some of the strategy/practice you deal with to handle unhandled exceptions in ASP.NET MVC.
In short I want to avoid the yellow screen whenever any error happens and show a error consistent error message to the visitor.
I mean do you write a controller for this which shows the appropriate error page or you go some other way like writing an httpmodule and trapping the error at a global level.
Any inputs in this direction is appreciated.
Using the HandleError attribute is the way to go. Here is a small sample which I use to handle Ajax calls from JQuery, ExtJs, and others.
On your controller
public class DataController : Controller
{
[HandleError(ExceptionType = typeof(ArgumentException), View = "ErrorAjax")]
public void Foo(string x, string y)
{
if (String.IsNullorEmpty(x))
throw new ArgumentException("String cannot be empty!");
// Call your layers or whatever here
AnotherCall();
}
}
Then on your view (ErrorAjax). Notice it's strongly typed (HandleErrorInfo)
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<HandleErrorInfo>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Sorry Dude!</title>
</head>
<body>
<div>
<!-- be creative here-->
Sorry, an error occurred while processing your request.
Action = <%= ViewData.Model.ActionName %>
Controller = <%= ViewData.Model.ControllerName %>
Message = <%= ViewData.Model.Exception.Message %>
</div>
</body>
</html>
A couple of gotchas
Check your web.config and make sure customErrors mode="On"
For starters, create the View under the Shared folder
Try the HandleError attribute.
Don't use the exception handling article that you linked to. It's an old article where they didn't have the HandleError attribute added in the framework. Use the HandleError attribute. It was added in preview 4.

Alternative Query String C# (asp.net)

Is there a quick and dirty way of using a query passed as follows:
domain.com/mypage.aspx/product/toycar/
I've done it before in PHP, but this needs to be done in page (in this instance).
--
I only have access to the aspx page and code behind, and have to work in asp.net 2 (i wish i was using 3.5)
quick and dirty:
public class ModuleRewriter : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
}
private void Application_BeginRequest(Object source, EventArgs e)
{
// The url will look like: http://domain.com/mypage.aspx/product/toycar/
// The module will rewrite it to: http://domain.com/mypage.aspx?product=toycar
HttpApplication application = source as HttpApplication;
string[] urlInfo = application.Request.RawUrl.ToString().Split('/');
if (urlInfo.Length > 2)
{
string page = urlInfo[urlInfo.Length - 3];
string action = urlInfo[urlInfo.Length - 2];
string id = urlInfo[urlInfo.Length - 1];
if (string.IsNullOrEmpty(page))
{
page = "default.aspx";
}
application.Server.Transfer(string.Format(
"~/{0}?{1}={2}", page, action, id));
}
}
public void Dispose()
{
}
}
web.config:
<httpModules>
<add name="ModuleRewriter" type="ModuleRewriter, MyWebApplication"/>
</httpModules>
and a test page:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<%= Request["product"] %>
</div>
</form>
</body>
</html>
You might want to look into the ASP.NET System.Web.Routing namespace, which was added in .NET 3.5 SP1 I believe:
http://blogs.msdn.com/mikeormond/archive/2008/05/14/using-asp-net-routing-independent-of-mvc.aspx
http://msdn.microsoft.com/en-us/library/system.web.routing.aspx
You'd be able to get rid of the .aspx extension too.
This would involve making a custom HTTP Handler.
Check this
You've got a few options, but all of them require access to the web.config and a change to IIS to map all file extensions to the dotNet ISAPI dll:
Use MVC (like stackoverflow does,
notice the urls)
Use asp.net routing (new in 3.5)
Write your own http handler Massive guide from Microsoft here
Use the excellent urlrewriting.net which does just about everything perfectly including getting round some awkward authentication and image path problems.
Personally I used urlrewriting.net with good results.
Since you mention you don't have access to anything but the code behind and the page, the only thing I can think of is actually creating those dirs (if you have access to do that) and using a server.transfer page passing the value to your actual page in the folder above. Messy, but if you can't access the other stuff, your choices are limited.
In case you just want to read the path from within your .aspx:
Request.ServerVariables["PATH_INFO"]
To clarify:
he has only access to the aspx (+ codebehind) itself, so he must know how the query is, but it is not in the Request.QueryString because of the format. So the only way then is Request.ServerVariables["PATH_INFO"] (Request.RawUrl)

Resources