ASP MVC RedirectToAction passing an array of objects without using ViewData - asp.net-mvc-2

I have the following method
public ActionResult Search(FormCollection form)
{
.......
Publication[] publicationsResult = server.SearchLibrary(this.getSession(), sq);
return RedirectToAction("BookListing", new { publications = publicationsResult });
}
Which gets a list of publications from the server and stores it in an array of type Publication.
I would like to show the results in another page, thus I redirected to the following method:
public ActionResult BookListing(Publication[] publications)
{
Publication[] p = publications;
return View(publications);
}
And I also have the following Routes defined:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Library", action = "Search", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"PublicationListing", // Route name
"{controller}/{action}/{publications}", // URL with parameters
new { controller = "Library", action = "BookListing", publications = UrlParameter.Optional } // Parameter defaults
);
When in Search the publications array is populated with over 13000 objects, however when I redirect to BookListing null is passed.
Is there a way to pass an array of objects from one action method to another using RedirectToAction?
Thanks.

You always have the TempData collection. This is persisted between the action redirects for a single request and so provides you with storage for anything like this...

Related

MVC How To Pass Url Values as Well as a Model From Action to a View

I am looking for a way to preserve a url parameter after posting through a form. For example my GET method takes a string "type" and uses that to determine the type of report to render in the View. The url looks like this:
http://mysite/Reports/Report?type=1
[HttpGet]
public ActionResult Report(string type)
{
var model = new ReportsModel()
{
Report = ReportList.Find(o => o.ReportType == type)
};
return View(model);
}
The View has a form that has start/end date filters used to determine the date range of the date to be displayed for the type of report:
#using (Html.BeginForm("Report", "Reports"))
{
Report.ReportName
#Html.HiddenFor(o => o.Report.ReportType)
#Html.EditorFor(o => o.Report.StartDate )<br/>
#Html.EditorFor(o => o.Report.EndDate )<br/>
<button id="reports">Report</button>
}
The above form posts to an action that gets report data from the database based on the specified report type, start/end dates, and returns back to the view.
[HttpPost]
public ActionResult Report(GenericReportsModel model)
{
switch (model.Report.ReportType)
{
case ReportType.ReportType1:
model.Result = ReportRepository.GetReport<ReportType1>(model.StartDate, model.EndDate);
break;
case ReportType.ReportType2:
model.Result = ReportRepository.GetReport<ReportType2>(model.StartDate, model.EndDate);
break;
}
return View(model);
}
The problem is that after the post, the "type" parameter is lost from the url.
Before the post: http://mysite/Reports/Report?type=1
After the post: http://mysite/Reports/Report
I need to be able to do something like this (which doesn't work):
return View(model, new {ReportType = model.ReportType);
How can I preserve the type parameter in the url after the post, in case someone wants to copy and paste the url to send to someone else?
You need to update Html.BeginForm and your HttpPost version of Report method.
#using(Html.BeginForm("Report", "Report", "YourController", new { type = model.ReportType})
{
// I am assuming that model.ReportType == type argument
// in your HttpGet Report action
// The rest of the form goes here
}
Your action should look like:
[HttpPost]
public ActionResult Report(string type, GenericReportsModel model)
{
switch (model.Report.ReportType)
{
case ReportType.ReportType1:
model.Result = ReportRepository.GetReport<ReportType1>(model.StartDate, model.EndDate);
break;
case ReportType.ReportType2:
model.Result = ReportRepository.GetReport<ReportType2>(model.StartDate, model.EndDate);
break;
}
return View(model);
}
If type is not equal to model.ReportType then you should create a ViewModel that contains the values from your GenericsReportModel and this other Report type.

MVC routing not working when default and custom route refer to same controller

I have two routers in my global.asax, one is a default router which is like:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Test", action = "Action1", id = UrlParameter.Optional }
);
and other is Custom router:
routes.MapRoute(
"CustomRouter", // Route name
"Test/{id}/{FacetString}/{CurrPageNo}",
new { controller = "Test", action = "Action12", id = "", FacetString = UrlParameter.Optional, CurrPageNo=UrlParameter.Optional }
);
some how when I pass url "http://localhost/Test/1001/State=TX" the second router should get executed but some how its not executing.
I had read that the sequence of router is important, hence I tried to exchange there sequence, but it is still not working, if I place it above default router than, the cutom router gets called for all the other actions in that router, which should not happen
the last URL-component State=TX looks like a query string parameter to me. Shouldn't it be ?State=TX (which then wouldn't match your route) or /State/TX
it seems like you should use constraints, reducing match rate for your custom router. You can use forth parameter to define your constraints. In this case it can be something like this
routes.MapRoute(
"CustomRouter", // Route name
"Test/{id}/{FacetString}/{CurrPageNo}",
new { controller = "Test", action = "Action12", id = "", FacetString = UrlParameter.Optional, CurrPageNo=UrlParameter.Optional
, new {id=#"\d+"});
in this way your second URL section requires to be numeric in order to get executed.
According your second route your url should be in one of these formats
http://localhost/Test/1001
http://localhost/Test/1001/State
http://localhost/Test/1001/State/3
Also there is no need of controller = "Test", action = "Action12" as they are not part of the second route definition
Have a look at this MSDN link on ASP.NET routing

Asp.net Mvc 2 How to reroute to www.example.com/my-profile

i would like to reroute this address www.exmaple.com/my-profile to a profile controller i have in my mvc application. There is my global.aspx, as you can the the default routing is
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}/", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
This is the Maproute i'm trying to use to reroute to www.exmaple.com/my-profile
routes.MapRoute(
"Profile", // Route name
"{profile_name}/", // URL with parameters
new { controller = "Portfolio", action = "Index", page = UrlParameter.Optional } // Parameter defaults
);
The problem is when i type www.exmaple.com/profile it trys to direct me to the default maproute, not the one i have specified.
But when i can do this www.example.com/profile/my-profile
routes.MapRouteLowercase(
"Profile", // Route name
"profile/{profile_name}/", // URL with parameters
new { controller = "Portfolio", action = "Index", page = UrlParameter.Optional } // Parameter defaults
);
it works fine, but i dont want to add profile before my-profile. I would like it to work like facebook.com/my-profile or youtube.com/my-profile.
Does anyone one know how i accomplish this, i have been looking for a solution for over 2 months (on and off)
Thanks
Your routing if I remember rightly will return the first matching pattern for the URL. I would expect in your case, your URL is matching your default pattern first.
Move your more specific route above your 'default' route and see if this helps.

where to check if user is login and how to prevent not login users to enter to the admin section

i have route all admin controllers to "admin folder",
but i want to check if the user is login and if not to give him login view.
for the not login user i want to let him enter just the "website" controller
where i need to check it?
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("elmah.axd");
routes.IgnoreRoute("admin/page/Scripts/tiny_mce/templates/(.*/).htm");
routes.IgnoreRoute("content/themes/(.*/)/(.*/).css");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
routes.MapRoute(
"Default", // Route name /Account/LogOn
"admin/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
//new { controller = "Account", action = "LogOn", id = UrlParameter.Optional }
);
routes.MapRoute(
"pagesseo", // Route name /Account/LogOn
"{fName}", // URL with parameters
new { controller = "website", action = "Index", fName = UrlParameter.Optional } // Parameter defaults
);
}
Take a look at the following Website:
http://www.dreamincode.net/forums/topic/161288-reroute-to-login-in-aspnet-mvc-using-authentication/
This might help you.
It shows how to restrict access and control access to controllers or pages.
Hope it helps , Be happy.
You could use the [Authorize] attribute to set authorization roles on controller actions.
I assume you are planning on using Windows Authentication, meaning that user has logged into their windows account before accessing your web site. You want to see if the credentials supplied match people on the list of 'admins'. In your web.config you need to specify that you are using Windows Authentication. To do this you put <authentication mode="Windows"/> into the the system.web section. Then in your protected pages OnInit routine you put something like the following.
if (!IsPostBack)
{
// if this is the first request for this page create the
// validation object and record their arrival
String userName = Request.ServerVariables["LOGON_USER"];
String host = Request.UserHostAddress;
UserValidation valid = new UserValidation();
if valid.checkUser(userName, host)
{
logger.Info("User " + userName + " opened the reviewer form");
} else
{
// ... redirect to error message page
}
}

Custom routing within an area

i have an Area called Members and the following registered routes in the MembersAreaRegistration file:
context.MapRoute(
"Members_Profile",
"Members/Profile/{id}",
new { controller = "Profile", action = "Index", id = UrlParameter.Optional },
new string[] { "MyProject.Web.Mvc.Areas.Members.Controllers" }
);
context.MapRoute(
"Members_default",
"Members/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "MyProject.Web.Mvc.Areas.Members.Controllers" }
);
I want to be able to map the following URLs:
~/Members (should map ~/Members/Home/Index )
~/Members/Profile/3 (should map ~/Members/Profile/Index/3)
With this route registrations everything works fine. However, I added the following URL:
~/Members/Profile/Add
and I got the error:
"The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'MyProject.Web.Mvc.Areas.Members.Controllers.ProfileController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
I also want to have the URL
~/Members/Profile/Edit/3
What should I modify in order to have all this URLs working properly?
You will need to add a couple of additional routes, BEFORE the routes you have already defined. This is because these are specific routes that you want picked before the more generic routes you already have.
context.MapRoute(
"Members_Profile",
"Members/Profile/Add",
new { controller = "Profile", action = "Add" },
new string[] { "MyProject.Web.Mvc.Areas.Members.Controllers" }
);
context.MapRoute(
"Members_Profile",
"Members/Profile/Edit/{Id}",
new { controller = "Profile", action = "Edit", id = UrlParameter.Optional },
new string[] { "MyProject.Web.Mvc.Areas.Members.Controllers" }
);