Return Response.Redirect or ActionResult from a single MVC method - asp.net-mvc

I have a MVC method that currently returns an ActionResult - I have had to make some changes and based on the business logic I want to do a response.redirect instead.
So I want to do something like this:
public ActionResult Index(CountryHomePageType currentPage)
{
if (someVar = true)
{
return View();
}
else
{
Response.redirect("www.website.com")
}
}
but I can't becuase Resonse.Redirect is not a ActionResult....
How can I get round this?

If you are redirecting outside of your current mvc application you can use
return Redirect("<your external url>"); // like "https://www.google.com"
if you want to redirecto back you your homepage you can use
return RedirectToAction("Index", "Home");
assuming you are using the default mvc setup
You might want to also look at ActionFilters if you are making this check in multiple places.

Related

Have same URL for two separate pages

I am working on testing different landing pages for users, and want 50% to land on a different page. The split is being done based on odd/even IP address. However, I want the URL of the landing page to be the same, but can't figure out how to do this. So far these are the two ActionResults:
[HttpGet]
public ActionResult VerifyVoucherCode()
{
var model = new VerifyVoucherModel();
model.ActivationCode = Request.GetFirstQueryValue("value", "voucher");
return View(model);
}
[HttpGet]
public ActionResult AlternateVerifyVoucherCode()
{
var model = new VerifyVoucherModel();
model.ActivationCode = Request.GetFirstQueryValue("value", "voucher");
return View(model);
}
As you can see the code is exactly the same, which I want to avoid regardless, but they correspond with different .cshtml files and partials and display different content. I want the URL for both to be 'SignUp/VerifyVoucher' but the second one is obviously at the moment 'SignUp/AlternateVerifyVoucher'. Is there any way I can get the AlternateVerifyVoucherCode to have the same URL but display and match up with the different razor pages?
Perhaps you need one entry point with mutliple results. Maybe something like this pseudo code?
[HttpGet]
public ActionResult VerifyVoucherCode()
{
var model = new SomeModel();
if (something == verifyvoucher)
{
return View("VerifyVoucherCode", model);
}
else if (something == alternateverifyvoucher)
{
return View("AlternateVerifyVoucherCode", model);
}
else
{
//TODO: error
return View("SomeError");
}
}

mvc ActionResult is not return to anotherView

Here I have two methods.
Login method
public ActionResult Login(LoginCrediential ObjCrendentials)
{
if (x == true)
return RedirectToAction("RoutingAction");
else
return View("Index");
}
RoutingAction method
public ActionResult RoutingAction()
{
if (User.IsInRole("Admin"))
return View("Admin/AdminHome/index");
else if (User.IsInRole("Hr"))
return View();
else
return View();
}
When my if condition Is true in the Login method, its navigating to RoutingAction() but throwing the following error
Admin/AdminHome/index or its master was not found or no view engine supports the searched locations
In url its showing as http://localhost:3013/Home/RoutingAction
Please help me how I can solve this issue.
Well, It's only going to search the Views folder of your controller (Home) and the Shared views. However, you should be able to specify the full path to the View:
return View("~/Areas/Admin/Views/AdminHome/Index.cshtml");
But, if you want the url to reflect this location, then you probably need to have an AdminHome Controller and redirect to its index action.

Asp.Net MVC3 Redirect

I have an action like shown below. In GetAvailableBookList, I get the list and if there is not any available book redirect to a message page. But in action part code continues to execute and gets an exception and I find myself in error page.
I don't want to use return RedirectToAction or something like that because there are a lot of places where we use this redirect logic in our application.
public ActionResult ActionName()
{
List<BookType> bookList = GetAvailableBookList();
// some code
return View("RelatedView");
}
private List<BookType> GetAvailableBookList()
{
....
list = GetList();
if(list.Count == 0)
{
System.Web.HttpContext.Current.Response.Redirect(messagePageUrl, true);
}
else return list;
}
Unfortunately, Response.Redirect() isn't really friendly with ASP.NET MVC. My rule of thumb is if it comes from HttpContext I don't want to touch it in the controller (of course there are many exceptions to that rule) -- especially since it improves testability.
My suggestion is to use RedirectToAction, but since you don't want to repeat code you can do it in such a way that you don't have to repeat code (although in this case I don't see a problem with repeating code).
public ActionResult LoadBookListAndContinue(
Func<List<BookType>, ActionResult> continuation)
{
var list = LoadBooklist();
if(list.Any())
{
return action(continuation);
}
return new RedirectResult(messagePageUrl);
}
// in your controller
public ActionResult ActionName()
{
return LoadBookListAndContinue(
list => {
// some code
return View("RelatedView");
});
}
Is it pretty? No, but it works better than the Redirect exception.
Use
return RedirectToAction("NoListAvailable");
if you have a specific action you would like to execute. The NoListAvailable action can return a view indicating the problem.
Alternatively, you could return the view directly
return View("NoListAvailable");
The exception you are getting is probably ThreadAbortException and this is something you cannot avoid unless you allow the thread to continue (2nd argument in Response.Redirect).
On a side note your current solution is generally flawed. You should use RedirectToAction in each action when your method returns an empty list.
Throwing a specific exception and redirect where you catch it may be solution
Try to write
System.Web.HttpContext.Current.Response.Redirect(messagePageUrl, false);

ASP.NET MVC check if user belongs to [x] group

Maybe I'm approaching this the wrong way and should be doing everything in action filters, in which case please point me in the right direction!
I'm setting up my ASP.NET MVC application so that the one HomeController Index action delivers two different types of content, like so:
if(Request.IsAuthenticated)
return View("IndexRegistered");
else
return View("IndexGuest");
This is fine but say I want to split it into three so Administrator members get their own page...
if(Request.IsAuthenticated)
{
if( /* user is a member of administrators */)
return View("IndexAdministrator");
else
return View("IndexCustomer");
}
else
return View("IndexGuest");
Can someone enlighten me as to the missing piece of this puzzle?
Use the Roles property of the Authorize Action Filter:
[Authorize(Roles="Administrators,Moderators")]
public ActionResult SomeAction(){
}
Or use the User.IsInRole() method:
if(User.IsInRole("Administrator")) { ... }
If you look at the Authentication provider which comes out-of-the-box in the default MVC project templates it's easy to add your own role support there and track it in session, so your code above would become:
if(Request.IsAuthenticated)
{
if(Session["Role"] == "Administrator")
return View("IndexAdministrator");
else
return View("IndexCustomer");
}
else
return View("IndexGuest");
and then opens possibilities like:
if(Request.IsAuthenticated)
return View("Index" + Session["Role"]);
else
return View("IndexGuest");

if a controller action redirects to external url, what do you return in the function?

i have a function and i am unclear what i should return from this?
public ActionResult LoadExternalURL()
{
Response.Redirect("http://www.google.com");
// what do i return here ??
}
Instead of calling Response.Redirect it's easier to use the built in RedirectResult ActionResult as follows:-
return Redirect("http://www.google.com");
This will also improve the testability of your code (you don't have to muck around mocking the HTTP context) and instead you can just test the Url property of the returned action result.

Resources