Getting and dealing with the Entered data in MVC - Simple - c#

I have some questions regarding my MVC learning curve
Goal:
I want to get the txtMHM entered text
after the btnStat is pushed and show the entered text via a label or span or ...

The View Model you should use (simplified):
public class YourViewModel
{
public string TextEntered { get ; set ; }
}
The View:
#model YourViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.TextEntered)
<br />
<input id="btnStat" type="submit" value="MHM" />
}
#Html.LabelFor(m => m.TextEntered)
The Controller Action method:
[HttpPost]
public ActionResult ChangeLabelText(YourViewModel yourViewModel)
{
return View(yourViewModel);
}
Your Altered Code
index.cshtml
#model MVCTest1.Models.EnteredTextModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.TextEntered)
<br />
<input id="btnStat" type="submit" value="MHM" />
}
#Html.LabelFor(m => m.TextEntered)
The Model
namespace MVCTest1.Models
{
public class EnteredTextModel
{
public string TextEntered { get; set; }
}
}
The HomeController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCTest1.Models ;
namespace MVCTest1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
[HttpPost]
public ActionResult Index(EnteredTextModel theModel)
{
return View(theModel);
}
public ActionResult About()
{
return View();
}
}
}

Sypress,
Best practice would be to use a viewmodel for your action. However, at a very simple level, based on exactly what you have above, you could use the viewbag object to pass back the input value. without further ado, the frig, i mean code :):
Controller actions:
[HttpGet]
public ActionResult ChangeLabelText()
{
return View();
}
[HttpPost]
public ActionResult ChangeLabelText(FormCollection formCollection)
{
ViewBag.LastNameEntered = formCollection["txtName"];
return View();
}
View stuff (assumes that the view is named ChangeLabelText.cshtml of course):
#{
ViewBag.Title = "ChangeLabelText";
}
<h2>ChangeLabelText</h2>
<form action="ChangeLabelText" method="post">
<input id="txtMHM" type="text" name="txtName" value="" />
<input id="btnStat" type="submit" value="Post" />
<br />
#Html.Label("Entered Text");
<span id="spnEnteredText">#ViewBag.LastNameEntered </span>
</form>
and the above is called as such http://localhost:xxxx/Home/ChangeLabelText (where xxxx is the port number of your dev server)
I would add that this would NOT be the way that I would approach this to be honest, but is my direct response to your example. go for sharks' example using the viewmodel.
good luck
[EDIT] - I've updated my answer now that I'm at a machine, so the above should work as intended.

Related

Passing Data from one controller method to another in MVC

I have a page that has 2 text boxes First Name and last Name after user click on sign up button API will run and returns user info and shows another page(view) that had user Phone, email,.. That fill with the info that API returns. I have 1 controller and 2 views.
I get the info from API and return the second view but not sure how fill the text boxes with the info I have. The problem is using the models in view, I have 2 models one for each view. I am getting this error when I call the second view:
The model item passed into the dictionary is of type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]', but this dictionary requires a model item of type Models.CreateLogInRequest'.
This is my controller:
[HttpGet]
public ActionResult SearchUser()
{
return View();
}
[HttpPost]
public async Task<ActionResult> SearchUser(UserSearchRequest userSearchRequest)
{
HttpClient client = new HttpClient();
object userObject = null;
string baseUrl = "http://test/api/users";
if (userSearchRequest.FirstName != null && userSearchRequest.LastName)
{
var response = await client.GetAsync(string.Format("{0}{1}/{2}/{3}", baseUrl, "/users", userSearchRequest.FirstName, userSearchRequest.LastName));
if (response.IsSuccessStatusCode)
{
userObject = new JavaScriptSerializer().DeserializeObject(response.Content.ReadAsStringAsync().Result) as object;
}
}
if (userObject != null)
{
return View("Create", userObject);
}
return View("Create", null);
}
[HttpPost]
public ActionResult Create(CreateLogInRequest createLogInRequest)
{
return View();
}
This is my First View that shows 2 text boxes:
#using (Html.BeginForm("SearchUser", "SignUp", FormMethod.Post))
{
#Html.AntiForgeryToken()
<input id="FirstName" name="FirstName" type="text" placeholder="First NAME" />
<input id="LastName" name="LastName" type="text" placeholder="LastName " />
<input id="btnSubmit" name="btnSubmit" type="submit" value="SIGN UP TODAY" />
}
and this is my model for 1st view:
public class UserSearchRequest
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
This is the second View:
#model Models.CreateLogInRequest
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm("create", "SignUp", FormMethod.Post))
{
#Html.AntiForgeryToken()
<input id="Email" name="Email" type="text" placeholder="Email" value="#Model.Email" />
<input id="Phone" name="Phone" type="text" placeholder="Phone" value="#Model.Phone" />
<input id="btnSubmit" name="btnSubmit" type="submit" value="CREATE ACCOUNT" />
}
and this is Model for this view:
public class CreateLogInRequest
{
public string Email { get; set; }
public string Phone { get; set; }
....
}
See my comments and try this:
[HttpGet]
public ActionResult SearchUser()
{
return View();
}
[HttpPost]
public async Task<ActionResult> SearchUser(UserSearchRequest userSearchRequest)
{
HttpClient client = new HttpClient();
CreateLogInRequest userObject = null;
string baseUrl = "http://test/api/users";
if (userSearchRequest.FirstName != null && userSearchRequest.LastName)
{
var response = await client.GetAsync(string.Format("{0}{1}/{2}/{3}", baseUrl, "/users", userSearchRequest.FirstName, userSearchRequest.LastName));
if (response.IsSuccessStatusCode)
{
userObject = new JavaScriptSerializer().DeserializeObject<CreateLogInRequest>(response.Content.ReadAsStringAsync().Result);
}
}
if (userObject != null)
{
return RedirectToAction("Create", userObject);
}
return View("Create", null);
}
[HttpPost]
public ActionResult Create(CreateLogInRequest createLogInRequest)
{
return View();
}
In the Controller you can create a new instance of Models.CreateLogInRequest model and fill the related properties received from 1st View. If Models.CreateLogInRequest does not contain such properties then it is better to load these values by using TempData or ViewBag in the Controller retrieved from the 1st View and pass them to the 2nd View. For the differences between ViewBag, ViewData, or TempData you might have a look at When to use ViewBag, ViewData, or TempData in ASP.NET MVC 3 applications. Hope this helps...

Sending a phrase (variable) from searcher (from view) to controller, asp.net mvc

I'm trying to create searcher in asp.net. I'm so green about it. I'm trying to create in view and send to controller variable, which has text written in searcher. In that moment, I have smth like that -->
My question is, where and how create and send variable and give her data written in searcher?
Layout
form class="navbar-form navbar-left" role="search">
#using (Html.BeginForm("Index", "Searcher", FormMethod.Post, new { phrase = "abc" }))
{
<div class="form-group">
<input type="text" class="form-control" placeholder="Wpisz frazę...">
</div>
<button type="submit" class="btn btn-default">#Html.ActionLink("Szukaj", "Index", "Searcher")</button>
}
</form>
Controller
public class SearcherController : ApplicationController
{
[HttpGet]
public ActionResult Index(string message)
{
ViewBag.phrase = message;
getCurrentUser();
return View();
}
}
View
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<ul>
<li>#ViewBag.message</li>
</ul>
You're missing a key part of MVC -> the Model.
Let's create one first:
public class SearchModel
{
public string Criteria { get; set; }
}
Then let's update your "Layout" view (don't know why you had a form in a form?):
#model SearchModel
#using (Html.BeginForm("Index", "Searcher", FormMethod.Post, new { phrase = "abc" }))
{
<div class="form-group">
#Html.EditorFor(m => m.Criteria)
</div>
<button type="submit" class="btn btn-default">#Html.ActionLink("Szukaj", "Index", "Searcher")</button>
}
Then your action that serves that view:
[HttpGet]
public ActionResult Index()
{
return View(new SearchModel());
}
Then your post method would be:
[HttpPost]
public ActionResult Index(SearchModel model)
{
ViewBag.phrase = model.Criteria;
getCurrentUser();
return View();
}

MVC submit button not firing

I am using ASP.net MVC 4 with the Razor engine.
I have a page (Index.cshtml) and a controller (HomeController.cs)
I am trying to hook up my submit button to an Action Result in my controller - however i can't seem to get it to fire.
My HTML :
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post))
{
<div class="main-Background">
******lots of other html here*******
<button type="submit" id="btnSave">Save</button>
</div>
}
My Controller :
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
[HttpPost]
public ActionResult SubmitForm()
{
return View();
}
}
At the moment i havn't implemented a model to pass the values through to the controller, i just wanted to see if i could get the ActionResult SubmitForm to fire.
I have tried #using (Html.BeginForm()) with no parameters, i have also tried including [HttpPost] above my ActionResult, without any luck.
Edit i have also tried using <input type="submit" id="btnSave">Save</input> instead of a button.
Not sure where i am going wrong
It turns out that jQuery was stopping the ActionResult from being hit.
I had a button click event which was "eating up" the ActionResult functionality. I solved this by calling my ActionResult using Ajax.
You dont need to use "-Controller" suffix. Use just Home instead of HomeController, MVC will convert it for you.
Use
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
instead of
#using (Html.BeginForm("SubmitForm", "HomeController", FormMethod.Post, new { id = "submitForm" }))
Full codes
view
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
{
<div class="main-Background">
******lots of other html here*******
<input type="submit" id="btnSave">Save</input>
</div>
}
And controller
[HttpPost]
public ActionResult SubmitForm()
{
return View();
}
View:
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post))
{
<div class="main-Background">
******lots of other html here*******
<button type="submit" id="btnSave">Save</button>
</div>
}
Controller:
[HttpPost]
public ActionResult SubmitForm()
{
return View();
}
May be the problem is occurred because of other HTML inside your div so check it out. Otherwise it works perfectly.
You need to add Html.BeginForm with the parameters. Here is an example:
ActionName – Name of the Action. In this case the name is Create.
ControllerName – Name of the Controller. In this case the name is Home.
FormMethod – It specifies the Form Method i.e. GET or POST. In this case it will be set to POST.
http://localhost:60386//Home/Create
#using (Html.BeginForm("Create", "Home", FormMethod.Post))
{
#Html.EditorFor(model => model.FirstName)
<input type="submit" value="Create"/>
}
HomeController.cs:
[HttpPost]
public ActionResult Create(Person person)
{
if (ModelState.IsValid)
{
db.Persons.Add(person);
db.SaveChanges();
return RedirectToAction("Create");
}
return View(person);
}
TL;DR
I had [Required] data attributes on my view model preventing the submit from working when the form wasn't filled.
I had two submit buttons in my MVC code, one for Submit, the other for Cancel.
Both buttons were firing correctly on data entry, but neither when nothing was entered.
It took me a bit to realize that my view model had [Required] field validations in place!
View:
#using (Html.BeginForm(actionName: "Index", controllerName: "User", method: FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.TextBoxFor(m => m.PhoneNumber)
...
<input type="submit" name="submitAction" value="Verify" />
<input type="submit" name="submitAction" value="Cancel" />
}
ViewModel:
public class UserViewModel
{
[Required]
[MaxLength(10)]
public string PhoneNumber { get; set; }
[Required]
...
}
Controller Method:
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult Index(UserViewModel viewModel, string submitAction)
{
switch(submitAction)
{
case "Verify": ...
case "Cancel": ...
}
}
Change this #using (Html.BeginForm("SubmitForm", "HomeController", FormMethod.Post, new { id = "submitForm" }))
to
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
Explanation : No need to suffix Controller anywhere, it being accepted by default
and in the Controller
[HttpPost]
public ActionResult SubmitForm(string id)
{
return View();
}
Explanation : as the Form Method given by you is Post so need to include [HttpPost] before the Action and the parameter you were passing was missing in the action method

Not able to run another function for another button inside same view

I have got the two buttons in the same view one is working with the data to show in a label in another view and I have written the function for the button2 (adding another value), when I click on the button2 its not showing the data in view ..... rather it's giving error like this ... http:404 Resource not found error
and this is the view
#model MvcSampleApplication.Models.products
#{
ViewBag.Title = "Valuesadd";
}
<h2>Valuesadd</h2>
#using (Html.BeginForm("SubmitValue","EnterValue",FormMethod.Post))
{
<div>
<fieldset>
<legend>Enter Textbox Value</legend>
<div class ="editor-label">
#Html.LabelFor(m => m.EnteredValue)
</div>
<div class="editor-field">
#Html.TextBoxFor(m=>m.EnteredValue)
</div>
<p>
<input type="submit" value="Submit1" />
</p>
</fieldset>
</div>
}
#using (Html.BeginForm("SubmitValue2","EnterValue",FormMethod.Post))
{
<p>
<input type="submit" value="Submit2" />
</p>
}
and this is the controller for
namespace MvcSampleApplication.Controllers
{
public class EnterValueController : Controller
{
[HttpPost]
public ActionResult SubmitValue(MvcSampleApplication.Models.products model)
{
TempData["logindata"] = model.EnteredValue;
return RedirectToAction("submittedvalues" , "SubmitValue2");
// how can we redirect to another view when the button is clicked in one view
}
public ActionResult submittedvalues()
{
var model = new MvcSampleApplication.Models.category();
string data = TempData["logindata"] != null ? TempData["logindata"].ToString() : "";
model.lablvalue = data;
return View(model);
}
// action for second button click
public ActionResult submittedvalues2()
{
var model = new MvcSampleApplication.Models.category();
string data = TempData["logindata"] != null ? TempData["logindata"].ToString() : "";
model.lablvalue = "HIIII"+data;
return View(model);
}
}
}
would you pls suggest any idea ..
Many thanks...
Your form action and action in the controller are not named the same. Also you don't have a HttpPostfor it
#using (Html.BeginForm("SubmitValue2","EnterValue",FormMethod.Post))
{
}
//add this
[HttpPost]
public ActionResult submittedvalues2()
{
var model = SOMETHING;
return View("submittedvalues", model);
}
or
[HttpPost]
public ActionResult submittedvalues2()
{
//Do your post actions and redirect to action
return RedirectToAction("submittedvalues");
}
SubmitValue2 in the form should be submittedvalues2, and add a HttpPost attribute on it

MVC 4. ModelState.IsValid always return true

I don't understand why ModelState.isValid give me in all the ways. I set something in the email returns true and I pùt empty field, it returns true too. My question ism, what do I have to do to return true when the field is empty and nothing whn I wrote the email?
I have the next view file:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div style="padding-top:5px;clear:both;"></div>
<% using (Html.BeginForm()) { %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Email usuario</legend>
<div class="editor-field">
<%: Html.TextBoxFor(m => m.Email) %>
<%: Html.ValidationMessageFor(m => m.Email) %>
</div>
<input type="submit" value="Enviar Email" />
</fieldset>
<% } %>
<div style="padding-top:5px;clear:both;"></div>
</asp:Content>
The Controller is:
//
// GET: /Account/EmailRequest
public ActionResult EmailRequest()
{
return View();
}
[HttpPost]
public ActionResult EmailRequest(string email)
{
if (ModelState.IsValid)
{
// save to db, for instance
return RedirectToAction("AnotherAction");
}
return View();
}
My model class is:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Security;
namespace PortalClient.Models
{
public class EmailRequest
{
[Required(ErrorMessage = "required")]
public string Email { get; set; }
}
}
Change the signature of your post action from string email to EmailRequest model and then check the state. e.g.
[HttpPost]
public ActionResult EmailRequest(EmailRequest model)
{
if (ModelState.IsValid)
{
// save to db, for instance
return RedirectToAction("AnotherAction");
}
return View();
}
You need to bind a view model to your view.
Change your EmailRequest model to something more descriptive like:
public class EmailRequestViewModel
{
[Required(ErrorMessage = "Required")]
public string Email { get; set; }
}
Your get action method would look something like:
public ActionResult EmailRequest()
{
EmailRequestViewModel viewModel = new EmailRequestViewModel();
return View(viewModel);
}
Your post action method:
public ActionResult EmailRequest(EmailRequestViewModel viewModel)
{
// Check for null view model
if (!ModelState.IsValid)
{
return View(viewModel);
}
// Do whatever you need to do
return RedirectToAction("List");
}
And then your view. Please excuse the ASP.NET MVC 4 code, MVC 2 is prehistoric :) This is just part of your view:
#model YourProject.ViewModels.EmailRequestViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(x => x.Email)
#Html.ValidationMessageFor(x => x.Email)
}
I hope this helps.
you need to bind your model with binder first to have ability to chek it by Modelstat.IsValid
public ActionResult EmailRequest()
{
EmailRequest email = new EmailRequest();
TryUpdateModel(email);
if (ModelState.IsValid)
{
// save to db, for instance
return RedirectToAction("AnotherAction");
}
return View();
}

Categories

Resources