I'll admit I'm new to MVC and this question might be a single case of RTFM. But I'm googling this problem and I can't seem to find a solution.
I've got a simple view used to fill out some details for a specific model. I need to render part of the form using Html.Partial (in truth this is a wrapper which renders old non-MVC controls used from another project).
I've no problems getting data FROM the controller INTO the view.
So what's the issue? How do I get user input from the partial view back to the controller after the user pressed the submit button?
Here's the view and controller I've currently got:
#model Poll
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Poll</h4>
<hr />
#*#Html.ValidationSummary(true)*#
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.Name)
#Html.Partial("~/ControlPlaceholder/QuestionPlaceholder.ascx", Model, new ViewDataDictionary(Model))
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Fill" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The view has been copied almost one-to-one from the standard generated edit view available in MVC5. Note that this is currently just a PoC - normally the whole thing should render a QuestionPlaceholder for every question in a Poll.
Here's the relevant part of the controller:
//
// GET: /Poll/Fill
[HttpGet]
public ActionResult Fill(Guid id)
{
var poll = pollRepository.Get(id);
return View(poll);
}
//
// POST: /Poll/Fill
[HttpPost]
public ActionResult Fill(Poll poll, FormCollection collection)
{
try
{
return RedirectToAction("Index");
}
catch
{
return View(poll);
}
}
it is so simple, just set name of inputs same as corresponding action parameters and let MVC ModelBinder do it's job. it's not important to render a partial in the form, it's input elements value would be passed to the action on submitting form.
another way is to use Request.Form["InputName"] that is not my first recommendation.
Related
I am creating a Live Chat web page in Razor Pages with c#.
I have a cshtml form that contains the gui.
#page
#model Project.Pages.LiveChatModel
#{
ViewData["Title"] = "LiveChat";
Layout = "~/Pages/_LoggedIn.cshtml";
}
<div class="container">
<h2>Live Chat</h2>
<div id="enterName">
Enter your name: <input type="text" id="name" />
<button id="btnName">Save</button>
</div>
<div id="currentName">
Your Name:
</div>
<div id="supportName">
Support Name: Jeff
</div>
Chat History
<div id="messages">
</div>
<div>
<textarea id="message" name="Message" cols="100"></textarea>
<button id="sendMessage">Send</button>
</div>
</div>
What I want to do is use the C# model to get a value from the textarea that is sent and write it to a text file in the project folder.
Hope you can help.
Thanks
This describes the steps and the flow and should clarify the process and answer your question.
Model:
public class ChatModel
{
public string Message{ get; set; }
View:
#model ChatModel
#using (Html.BeginForm("SendMessage", "MessageController", FormMethod.Post}))
{
#Html.TextAreaFor(model => model.Message)
Controller:
public class MessageController : Controller
[HttpPost]
public ActionResult SendMessage(ChatModel viewModel)
{
var message = viewModel.Message;
// Code to save to file here
You have a model, a controller and a view.
The model declares the variables that will be used for binding.
In the View you declare your model and you set the properties of this model as shown above. It is 2 way binding, meaning that you can have values that come from the server initially and these values also go back to the server when you submit.
Example: if I set the value of property Message to "Hello, this is initial value". Then this will be shown to the client side.
Now if it is editable field, the user can change that value, e.g. "This is my message" and when the form that contains this element is submitted, the controller should have parameter of type ChatModel...then the ASP.Net engine will bind the values from the client side to the corresponding variables.
And yes...you will get the message value on the server and you can persist to anything you want, DB, file or transport further to another service...
I am trying to use Select2.js within my MVC 6 (Core) project, where if a user selects a value (or multiple values) within the first listbox, then they are then provided with an updated list of values within the second listbox. So for example... if a user selects "Ford" and "Renault" from the Manufacturer listbox, then they are only provided with relevant values in the Brand listbox e.g. Mondeo, Mustang, Clio, Megane etc.
My View syntax is:
#model MyProject.ViewModels.MyViewModel
<script type="text/javascript">
$(document).ready(function () {
$('#ManufacturerID').select2({
placeholder: 'Please make a selection...',
width: 500
});
$('#BrandID').select2({
placeholder: 'Please make a selection...',
width: 500
});
});
</script>
<form asp-action="Generation">
<div class="form-horizontal">
<div class="col-md-10">
#Html.ListBoxFor(model => model.ManufacturerID, Model.ManufacturerNames)
#Html.ListBoxFor(model => model.BrandID, Model.BrandNames)
</div>
</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>
</form>
If I click the submit button, the post action method successfully acquires a list of Manufacturer ID's:
// POST: MyController/Generation
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Generation(MyViewModel myViewModel, IEnumerable<int> manufacturerID)
{
return RedirectToAction("Generation");
}
But what I really want is something similar to AJAX Update Panel in Web Forms where the call to the controllers post action method is performed immediately on selecting an option from the listbox, not when the user clicks submit.
Your help is greatly appreciated.
Regards,
X22
$(document).ready(function(){
pageInit();
});
function pageInit(){
$('#ManufacturerNames').off();
$('#ManufacturerNames').on('change', function(e){
//ajax request here
//call pageInit() in your callback to reattach select2
//and event handler if you are fully replacing the dropdown.
});
$('#BrandNames').off();
$('#BrandNames').on('change', function(e){
//ajax request here
//same as callback above depending on how you go about doing this.
});
}
This is the manual way but since you are using a library like select2, they may provide an easy way to set this up in your initialization.
I've started with asp mvc 3, with c# and razor, then. I want to use forms with security for send petitions POST.
I want to with razor render some like that
<form action="/sass/" method="post">
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<div class="form-group">
<label>Ingresa tu Nombre</label>
<input class="form-control" name="nombre" />
</div>
<div class="form-group">
<input type="submit" value="Enviar mi duda" class="btn btn-primary btn-sm" />
</div>
}
And in C# I dont know how to validate that csrf token, is valid.
I work with C#, asp mvc3 and razor.
Please help me!
In your action method you need to add the respective attribute [ValidateAntiForgeryToken], and it validate the input for you.
You have a problem with the state of your code. There are two embedded forms: the outer one and the one produced by Html.BeginForm. However, the way to validate the token is to decorate the target action or controller with [ValidateAntiForgeryToken].
So either:
[ValidateAntiForgeryToken]
public ActionResult Index()
{
return View();
}
or to validate all methods in the controller:
[ValidateAntiForgeryToken]
public class MyController : Controller
{
}
I am learning MVC and creating a project management site, and am stuck on a couple key ideas. I have a complex model, which includes a summary of the project, and a list of tasks
public class SummaryAndCategoriesViewModel
{
public Project Summary { get; set; }
public IEnumerable<task> Tasks { get; set; }
}
Inside the tasks, i've created an EditorTemplate, so that the user can switch each task state (from 'not started' -> 'completed'. for example)
In may main 'details' View, i have two partial views:
#{var categories = ViewData["AllCategories"] as List<Models.category>;}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
<div class="form-horizontal">
<hr />
<div class="Summary">
#Html.LabelFor(item => Model.Summary )
#{Html.RenderPartial("_Summary", Model.Summary);}
</div>
<hr />
<div class="tasks">
#Html.LabelFor(item => Model.Tasks )
#{Html.RenderPartial("_Task", Model.Tasks);}
</div>
</div>
}
What I'd ideally like is that the 'summary' loads in the normal details view, which it does, while the 'tasks' loads in an edit mode, which i've done as well.
As of now, i'm stuck on two things:
1- I would like to be able to change only the 'summary' partial view to edit somewhow (modal popup could work too), and still perform httpPosts.
2- I would like the user to be able to change the 'tasks' partial view, and by clicking save, update the tasks in the database and refresh the 'tasks' partial. I've been reading up on the partials and renderpartials, but i'm a bit confused on which method I should be using, how to return the partial models to the HTTPPost, and how to switch the partial views.
Any guidance would be greately appreciated
I am beginner in MVC3 and building one application, i need to make confirmation page where all details of user will display for confirmation.
I have build wizards to fill this information using javascript & divs and in final wizard i would like to put all details which have been filled by user
#using (Html.BeginForm("Confirm", "Home", FormMethod.Get))
{
<div>
//user details goes here...
</div>
<input type="submit" name="name" value="confirm" />
}
how can i load data here?, i need to make some method call before form will render or something else? please guide me.
thanks in advance.
The best way would be to load those data in action that return this page. Load user data into a model object and pass that object to a view:
// Return view
return View( new SomeViewModel(userData));
And than you handle those data in view, like (Razor):
#this.Model.UserFirstName ...
#using (Html.BeginForm("Confirm", "Home", FormMethod.Get))
{
<div id="userDetailDiv">
</div>
<input type="submit" name="name" value="confirm" />
}
you can use .load
$(function(){
$("#userDetailDiv").load(#Url.Action('UserDetail'));
}
or you can use RenderAction
#using (Html.BeginForm("Confirm", "Home", FormMethod.Get))
{
<div id="userDetailDiv">
#Html.RenderAction("_UserDetail", "Cintroller");
</div>
<input type="submit" name="name" value="confirm" />
}