Passed value is not preserved - asp.net-core

Not MVC!
Hi all,
What am I doing wrong here...
Im trying to pass an integer value from the onPost method of a Razor Page(Scores/Create.cshtml) to the onGet method of another page(/Scores/Index.cshtml) however the value is not being preserved and I either get null or 0 when inspecting the id value in the onGet method depending on how I send the integer.
I know this works using routes as I do this on another page
<a asp-page="/Scores/Index" asp-route-id="#item.ElementId">Update scores</a>
I have tried passing the value from an entity property like in the code example below, from ViewData variable, also from a locally created integer and finally just passing an integer value itself. In all cases the value is correct in the OnPost but never gets to the onGet.
The OnPost
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.TScores.Add(TScores);
await _context.SaveChangesAsync();
return RedirectToPage("./Index","OnGet",TScores.ElementId);
}
The OnGet
public async Task OnGetAsync(int? id)
{
TElements telement = new TElements();
telement = _context.TElements.Where(a => a.ElementId == id).FirstOrDefault();
I have also tried it without setting the OnGet method name in the RedirecttoPage
I am expecting to get the value of id in the onGet to match TScores.ElementID passed from the onPost.
Thanks in advance
D

The parameter requires an object, specifically an anonymous object of route values; it doesn't know what to do with an int.
return RedirectToPage("./Index", new { id = TScores.ElementId });

Related

ASP.NET Core 3.1 unable to get Odata Query parameter

Using ASP.NET Core 3.1 and Microsoft.AspNetCore.OData 7.5.6,
When a HTTP "DELETE" request is sent to an action method, I am unable to get the
query parameter, the resulting parameter value remains set to 0.
Here is my HTTP Request:
https://localhost:8083/api/EventTypes(Id%3D66L)
And my Action Method:
[Route("api/EventTypes({Id})")]
[HttpDelete]
// [AcceptVerbs("DELETE")]
public async Task<IActionResult> Delete(Int64 Id)
{
DynamicParameters param = new DynamicParameters();
param.Add("Id", Id);
await Dapper.DapperORM.ExecuteWithoutReturn("event_type_delete", param);
return Ok();
}
When I inspect the value of Id the value is 0. I have tried changing the type to string, and then the value is set to "Id=66L".
I expect this to work but it does not in my case:
Delete([FromODataUri]Int64 Id)
What is the best/correct way to get the integer value?
Changing the Route Parameter to use this format Id={Id} and using FromODataUri I managed to get the desired parameter value.
e.g.
[Route("api/EventTypes(Id={Id})")]
[AcceptVerbs("DELETE")]
public async Task<IActionResult> Delete([FromODataUri]Int64 Id)

Access codes for controller methods

I dont want the users to put in method names and their parameters manually and mess with the method. Im aware i can check for unvalid inputs but what if I call a method that generates an access code and passes that into the main controller with the all the other parameters. If the access code. Then decide that access code, if valid proceed. Is this a little too much and too crazy? What other options would you suggest
Public IActionResult MainMethod(string input, string accesscode)
{
//check if access code is correct. I can figure out the decode process and stuff
}
Public IActionResult GenerateCode(string Inputt)
{
// generate a code
Return redirectToAction(“MainMethod” new {input=Inputt , accesscode=accesscode}
});
In View when a button is clicked, I call GenerateCode first
Since you pass Inputt and generated accesscode from GenerateCode to MainMethod,why not only pass input to MainMethod?And then call a method to accesscode,and then check the accesscode in MainMehtod.
public IActionResult MainMethod(string input)
{
string accesscode = GenerateCode(input);
//check if access code is correct. I can figure out the decode process and stuff
}
public string GenerateCode(string Inputt)
{
// generate a code
return accesscode;
}

Redirect to action passes null instead of object

My MVC4 project uses the RedirectToAction() to pass values to another controller.
The problem is, it passes null instead of a value
[HttpGet]
public ActionResult MyProduct(product prod)
{
return RedirectToAction("Index", "MyController", new { prod = prod});
}
This accurately redirects to my MyController which is
public ActionResult Index(Product prod)
{
// prod is null :(
}
I put on a watch in the MyProduct controller, the prod object has a value. The properties do not have values :( it is null
Why does it become null when I pass the object between controllers?
You mistyped you parameter name that you are expecting at your action change it to prod because the prod is a part of RouteValueDictionary which will be collected by the same parameter as defined askey in the dictionary
return RedirectToAction("Index", "MyController", new { prod = prod});
Update
You cannot pass a model object via route parameters via RedirectToAction if I understood your question correctly, instead you can pass specific properties required to be send or you can use the TempData
You can't send data with a RedirectAction. That's because you're doing a 301 redirection and that goes back to the client.
When you redirect you mainly have the query string as a means to pass data to the other request. The other approach is to use TempData which stores data away on the server and you can retrieve it on the next request. By default TempData uses Session.
Consider this image for getting the ways of passing data between Model-View-Controller
Your function parameter name doesn't match in your RedirectToAction().
You should change it like this:
return RedirectToAction("Index", "MyController", new { prod = prod});

Data is not inserting to the database

I am new to asp .net MVC 4.
I have one text box and the text box value I am fetching from one table.But while clicking on submit button this value I want to insert into different table , which is not inserting and showing error.It is taking value as null.
coding
View
#Html.TextBox("empname", (string)ViewBag.empname, new { #readonly = "readonly" })
controller
[HttpGet]
public ActionResult Facilities()
{
mstEmpDetail emp = new mstEmpDetail();
emp = db.mstEmpDetails.Single(x => x.intEmpId == 10001);
ViewBag.empname = emp.txtEmpFirstName;
return View();
}
[HttpPost]
public ActionResult Facilities(TrnBusinessCardDetail bc)
{
var empname1 = ViewBag.empname;
bc.txtfirstName = empname1;
db.TrnBusinessCardDetails.Add(bc);
db.SaveChanges();
return RedirectToAction("Facilities");
}
While I was working with normal text box it was inserting properly,but when I have retrieve
fro DB then i am getting this problem ?
How to solve this problem ?
Viewbag is a one way street - you can use it to pass information to the view, but you cannot use it to get the information from the view. The statement ViewBag.empname in your POST method has a value of null in your code.
As suggested by #dotnetom, ViewBag is a one way street. MVC is stateless so a POST request is not a "Round Trip" from previous get request. Thus your ViewBag can not hold its state.
MVC can determine (and construct) your action parameters from Form Parameters. In your case you have added a textbox with name "empname". So you should get this value as parameter in your POST request.
[HttpPost]
public ActionResult Facilities(TrnBusinessCardDetail bc, string empname)
{
bc.txtfirstName = empname;
db.TrnBusinessCardDetails.Add(bc);
db.SaveChanges();
return RedirectToAction("Facilities");
}
This would be simplest of solution given your problem. More appropriate would be binding your textbox directly with you model property. This way you will not have to worry about retrieving and assigning property value to model in your controller.
I think the problem is when you are using var empname1 = ViewBag.empname; in post controller because ViewBag.empname lost its value at that time.

Uploaded file gets lost when the model is passed inside RedirectToAction method

This is the action method where I save user input and then redirect to the view mode:
[HttpPost]
public ActionResult SaveDocumentCitizen(DocumentCitizen documentCitizen)
{
DocumentCitizenRepository repository = new DocumentCitizenRepository();
repository.SaveDocument(documentCitizen);
return RedirectToAction(actionName: "ViewDocumentCitizen", routeValues: new RouteValueDictionary(documentCitizen));
}
And here's the ViewDocumentCitizen action method:
public ActionResult ViewDocumentCitizen(DocumentCitizen doc)// The Attachment value is null here
{
DocumentCitizenRepository repository = new DocumentCitizenRepository();
DocumentCitizen docCitizen = repository.UpdateTextualValues(doc.DocID);
return View(viewName: "DocumentCitizen", model: docCitizen);
}
The DocumentCitizen model has the following property:
public byte[] Attachment{get;set;}
I choose a file then submit the form and then when I debug the SaveDocumentCitizen method I can see that the Attachment is not null. But it gets set to null as soon as it's passed to the ViewDocumentCitizen method. What do I have to do to have the file property value persisted through redirection?
I think the problem is parameter name in RouteData and in Action method are not equal . Try to modify your SaveDocumentCitizen action
[HttpPost]
public ActionResult SaveDocumentCitizen(DocumentCitizen documentCitizen)
{
DocumentCitizenRepository repository = new DocumentCitizenRepository();
repository.SaveDocument(documentCitizen);
return RedirectToAction(actionName: "ViewDocumentCitizen", routeValues: new RouteValueDictionary(new RouteValueDictionary(new Dictionary<string, object> {{"doc", documentCitizen}})));
}
Or better
return RedirectToAction(actionName: "ViewDocumentCitizen", routeValues: new { doc = documentCitizen});
This should help to your ModelBinder to recognize parameter by name
EDIT:
From MSDN "Controller.RedirectToAction "
Returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action.
Get method has a length limit, read more HERE
But .Net Framework ready for everything, and they created ControllerBase.TempData property read more on MSDN
Hope it will help you