session become null in controller method - c#

I have following controller , in that controller I created session to save IENUMERABLE data-set
[HttpPost]
[ValidateInput(false)]
public ActionResult Create_Brochure(IEnumerable<ProductsPropertiesVM> model)
{
IEnumerable<ProductsPropertiesVM> newmodel = model;
IEnumerable<BrochureTemplateProperties> sample = model.Where.....
Session["TemplateData"] = newmodel;
return View(sample);
}
EDIT:
Create_Brchure View page has href link to call PrintIndex method in same class file
Download ViewAsPdf
this is PrintIndex method
public ActionResult PrintIndex()
{
return new Rotativa.ActionAsPdf("Create_Brochure_PDF") { FileName = "TestActionAsPdf.pdf" };
}
I want to use that session list dataset again in Create_Brochure_PDF controller method,so I created here that method
public ActionResult Create_Brochure_PDF()
{
IEnumerable<ProductsPropertiesVM> newmodel = Session["TemplateData"] as IEnumerable<ProductsPropertiesVM>;
IEnumerable<BrochureTemplateProperties> samplePDF = newmodel.Where(....
return View(samplePDF);
}
but in above method I'm getting null IEnumerable<ProductsPropertiesVM> newmodel
EDIT:
If I explain this whole scenario
Create_Brochure controller method has a view ,
In that view I have href link to save that Create_Brochure view as
PDF
Once I click that href link I'm calling PrintIndex method so in
that action method again its calling to Create_Brochure_PDF method ,
so I'm getting null object set in Create_Brochure_PDF

I had the same issue some times ago, So I came up with solution ViewasPdf() method in Rotativa library
You can directly call to once You click that href link but you have to create a View for this method that your going to generate as PDF
So here the steps
Create a Action for the View that your Going to Generate as PDF
public ActionResult Create_Brochure_PDF()
{
IEnumerable<ProductsPropertiesVM> newmodel = Session["TemplateData"] as IEnumerable<ProductsPropertiesVM>;
IEnumerable<BrochureTemplateProperties> samplePDF = newmodel.Where(....
rerurn View();
}
Generate view for that Action method
Replace this line rerurn View(); with following line in Create_Brochure_PDF() method
return new Rotativa.ViewAsPdf("Create_Brochure_PDF") { FileName = "TestActionAsPdf.pdf" };
Now call the Create_Brochure_PDF() method as follows in
Create_Brochure view page
Download ViewAsPdf

Related

Get attribute of current controller action in MVC View

I wish to display the current action of the controller on my MVC View in a human readable format.
I understand you can acquire the name of the current action through:
#ViewContext.Controller.ValueProvider.GetValue("action")
this returns e.g. 'Index' in the example below
What I am looking to do is something like:
[DisplayName=Resources.Overview]
public ActionResult Index()
{
return View();
}
and then print that DisplayName on the page, some pseudo-code like:
#ViewContext.Controller.ValueProvider.GetValue("action").GetAttribute("DisplayName")
which would return 'Overview' from Resources
Is this possible?
You should first make a reflection to the method with Type.GetMethodInfo
string actionName = ViewContext.RouteData.Values["Action"]
MethodInfo method = type.GetMethod(actionName);
var attribute = method.GetCustomAttributes(typeof(DisplayNameAttribute), false);
if (attribute.Length > 0)
actionName = ((DisplayNameAttribute)attribute[0]).DisplayName;
else
actionName = type.Name; // fallback to the type name of the controller
And then you can pass the actionName to the View using something like
ViewBag.name = actionName;
and then get the Viewbag variable from the view
Why not just set the DisplayName inside the Viewbag and retrieve it in code, for every page that requires it?
For Example,
public ActionResult Index()
{
Viewbag.DisplayName = 'Resources.Overview'
return View();
}
then in any view that populates the DisplayName value, you can display it at the top with the following,
<head>
#ViewBag.DisplayName
</head>

Razor form not passing back to controller method

I am trying to pass a textbox's text back to a method in my controller, but the data is not being passed in the parameter
I am genuinely confused, i'm following another example but i'm getting a different result, ie - my method behaving as if no parameter is passed
Code
public ActionResult Index(string searchString)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
var listOfAnimals = db.Animals.ToList();
if (!String.IsNullOrEmpty(searchString))
{
listOfAnimals = listOfAnimals.Where(a => a.AnimalName.ToLower().Contains(searchString.ToLower())).ToList();
}
return View(listOfAnimals);
}
and here is my razor form from my view page
#using(Html.BeginForm("Index", "Home"))
{
#Html.TextBox("searchString")
<input type="submit" id="Index" value="Index" />
}
Can anybody spot why this isn't working?
If more code is needed, please let me know but i think the issue is isolated to here
You code is correct.
Since you didn't add [HttpGet] or [HttpPost] before index method.
This method was called twice.
The first call ran when producing the page with form via url http://server/Home/Index. This call was an http get and searchString mapped from URL was null, which is correct.
The second call ran when you clicked submit button. Correct value would be mapped by MVC correctly.
You need to have 2 Index actions (two methods), one without decorations (GET verb) and another one decorated with HttpPost (POST verb). Basically, when you go to the index page, the GET action is executed. When you submit the form, a POST request is executed and the Index decorated with HttpPost is executed.
// GET
public ActionResult Index() { ... }
// POST
[HttpPost]
public ActionResult Index(string searchString) { ... }
Francisco Goldenstein wrote the recommended way. It means you can have two Index() actions:
// for GET
public ActionResult Index() { ... }
// for POST
[HttpPost]
public ActionResult Index(string searchString) { ... }
However it is possible to have one Index() method for handling both (GET and POST) requests:
public ActionResult Index(string searchString = "")
{
if(!string.IsNullOrEmpty(searchString)
{ /* apply filter rule here */ }
}
You wrote, your code is not working. Do you mean, your action method is not requested after click on the button? Consider to allow empty value Index(string searchString = "")
If your action method is fired but variable is empty, check the name on the View() side. Textbox must not be disabled, of course.

#Html.ActionLink is not working

I have a orchard project, where I have created a module in MVC. I want to pass the id of particular user to controller using #Html.ActionLink but it not calling controller. Here is my code:
In view:
#Html.ActionLink("100111", "AddToCart", "ShoppingCart", new { id = 101 }, null)
//also tried,
#Html.ActionLink("102829", "AddToCart", "ShoppingCart", new { id = 1, area = "OnlineShopping" },null)
In Controller:
[HttpPost]
public ActionResult AddToCart(int id)
{
_shoppingCart.Add(id, 1);
return RedirectToAction("Index");
}
[Themed]
public ActionResult Index()
{
// Create a new shape using the "New" property of IOrchardServices.
var shape = _services.New.ShoppingCart();
// Return a ShapeResult
return new ShapeResult(this, shape);
}
It is not calling the action method because of [HttpPost] and clicking on anchor tag actually does a Get. So try remove the [HttpPost] attribute decoration from your AddToCart action.
[HttpPost]//<--Remove this
public ActionResult AddToCart(int id)
{
_shoppingCart.Add(id, 1);
return RedirectToAction("Index");
}
Found this on ASP.NET MVC ActionLink and post method
You can't use an ActionLink because that just renders an anchor tag.
You can use a JQuery AJAX post, see
http://docs.jquery.com/Ajax/jQuery.post or just call the form's submit
method with or without JQuery (which would be non-AJAX), perhaps in
the onclick event of whatever control takes your fancy.

Post method that calls another one for returning the view

In an MVC4 project I need to "refresh" the page depending on some messages that can be present, otherwise I just redirect to a page, and if presenting again the page if them messages are present I would like to avoid just returning the View as it will cause then the double submission when the user tries to refresh it.
What I'm trying to do is this
[HttpGet]
public ActionResult SampleMethod()
{
viewModel = _builder.Build();
return View(viewModel);
}
[HttpPost]
public void SampleMethod(SampleViewModel viewModel)
{
if (ModelState.IsValid)
{
var response = serviceCall;
var errorMessages = response.ErrorMessages;
if (!errorMessages.Any())
{
//Redirect to proper view
}
else
vm = _builder.Build();
}
else vm = _builder.Build(); //There is some validation error I rebuild
CashbackOffersConfirmation(vm);
}
public ActionResult SampleMethodConfirmation(SampleViewModel viewModel)
{
return View("SampleMethod", viewModel);
}
It goes through the process
but the final page is .../SampleMethod instead of .../SampleMethodConfirmation and is blank,
Is this something to do with the routing (quite lost in this)? Is this a correct approach?
Thanks
In order to pass the object model from the view to the controller, you need to make a post request. Make sure you use a form that will generate the post request.
Also make the SampleMethodConfirmation method a post.
E.g.: add [HttpPost] on top of the method in the controller

View to String from another controller

i have done as Vdex suggested here:
https://stackoverflow.com/a/5801502/973485
And used the RenderPartialToString method he found. And it works perfectly like this:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Test()
{
string t = ViewToString.RenderPartialToString("Index", null, ControllerContext);
return Content(t);
}
}
But if i want to render the Home > Index from another Controller, i get:
Value cannot be null.
Parameter name: controllerContext
Like this:
public class FooController : Controller
{
public ActionResult Index()
{
string t = ViewToString.RenderPartialToString("Index", null, new HomeController().ControllerContext);
return Content(t);
}
}
Is there any way to pass a View from another Controller to a string? I have tried many different methods, and it all of them fails at the ControllerContext. Many thanks!
Update: Why i need to do this:
Imagine i have a website full of widgets, the amount of widgets on each page is dynamic, so i cannot hardcode them in my cshtml file. But in that file there are different areas defined where the widgets gets printet out. To print out these widget i have a list of IWidgetController wich contains alle the different Widgets available, and the interface sais that they need to containe a ActionResult for edit, new and view. example of widgets: CalenderController, NewsController, GalleryController and so on... So in those areas i need to print out the content of each of those Controllers. Now i could also load the URLHTML but i figured doing it from the inside would be faster... right?
Try this:
string t = ViewToString.RenderPartialToString("Index", null, this.ControllerContext);
Anyway, why do you need to convert to a string?

Categories