Umbraco - Check if request is XmlHttpRequest - asp.net

I'm doing an AJAX feature for my Umbraco website.
Basically what I'm trying to do is when someone requests for http://mysite.com/news with the XmlHttpRequest header then I want Umbraco to return JSON of the following page.
What I've been trying to do is finding the right place to check for the header in Umbraco. Basically I want to override or inherit some class where I could check the header and return the page in Json or HTML depending on the header.
I'm using Umbraco 4.7.0 (1.0.4090.21631)
Any feedback would be more than welcome! Thanks!

I'd probably use the URL Rewriting module for IIS7 to detect the content-type in the request, then redirect to the same URL with /jsonTemplate on the end of it. You would then create a masterpage called jsonTemplate, with a single macro inside it, which would return your JSON.
This is common for Umbraco - specifying a separate template with a separate macro to return a different view of the same content. Check out http://blog4umbraco.codeplex.com/SourceControl/changeset/view/68424#1138733 for an example of an XSLT macro that returns RSS using this approach.

You should check the Content-Type header from server side logic. Your Javascript should be specifying a Content-Type like application/json.

Related

HTTP Cache: multiple URLs point to the same HTML file

There are times when multiple URLs point to the same HTML file.
For example, the classic use of the base tag
For example the main page can be in:
https://dom.com/schops/
but the following URLs also direct to that file:
https://dom.com/shops/mark1
https://dom.com/shops/mark1/products
https://dom.com/shops/mark3
My question is, is there a HTTP cache header or a way to mark that a URL actually has another source URL?
How do you usually solve this problem?
Anyway I am creating my implementation in Cache Storge API, but I would like its behavior to be similar to the standard using the necessary headers when appropriate.

ASP.Net WebAPI MediaTypeMapping using Body Content

Is it possible (or sensible) to build a custom MediaTypeMapping to select a MediaTypeFormatter based on content from the Request Body?
I'm thinking specifically of a case where I have a very non-descriptive text/plain in a multipart/form-data payload and I want to use heuristics to work out what's contained.
I'm currently doing this in a custom MediaTypeFormatter that looks at the first few lines, and if the content begins with { then it assumes JSON, if it's word,word,word the the commas indicate CSV.
I was thinking that a MediaTypeMapping would be cleaner but I don't know if it's sensible to try and match from the Body content.
Currently there is no way you can really Inspect content in Webapi. You can not read the stream more than once.

.NET MVC3: Prevent 404 for missing CSS files? Or ensure files exist before writing HTML?

We have a requirement to provide skinning capabilities to an ASP.NET MVC3 app.
My approach so far has been to tackle this with a cookie and child actions for the css files:
Client links to our app using a URL like www.ourapp.com/as/www.clientapp.com/then-go-to/path/in/ourapp.
The above url is routed to an action method that writes a cookie named "skin" with value "www.clientapp.com" and then redirects to /path/in/ourapp.
Our layout (masterpage) has an #Html.Action in the <head> section where the css files are to be rendered.
The child action inspects the cookie and creates a viewmodel that will tell the partial view which <link> tags to render.
The css file structure is based on the cookie value. So our css content might look like this:
/content
/www.clientapp.com
/style1.css
/style1.css
/www.client2app.com
/style1.css
/style2.css
I am open to hearing better patterns / alternatives to the above for applying skins to the layout. However this isn't the reason for my question.
There is currently a problem with this approach when the css files are not present in the filesystem. The request causes IIS to return a 404. We override the 404 page with a custom page (not using the same layout that has the #Html.Action in the <head>). This causes IIS to do some additional processing which is not necessary (for example partials & child actions to render sign-in/sign out links, horizontal nav, etc, on the 404 page's layout).
The way I see it there are 2 ways to solve this:
In the child action that configures the css, check to make sure the files exist on disk before telling the viewmodel that they should be rendered. Pro with this approach is that it should be fairly easy. Cons are that to unit test it, would have to wrap file I/O in a service that can be injected. Also the app will be deployed to Azure. I think Azure can read the filesystem (which is what would be needed), but not write to it.
Somehow prevent a 404 from being returned for css files. To do this, would we have to implement logic in global.asax Application_Error? Or is there another way to prevent missing CSS files from triggering a 404 response?
Which approach is correct? Or is there another that I'm not considering?
Update
We ended up solving this in the custom 404 error page like so:
[ActionName("not-found")]
public virtual ActionResult NotFound()
{
// do not return 404 for missing css files
if (Request.RawUrl.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
{
Response.StatusCode = 404;
return new EmptyResult();
}
return View();
}
One option would be to not override 404 errors for CSS requests.
For missing CSS files, return the 404 status, but leave the body empty. The body doesn't matter with a CSS file, since a human doesn't see it, and all the browser cares about is the status.

Disable Cache-Control Header field in custom ASP.NET HttpHandler response

How can I completely supress the output of the Cache-Control Header that is returned by my custom HttpHandler in ASP.NET?
I know, I can change the header field by modifying response.Cache and response.Cache.SetCacheability, but that will only change the header field, not remove it. That is not what I want. I completely want to make no assumptions about the Cache-Control field and leave it up to the browsers policy.
EDIT: The same holds true for HttpResponse.Charset. If no charset is set, ASP.NET will always set it to "utf-8", although returning a header "Content-Type: text/html" without the charset parameter is perfectly valid html. Any idea how to supress the charset, too?
You can remove header values using
HttpContext.Current.Response.Headers.Remove("HEADER-VALUE-HERE");
If you are using a IIS7 integrated pipeline, however some header values are protected and cannot be removed (i.e they are injected after the response is dealt with on the most common page lifecycles).
What you can do if the above fails (ie its protected) is you can make a module to manually hook into the PreSendRequestHeaders and use the code above to remove the header at this point.
The majority of problems removing the header is not the inabillity to remove it, its to remove it at the correct time.
I believe using a custom http handler you should be able to remove it at the instantiation of the handler though.
I'm only guessing here, but I would think that this is configured within IIS -- on the website (or virtual directory)'s Properties dialog, there is a section called "Enable content expiration". Does unticking this box suppress the header?
If you don't have access to your IIS Manager, then I'm afraid I am not sure how you could suppress that header. Looking at the docs, response.Headers is a read-only property, so setting it to an empty string isn't going to work...

How do I determine if an asp.net url has been "rewritten"?

I'm using http://urlrewriter.net/ to rewrite urls at my website. For example, I'm rewriting:
http://www.example.com/schedule.aspx?state=ca
to
http://www.example.com/california.aspx
What I'm trying to do (for SEO purposes) to to dynamically add the meta tag:
<meta name="robots" content="noindex,follow" />
only to the page that hasn't been rewritten. This is because I want both URLs to work, but only the rewritten one to be indexed by search engines.
How do I determine which version of the page has been requested?
EDIT
Answers below suggest a 301 redirect instead of using a meta tag. Maybe I'll do this, but I still want to know the answer to the underlying question... how do I know if the page has been rewritten?
personally, I would 301 redirect from the un-rewritten one to the re-written one, and only use the single copy of the page. It is easier for users, and from an SEO perspective, you have 1 copy of the content.
If you need to do this you can probably do something like:
<add header="X-WasRewritten" value="true" />
And you can check for the header in your view and add the robots meta tag if you need it.
This will get returned to the client too, so if you want to hide that you can write a CustomAction (http://urlrewriter.net/index.php/support/reference/actions/custom-action) which will set some kind of state value in your request.
However, having two URIs for the same resource is something I would not recommend. I suggest you just keep the one representation. If you're worried about invalidating old bookmarks you can set the old one to redirect to the new one.
Further to chakrit's answer, it looks like UrlRewriter.NET stores the original URL in the HttpContext, in a key called UrlRewriter.NET.RawUrl. So, you could try something like:
bool isPageRewritten =
!string.IsNullOrEmpty(HttpContext.Current.Items["UrlRewriter.NET.RawUrl"]);
Most obvious method is to use the Request.Url object in your page to get information about the URL and query string. For example:
if (Path.GetFileName(Request.Url.FilePath) == "schedule.aspx")
//Not rewritten
else
//rewritten
I think that's the job of HttpContext.Current.Items.
You can save the "Redirection" in HttpContext.Current.Items and then in your pages, you can check it for a certain added value.
I believe you can add hooks to urlrewriter.net that could do it, something alongs:
HttpContext.Current.Items["Redirected_From"] = currentUrlHere;
And then in your webpages, you could check it by:
if (!string.IsNullOrEmpty(HttpContext.Current.Items["Redirected_From"]))
// the page's been redirected, do something!
else
// no it's visited normally.
I have long since left it for the ASP.NET Routing framework in .NET 3.5 SP1, it is better than urlrewriter.net IMO.

Resources