I have this index view:
#model LeadManager.Models.ProspectingApprovalViewModel
#{
ViewBag.Title = "Index";
}
<h2>Approve Or Reject</h2>
<div class="form-horizontal">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-group">
<div>
<input type="submit" name="ApprovalAction" value="Approve" class="btn btn-default" />
<input type="submit" name="ApprovalAction" value="Reject" class="btn btn-default" />
</div>
</div>
}
</div>
//model details are below form
I am trying to read the model inside controller like so:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(ProspectingApprovalViewModel prospectingApprovalViewModel, string ApprovalAction)
{
//access model
}
I can read ApprovalAction but the prospectingApprovalViewModel is null on the postback.
Why is the model not being attached?
Your helper must be inside the form.
When you use two class in parameter in name of html helper must be
name="className.propetyName".
When you want to post two classes you must use ViewModel.
Related
I'm using to wrap my forms the following helper:
#using (Html.BeginForm("Edit", "MyController", FormMethod.Post)) { ... }
In my Controller I have two methods, one for loading my partial view and another one for processing the Post request:
[SomeFilter]
[ChildActionOnly]
[AcceptVerbs(HttpVerbs.Get)]
public PartialViewResult Edit(int id)
{
//Some Code
}
[SomeFilter]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MyViewModel model, string submit) {
//Some Code
}
Everything seems to be working fine except when users submit an empty form. In that case request is being caught by GET Method instead of POST one. I know it's calling the GET method because I get an exception as:
"The action 'Edit' is accessible only by a child request."
And only the GET overload has [ChildActionOnly] filter. I don't understand why is this happening. Both are different and both are decorated.
Any suggestions?
Partial View code:
#model MVC.Models.MyViewModel
#using (Html.BeginForm("Edit", "MyController", FormMethod.Post))
{
#Html.HiddenFor(m => m.Id)
#Html.AntiForgeryToken()
<div class="row margin-top-20 form-group text-center">
<div class="col-md-3 col-lg-offset-2">
#Html.LabelFor(m => m.ManyItemsAvailable)
#Html.ListBox("ManyItemsAvailable", Model.ItemsAvailable)
</div>
<input type="submit" class="btn btn-default" value=">" id="add" name="submit" />
<input type="submit" class="btn btn-default margin-top-10" value="<" id="remove" name="submit" />
<div class="col-md-3">
#Html.LabelFor(m => m.ManyItemsSelected)
#Html.ListBox("ManyItemsSelected", Model.ItemsSelected)
</div>
</div>
}
So, I replaced both submit buttons with these:
<input type="submit" class="btn btn-default" value=">" id="add" name="submit" />
<input type="submit" class="btn btn-default margin-top-10" value="<" id="remove" name="submit" formmethod="post" />
Explicitly specifying formmethod="post" and it's now working as expected.
Hey Guys I have a problem with my ASP.NET MVC Application. I want to make a Search textfield and a image button in my application. If I input a valu in the textfield I want use this value for search in a list and send the result to the View. I use bootstrap because it looks fine.
here is my code: Index.cshtml
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Search", "HomeController"))
{
<div class="container">
<div class="row">
<h2>Suche</h2>
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" id="txtSearch" class=" search-query form-control" placeholder="Search" name="txtSearch" />
<span class="input-group-btn">
<button class="btn btn-danger" type="submit">
<span class=" glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
</div>
</div>
}
Here is my Controller:
[HttpPost]
public ActionResult Search(string txt)
{
List<string> petList = new List<string>();
petList.Add(txt);
ViewBag.liste = petList;
return View();
}
Your input does not have a name attribute that matches the parameter in the method so it is not bound. Change it to
<input type="text" id="txtSearch" class="..." name="txt" />
or change the method to match the current name attribute
[HttpPost]
public ActionResult Search(string txtSearch)
Side note: Assuming your controller is named HomeController then it should be #using (Html.BeginForm("Search", "Home")), not #using (Html.BeginForm("Search", "HomeController")) (which would only work if you have a controller named HomeControllerController)
I am passing a list of model in the View page and only editing the Answer property of the model. But after postback all the properties are set to null except Answer property.
Here is the View Code.
#model List<NewsLetter.Models.NewsLetterQuestions>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
for (var i = 0; i < Model.Count(); i++)
{
<div>
#Html.DisplayFor(m => m[i].Question)
</div>
<div>
#Html.EditorFor(m => m[i].Answer)
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</div>
}
Any help will be appreciable.
That is how the model binding is supposed to work. It will create NewsLetterQuestions objects and set the properties your form send to the controller action. See Introduction to ASP.NET MVC Model Binding for an explanation with examples.
If you need to post additional model data from your view to the controller you can use Html.HiddenFor(model => model.SomeProperty). See What does Html.HiddenFor do? for an explanation.
The DisplayFor() does not returns anything. You could use the below code.
#model List<NewsLetter.Models.NewsLetterQuestions>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
for (var i = 0; i < Model.Count(); i++)
{
<div>
#Html.TextBoxFor(m => m[i].Question, new {#readonly = "readonly"})
</div>
<div>
#Html.EditorFor(m => m[i].Answer)
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</div>
}
Hope this helps
I have an ASP.NET project and I have some checkbox to select the recurrence. I want to convert that to a string that will display it.
A simple version is
Create.cshtml
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<p style="font-weight:bold">New Record</p>
<div id="date">
<input type="checkbox" value="Sunday" />Sunday
<input type="checkbox" value="Monday" />Monday
<input type="checkbox" value="Tuesday" />Tuesday
...
</div>
<p>
<input type="submit" value="Create" />
</p>
<div align="left">
<font color="black" size="4" > #Html.ActionLink("<<Back to List", "Index", "Home", null, null)</font>
</div>
</fieldset>
}
And I want to save it in the model as a simple string like "1011011"
Standard Create function
[HttpPost]
public ActionResult Create(Event event)
{
if (ModelState.IsValid)
{
using (var context = new EventDBContext())
{
context.RecordList.Add(event);
context.SaveChanges();
}
return View("Index");
}
return View("Error");
}
What is the proper way to do this?
Utilize the CheckBoxFor Input extension
There are all sorts of walkthroughs on using them.
I am having an issue getting data in my model on my MakePayment.cshmtl view.
The AccountScreen.cshtml is calling the MakePayment.cshtml view:
#model SuburbanCustPortal.SuburbanService.CustomerData
#{
ViewBag.Title = "Account Screen";
}
<h2>AccountScreen</h2>
<div class="leftdiv">
<fieldset>
<legend>customer info</legend>
#Html.Partial("CustomerInfoPartialView", Model)
</fieldset>
<fieldset>
<legend>delivery address</legend>
#Html.Partial("DeliveryAddressPartialView", Model)
</fieldset>
<fieldset>
<legend>delivery info</legend>
#Html.Partial("DeliveryInfoPartialView", Model)
</fieldset>
</div>
<div class="rightdiv">
<fieldset>
<legend>balance</legend>
<div>
#Html.Partial("BalancePartialView", Model)
</div>
</fieldset>
<fieldset>
<legend>payment</legend>
<div>
#Html.Partial("MakePayment", Model)
</div>
</fieldset>
<fieldset>
<legend>billing info</legend>
<div>
#Html.Partial("BillingInfoPartialView", Model)
</div>
</fieldset>
</div>
My MakePayment.cshtml view:
#model SuburbanCustPortal.SuburbanService.CustomerData
#using (Html.BeginForm("MakePayment2", "Customer", FormMethod.Post))
{
<div style="text-align:center;">
<input class="makePaymentInput" type="submit" value="Make a Payment" />
</div>
}
My CustomerController:
public ActionResult AccountScreen(LogOnModel model)
{
return ShowCustomer(model.AccountNumber);
}
public ActionResult MakePayment(CustomerData model)
{
return View("MakePayment", model);
}
[HttpPost]
public ActionResult MakePayment2(CustomerData model)
{
//CustomerData model = new CustomerData();
var newmodel = new PaymentModel.SendToGateway();
newmodel.AccountBalance = model.TotalBalance;
newmodel.Amount = model.TotalBalance;
return RedirectToAction("PrePayment", "Payment", newmodel);
}
The public ActionResult MakePayment(CustomerData model) is never being reached.
My problem: The [HttpPost] public ActionResult MakePayment2(CustomerData model) is being reached but the model has nulls in it.
I know the data initial model from the AccountScreen is being populated since the other views that are being rendered is showing data.
Anyone see what I am doing wrong?
The problem is there's nothing inside your form except a submit button. You need to make sure input fields are there (either text boxes, select lists, or hidden fields), as those are what post data back to the controller.
You could try using EditorForModel inside your partial view:
#using (Html.BeginForm("MakePayment2", "Customer", FormMethod.Post))
{
#Html.EditorForModel()
<div style="text-align:center;">
<input class="makePaymentInput" type="submit" value="Make a Payment" />
</div>
}
Edit based on comments
Razor doesn't include an Html.HiddenForModel() method, for whatever reason. Possible workarounds:
List out each property of the model using Html.HiddenFor(model => model.Property)
Annotate the model properties with \[HiddenInput\]
Use EditorForModel() but wrap it in <div style="display: none;"></div> (NOTE that a malicious user can still modify the properties as if they were visible.)
Use only Html.HiddenFor(model => model.id) and fetch the model in the controller.
Use the serialization method in the MVC Futures assembly
Related quesion here:
Is there some way to use #Html.HiddenFor for complete model?
The problem is, you are creating a form containing nothing else than a submit button.
When you submit it, it posts nothing back to the server, thus your function receives an empty model.
#using (Html.BeginForm("MakePayment2", "Customer", FormMethod.Post))
{
<div style="text-align:center;">
<input class="makePaymentInput" type="submit" value="Make a Payment" />
</div>
}
This translates as :
<form method="POST" action="{url}">
<div style="text-align:center;">
<input class="makePaymentInput" type="submit" value="Make a Payment" />
</div>
</form>
More details :
Since in the logic you then redirect to a new page to collect payment information, you don't want to give the user the opportunity to mess with your model, thus you should query your customer data from your Context instead of trusting what is submitted in the POST.
Thus all you really need to add if this :
#using (Html.BeginForm("MakePayment2", "Customer", FormMethod.Post))
{
#Html.HiddenFor(model => model.{ID Field})
<div style="text-align:center;">
<input class="makePaymentInput" type="submit" value="Make a Payment" />
</div>
}
This way, you will be able to get your model back in the server side code.
Basically, your form submits nothing as there are no input fields inside the form scope. Try to wrap all your html in AccountScreen.cshtml within #using (Html.BeginForm( statement (and throw it out from MakePayment.cshtml).