I am new at the forum and also pretty new to MVC.
I have an MVC app which runs OK while tested on my local development environment, but when deployed on IIS7 I am having some issues, one of it is that I get a 404 error when invoking an action from a controller passing parameters in the querystring, the "?" and "=" are encoded by IIS and I guess that's the reason why it is failing the call.
My controller action:
public ActionResult CreateMenu()
{
MenuModel.MenuItem menuItem;
MenuModel.MenuItem childItem;
if (AuthenticationService.IsUserAuthenticated())
{
string u_id = AuthenticationService.GetAuthenticatedUserName();
Role u_role = Repository.GetUserRole(u_id);
mainMenu.MenuItems.RemoveAt(0);
if ((u_role.Role_Desc == "Administrator") || (u_role.Role_Desc == "Manager"))
{
int lastMenuNumber = mainMenu.MenuItems.Count;
menuItem = new MenuModel.MenuItem(++lastMenuNumber, "Account Settings", "", "");
childItem = new MenuModel.MenuItem(++lastMenuNumber, "Log Report", "LogReporting", "ShowLog");
menuItem.ChildItems.Add(childItem);
childItem = new MenuModel.MenuItem(++lastMenuNumber, "User Permissions", "PermissionsSetting", "ListPermissions");
menuItem.ChildItems.Add(childItem);
mainMenu.MenuItems.Insert(0, menuItem);
}
// list of accessible BGs for selected client
var selectedClient = Session["client_Id"] != null ?
Repository.GetClientById((short)Session["client_Id"]) :
Repository.GetUserClients(u_id).First();
int i = 0;
var bgs = Repository.GetUserClientAccesibleBusinessGroups(u_id, selectedClient.Client_ID);
if (bgs.Count() > 0)
{
foreach (var bg in bgs)
{
menuItem = new MenuModel.MenuItem(mainMenu.MenuItems.Count + 1, bg.BG_Desc, "FtpAccess", String.Format("Group/{0}?cbg={1}", selectedClient.Client_ID, bg.Client_BG_ID));
mainMenu.MenuItems.Insert(i++, menuItem);
}
}
}
ViewData.Model = mainMenu;
return View();
}
This is used in a partial view <% Html.RenderAction("CreateMenu", "Menu"); %> on the master view, which is rendered correctly, but when click on an item, the result is the 404 error.
One thing that I changed on the web.config was the settings for:
requestValidationMode="2.0" requestPathInvalidCharacters=""
because I was getting the error: A potentially dangerous Request.Path value was detected from the client (?), after addindg those settings the Request.Path error disapear but now I am getting the 404.
Any help.
Thanks.
Are you Url.Encoding the keys/values in the query string?
HttpUtility.UrlEncode
can you paste the url which fails? You might have some invalid characters in the query string if you are not encoding it (e.g. '/') which might be causing the problem.
Related
I have just come across a rather strange issue and I really can't understand why this is happening ...
I have a rather simple, MVC website based on .NET Framework 4.7.2. I'm keeping 2 Resource files (resx) for a couple of languages. So far so good. What I do is keeping the selected Culture into a Cookie with the CultureInfo (en-US & el-GR). In my development maching, using IISExpress, everything is running like a charm! The cookie is being updated as expected and of course the value switching can be seen from the browser debugging.
Using Application_BeginRequest() from Global.asax I can recover the selected culture:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string culture = "el-GR";
var langCookie = Request.Cookies["SiderLangCookie"];
if (langCookie != null)
culture = langCookie.Value;
else
{
culture = "el-GR";
HttpCookie cookie = new HttpCookie("SiderLangCookie", culture)
{
HttpOnly = true,
Expires = DateTime.Now.AddMonths(6)
};
Response.AddHeader("Set-Cookie", "SameSite=Strict;Secure");
Response.AppendCookie(cookie);
}
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
}
And later on, if the user chooses to do so, he/she may change the culture from an anchor button:
<a class="socials-item" href="javascript:SwitchLanguage();" title="Language"><i class="fa fa-flag" aria-hidden="true"></i></a>
which is calling a javascript function for an AJAX POST request to the Controller action:
function SwitchLanguage() {
$.ajax({
url: '#Url.Action("SwitchLanguage", "Home")',
method: 'POST',
success: function (response) {
if (response.result == "OK") {
toastr.success("#Resource.LanguageSwitchSuccess", "SUCCESS");
setTimeout(function () { window.location.reload(); }, 2500);
}
},
error: function () {
toastr.error("#Resource.LanguageSwitchError", "ERROR");
}
});
}
and this is my action:
[HttpPost]
public ActionResult SwitchLanguage()
{
string lang = "en-US";
var langCookie = Request.Cookies["SiderLangCookie"];
if (langCookie == null)
{
langCookie = new HttpCookie("SiderLangCookie", lang)
{
HttpOnly = true,
Expires = DateTime.Now.AddMonths(6),
};
Response.AddHeader("Set-Cookie", "SameSite=Strict;Secure");
Response.AppendCookie(langCookie);
}
else
{
lang = langCookie.Value;
if (lang == "en-US")
lang = "el-GR";
else
lang = "en-US";
langCookie.Value = lang;
Response.AddHeader("Set-Cookie", "SameSite=Strict;Secure");
Response.SetCookie(langCookie);
}
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);
return Json(new { result = "OK" }, JsonRequestBehavior.AllowGet);
}
For some reason, when I deploy the website (Publishing to a folder and uploading to the Host), even though the Action code is executing successfully (no exceptions and errors whatsoever), the cookie is no longer updating the value to either el-GR or en-US. It just sticks to the first value it got when first created.
Does anyone have the slightest clue why is this happening?
Thanks in advance.
Cookies issues usually appears if you do not have correct setup the relative sessions on web.config.
Check the domain that is correct setup with out the www. - if you use the www. then check that all calls done from www.
<httpCookies domain="yourdomain.com" httpOnlyCookies="true" requireSSL="true"/>
The domain property also exist on forms and on roleManager
Ok, I managed to figure out the situation. Many many thanks to Thomas Ardal who wrote this article:
[The ultimate guide to secure cookies with web.config in .NET][1]
[1]: https://blog.elmah.io/the-ultimate-guide-to-secure-cookies-with-web-config-in-net/
It seems that the latest changes regarding Cookie management by the browsers are more restrictive than anticipated.
Incorporating the rewrite rule, Thomas proposed, did the trick.
Now the Cookie value seems to be changing as expected.
Thanks
What would be the best way to retrieve the Username entered on a login form in dart polymer to be read in the next page to which it is redirected?
The login component is as below -
#CustomTag('alfresco-login-form')
class LoginFormComponent extends FormElement with Polymer, Observable {
LoginFormComponent.created() : super.created();
#observable String username = "";
#observable String password = "";
#observable Map loginData = toObservable({
'username' : '',
'password' : ''
});
#observable String serverResponse = '';
HttpRequest request;
void submitForm(Event e, var detail, Node target) {
e.preventDefault(); // Don't do the default submit.
request = new HttpRequest();
request.onReadyStateChange.listen(onData);
// POST the data to the server.
var url = 'http://127.0.0.1/alfresco/service/api/login';
request.open("POST", url);
request.send(_loginDataAsJsonData());
}
void onData(_) {
if (request.readyState == HttpRequest.DONE &&
request.status == 200) {
// Data saved OK.
serverResponse = 'Server Sez: ' + request.responseText;
Map parsedMap = JSON.decode(request.responseText);
var currentTicket = new Ticket(parsedMap["data"]["ticket"]);
//keeps the back history button active
//window.location.assign('dashboard.html');
//doesn't keep the back history button active
//doesn't put the originating page in the session history
window.location.replace('dashboard.html');
} else if (request.readyState == HttpRequest.DONE &&
request.status == 0) {
// Status is 0...most likely the server isn't running.
serverResponse = 'No server';
}
}
String _loginDataAsJsonData(){
return JSON.encode(loginData);
}
}
I need to have access to that loginData['username'] & parsedMap["data"]["ticket"] to be available in the page dashboard.html.
Not really an answer, but to long for a comment:
Your code shows how you send the credentials to the server. So my previous comment still fits. You can't just pass variables to a new page. When a page is loaded this is like a application restart. You can pass values in the URL you redirect to, as cookies if both pages are loaded from the same domain or you can just reload them from the server where you stored them previously. To know that the new page is was requested by the same user you have to use some session handling (like the previously mentioned session cookie). This has nothing to do with Dart or Polymer this is more about how the web works.
We recently replaced an old php website with an asp.net MVC website. In order to prevent 404 errors from the legacy urls in search engines, we setup a custom legacy route system via - http://www.mikesdotnetting.com/Article/108/Handling-Legacy-URLs-with-ASP.NET-MVC
The code works on my local machine, and it redirects to the correct route; however, the live server issues a 404. Bonus problem/clue, the 404 is not our custom 404 page but the iis 6 default page.
The code:
public class LegacyUrlRoute: RouteBase
{
// source: http://www.mikesdotnetting.com/Article/108/Handling-Legacy-URLs-with-ASP.NET-MVC
public override RouteData GetRouteData(HttpContextBase httpContext)
{
const string status = "301 Moved Permanently";
var request = httpContext.Request;
var response = httpContext.Response;
var legacyUrl = request.Url.ToString();
var newUrl = "";
if (legacyUrl.Contains(".php"))
{
newUrl = "/";
if (legacyUrl.Contains("support/mailfilter.php"))
newUrl = "/support/";
else if (legacyUrl.Contains("/support/default.php"))
newUrl = "/support/";
else if (legacyUrl.Contains("/business/default.php"))
newUrl = "/services/";
else if (legacyUrl.Contains("/residential/default.php"))
newUrl = "/services/";
else if (legacyUrl.Contains("/about/default.php"))
newUrl = "/home/about/";
else if (legacyUrl.Contains("/jobs.php"))
newUrl = "/jobs/";
else if (legacyUrl.Contains("/support/links.php"))
newUrl = "/support/";
else if (legacyUrl.Contains("/support/settings.php"))
newUrl = "/support/";
else if (legacyUrl.Contains("/default.php"))
newUrl = "/";
response.Status = status;
response.RedirectLocation = newUrl;
response.End();
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
Note:
We suspect that the problem is with iis being unable to serve php pages, but I can't seem to find a setting in iis to fix the problem. It is as if the request never hits the Controller code, error or otherwise. All other pages/routing is working perfectly.
Found the answer.
The problem is due to the fact that iis never starts the asp.net service if the extension is .php.
The solution is to go to Properties>Home Directory>Configuration, find the .php extension, change the executable path to the asp.net path, and limit it to "GET,HEAD,POST,DEBUG" or whatever you prefer. I originally selected the "All Verbs" radio button, but that did not work.
Though the page did not specifically have the answer I came up with, this page did help.
How can I detect the language of the browser and automatically display the correctly localized version of my grails website depending on that value.
I put this in to Index action
Locale locale = new Locale(params.lang)
cookieLocaleResolver.setLocale(request, response, (Locale)
session.getAttribute('locale'))
{
render controller: "home", action: "index"
return
}
And I got exception--
Error 500: Executing action [index] of controller [socialworking.HomeController] caused exception: null
Servlet: grails
URI: /socialworking/grails/home.dispatch
Exception Message:
Caused by:
Class: Unknown
First off, you should put that in a filter in grails-app/conf directory. Create a filter if you don't already have one.
MyFilters.groovy
class MyFilters {
def filters = {
setLocale(controller:'*', action:'*') {
before = {
// Your logic here
}
}
}
}
Your logic here could look in many ways, but here is a try:
String langToSet = 'en';
if ( params.lang && params.lang in validLanguages )
langToSet = params.lang;
else if ( session.lang ) {
langToSet = session.lang;
}
else if ( ... ) // Cookie lang is set ( User might have accessed the site before and you have stored their preferred lang )
// Get cookie lang
Locale locale = new Locale( langToUse)
org.springframework.web.servlet.support.RequestContextUtils.getLocaleResolver(request).setLocale(request, response, locale);
// Set the cookie lang
...
// We set the session lang
session.lang = langToSet
Note that the above is not a complete implementation but it is almost. The cookie stuff and validLanguages you should be able to figure out what they do.
I hope that helps!
I’m using an ExceptionFilter to set the response code to 500 and show a JSONP representation of the exception:
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.Controller.ViewBag.callback = GetCallBack(filterContext);
filterContext.Result = new ViewResult
{
ViewName = GetFormat(filterContext),
ViewData = new ViewDataDictionary(new [] { new { message = "sorry!" } }),
TempData = filterContext.Controller.TempData
};
This is working fine locally, displaying:
whatever([{ "message": "sorry!" }]);
when called locally.
However, when called from a remote machine, I get the IIS7 generic “Error Occurred” page. How can I get my custom content to display instead?