ASP.NET: Saving and displaying value passed from URL - c#

I have passed a string value farmName from one controller to another.
<a asp-action="Index" asp-controller="JFTreatment" asp-route-farmName="#item.Farm.Name">link</a>
I can see in my index view that it has been passed successfully:
I would now like to display the farmName as a title in my edit view, but I am unsure of the syntax of how to set a session string or how to display it.

Assuming that you're setting your Title using ViewData["Title"] dictionary that is set on every page. You can do the following to get the farmName from Url.
Option 1: Get the query value directly from Query Collection
foreach(var query in HttpContext.Request.Query)
{
if(query.Key == "farmName")
{
ViewData["Title"] = query.Value;
}
}
Option 2: Get your route data as method parameter (Recommended)
For this option to work, your Index method should look like this:
public IActionResult Index(string farmName, int? plotId = null){
ViewData["Title"] = farmName;
... Some more code
}
Here the route property is received via Action Parameter...

Figured it out!
I did it using session string
I received the URL through
public async Task<IActionResult> Index( string farmName){
HttpContext.Session.SetString("farmName", farmName);}
Then just set add the reference
#using Microsoft.AspNetCore.Http
Then set the title with
ViewData["Title"] = #Context.Session.GetString("farmName");

Related

Execute a controller from view in ASP.NET MVC - Razor

I am trying to print the name of the user who executes my web app. It is written in MVC-Razor.
From the initial View, I would to execute the controller below:
[Authorize]
public ActionResult Check()
{
var check = new CheckAD();
var user = new User {Name = check.CheckSecurityWithAD()};
if (!string.IsNullOrEmpty(user.Name))
{
return View("Checked", user);
}
var errors = new ErrorsModel()
{
Messages = new List<string>(){"You don't have permission"}
};
return View("Error", errors);
}
This controller returns another view if the user is correctly authenticated:
#model UsersActivationWeb.Models.User
#{
ViewBag.Title = "Checked";
}
#{ <p> Logged come #Model.Name </p>};
How can I print the second view (I think it's a partial view) in the first one using the controller?
Thanks
Sounds to me like you need an Html.Action. This will run the controller code and display the view contents that are produced where you place the call.
Most likely you will need this overload, Html.Action(string actionName, string controllerName).
Assuming the controller is called CheckController. In your initial view call it like this
#Html.Action("Check","Check")
Since you don't want people navigating to the Check view you should give it a ChildActionOnly attribute so it looks like this
[Authorize]
[ChildActionOnly]
public ActionResult Check()
{
//rest of code
}
Finally you almost certainly don't want the layout contents to appear with the Checked view so change your Checked view to this
#model UsersActivationWeb.Models.User
#{
Layout = null;
}
#{ <p> Logged come #Model.Name </p>};
Since you are doing authorization logic in the Check action you might not need the Authorize attribute. I say that because with it a user not logged in will not get the error or their name. Maybe you want this though, I'd need to know more about your code to say for sure.
This way you will either get the name of the user or the errors as required.

Send Selected DropDownList value to HomeController ActionResult

Hi I have a drop down list that is filled in from comma delimited values in the config. This works fine.
What I am trying to do is to send the selected value on button click to a ActionResult in the HomeController.
I created a Model, which is taking a string. When I hit the button I get error:
The view 'TestAction' or its master was not found or no view engine supports the searched locations.
This is what my Controller looks like:
[HttpPost]
[ActionName("TestAction")]
public ActionResult TestAction(SQL_Blocks_App.Models.DropdownList SelectedValue)
{
//System.Diagnostics.Debug.WriteLine(SelectedValue);
return View();
}
This is what my model looks like:
public class DropdownList
{
//
// GET: /DropdownList/
[Display(Name = "Servers")]
public string SelectedValue{ get; set; }
}
and this is what my Index View looks like:
<form id="SelectedValue" action="/Home/TestAction" method="post" style="margin: 0">
<div class="col-lg-5">
#{
ViewBag.Title = "Index";
}
#Html.DropDownList("YourElementName", (IEnumerable<SelectListItem>)ViewBag.DropdownVals, "--Choose Your Value--", new
{
//size = "5",
style = "width: 600px"
})
</div>
<div class="col-lg-5">
<input type="submit" value="Run Query" />
<input id="Button2" type="button" value="Clear" onclick="window.location.reload()" />
</div>
</form>
I want to clarify. My end goal is to use the selected value in a SQL query in the ActionResult and return the results back to the index so I can fill them in a table. ( You don't have to show me how to do the SQL part for now I just would like to see the selected value at least printed in the output.)
Redirect to index action, and pass the parameters along
[HttpPost]
[ActionName("TestAction")]
public ActionResult TestAction(SQL_Blocks_App.Models.DropdownList _selectedValue)
{
//System.Diagnostics.Debug.WriteLine(SelectedValue);
return RedirectToAction("Index", "[Controller]", new {#_selectedValue = _selectedValue });
}
and then your Index method should accept the parameter.
[HttpGet]
public ActionResult Index(SQL_Blocks_App.Models.DropdownList _selectedValue)
{
//use _selectedValue
}
I would recommend using another method other than your index, or make Dropdownlist nullable/set a default for it.
The default framework behavior of return View() is to return a view with the same name as the currently-executing action. Which is TestAction. The error is telling you that no such view was found.
You have a couple of options. You can either create the view, or you can return something else. For example, if you want to redirect back to the Index then you can return a redirect result:
return RedirectToAction("Index");
You could also specify the Index view in the response:
return View("Index");
However, keep in mind that the URL will still be for TestAction and not for Index, which could result in unexpected changes to behavior if you're not aware of this.
Edit: Based on comments on this answer, it sounds like what you actually want is to build a pair of actions which generally operate on the same view. This isn't particularly common for an index view, but is very common for edit views. The only difference is semantics, structurally the concept works anywhere.
Consider two actions:
public ActionResult Index()
{
// just show the page
return View();
}
[HttpPost]
public ActionResult Index(SQL_Blocks_App.Models.DropdownList SelectedValue)
{
// receive data from the page
// perform some operation
// and show the page again
return View();
}
Requests between these two actions would differ only by the HTTP verb (GET or POST), not by the action name on the URL. That name would always be "Index". But when the form on the index view is submitted via POST and has a "SelectedValue", the second action is invoked instead of the first.
In that second action you would perform your database interaction, gather whatever data you needed, and if necessary include a model or some additional data in the response.
You TestAction method is returning to a View. Make sure View TestAction.cshtml exists and is in the Home folder.

How do you use the Html.BeginFrom method when passing attributes to your controller?

First of all, I'm fairly certain that this is already answered, and I'm sorry that it's most likely a re-post, but I can't find the answer right now. Zzz.
Here is my razor code (stripped of non-essentials):
#model SurveyApp.Models.LoginModel
#{
var x = ViewBag.Culture; //x gets populated with "en-CA"
}
#using (Html.BeginForm("Login", "Account", FormMethod.Post, new { culture = x, id = "login-form" }))
{
//...
Submit
}
I'm pretty sure that this is all of the relevant code, because in my [httppost]login method, I am getting null in the second parameter.
Here is the login prototype (or whatever you call it):
public ActionResult Login(LoginModel model, string culture)
{
//...
}
Am I using the attribute parameter of the Html.BeginForm call improperly?
You should put those as hidden form fields. The attributes on a form tag don't get submitted unless its the URL.

View is sending null value to the controller

I have a view file from where I am trying to send the url to the controller file
My view file looks like:
#model WebRole1.Models.CodeSnippet
#{
ViewBag.Title = "Details";
}
<p>
#Html.ActionLink("Preview", "Preview", new { Model.URL }) |
</p>
In the above code I am trying to send the url value to the controller file. Function in the controller file looks like
public ActionResult Preview(object zipPath)
{
// some operation...
}
However for some reason view is sending null value to the controller. i.e. when Preview method of controller gets called zipPath value remains null. What can be the issue?
Your action method is waiting for property with the name zipPath. But, since you don't provide a name for a property in your anonymous object, it will be URL by default.
So, change your code to:
#Html.ActionLink("Preview", "Preview", new { zipPath = Model.URL })
Additional information:
If you have included zipPath as a URL segment in your route, then the value will assigned to this segment by the routing segment. Otherwise, the value we supplied will be added as part of the query string.

How to pass Viewdata value to masterpage in Razor MVC4

I use Directoryservices for login in My page. I need to pass the username to my masterpage to display the username in all the pages.
I got the username and stored it in a ViewData. How to pass the viewdata value in masterpage.
My code :
[HttpPost]
public ActionResult Index(LoginModels model)
{
if (ModelState.IsValid)
{
string DisplayUserName = string.Empty;
string LoginUser = model.Userid;
string LoginPassword = model.Password;
string name = model.UserName
if (ValidateActiveDirectoryLogin(LoginUser, LoginPassword, out DisplayUserName) == true)
{
model.UserName = DisplayUserName;
ViewData["UserName"] = "Welcome" + DisplayUserName;
return RedirectToAction("Index", "MPP", new { UserID = LoginUser });
}
else
{
ModelState.AddModelError("","Invalid Username or Password");
}
}
return View();
}
In Layout page :
#{ #ViewData["UserName"] }
I tried the following way to display the Username. But it throws nullexception.
EDIT :
#foreach (var m in IEnumerable<SampleECommerce.Models.LoginModels>)ViewData["UserName"])
{
#m.UserName
}
There are some misunderstandings, like if you set ViewData["UserName"] to a string value you get a IEnumerable<SampleECommerce.Models.LoginModels>. Here is another solution:
Put this to layout page:
<span>#{Html.RenderAction("actionname", "controllername");}</span>
And in related action:
public ActionResult actionname() {
string result = getusername();
return Content(result);
}
[NoneAction]
private string getusername(){
return (Membership.GetUser()!= null) ? Membership.GetUser().UserName : "Guest";
}
Try it without the extra #, i.e.
#{ ViewData["UserName"] }
Firs you need to change your syntax to:
#(ViewData["UserName"])
That's probably the best (of a bad bunch). Realistically you should be looking to push your user into the User property of your pages via the User property of your controllers (typically in an authorization attribute where, perhaps, you read a cookie) - that way you don't rely on type-unsafe ViewData and magic strings for something that you're going to be using on every page.
But anyway... if the view is rendering because of the last return View(); line then what you're trying to do will work if you change your syntax as I've shown.
If not, and it's when you do return RedirectToAction("Index", "MPP", new { UserID = LoginUser }); then you need to push the UserName into TempData and then read it back at the start of the Index action on your MPP controller:
So:
TempData["UserName"] = "Welcome " + DisplayUserName;
return RedirectToAction("Index", "MPP", new { UserID = LoginUser });
And then at the start of your Index method you need to pull the value back out of TempData:
public class MPPController {
public ActionResult Index(){
ViewData["UserName"] = TempData["UserName"];
}
}
Why do you have to do this? Because RedirectToAction doesn't render a page - it tells the client to make a different request to a new Url - thus any ViewData or model or whatever is thrown away as far as the server is concerned. TempData is there to provide temporary storage between two successive requests only - thus it works well for the RedirectToAction scenario.
Like I say though - this really is a poor way to persist your user information from controller to view and you should seriously rethink it as a matter of urgency.
in layout page:
<span>#{Html.RenderAction("actionname", "controllername");}</span>
in controller store a session variable
[HttpPost]
public ActionResult Index(LoginModels model)
{
Session["username"] = model.UserName;
//remaining code
}
add one more function
public ActionResult actionname() {
return Content(Session["username"]);
}
so here we dont need additional functions.

Categories