If I am using an Ajax.ActionLink helper, and I need to pass a couple parameters to the controller action, how can I get the value of a TextArea that is not bound to a model?
For instance, I want the user to fill out a textarea, and then click Save, sending the textarea value to the controller action for further processing.
Do I use ViewBag? If so, how do I assign the value of a DOM element to ViewBag?
I've toyed with this problem before, and you can get around it by using Ajax.BeginForm.
Take this follow example:
I have a model Person that one string property for Name.
View
#model Application.Models.Person
<fieldset>
<legend>Form</legend>
#using (Ajax.BeginForm("SendUp", "Home", new AjaxOptions
{
HttpMethod = "POST",
OnComplete = "window.location.href = 'Index'"
}))
{
<p>
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
</p>
<p>
#Html.TextArea("ta")
</p>
<p>
<input type="submit" value="Submit" />
</p>
}
</fieldset>
Controller
[HttpPost]
public ActionResult SendUp(string Name, string ta)
{
string s = ta;
// Process stuff here
// Go to another action or whatever
return RedirectToAction("Index");
}
Using Ajax.BeginForm() allows you to send data up to the controller even if it not bound to a model on the page. You need to make sure that the name property of your Html element is the same name as the parameter that the controller needs.
So if you have the controller method of
public ActionResult SendUp(string Name, string ta)
You will need to have an Html element of with the name Name and ta inside of the Ajax.BeginForm().
To do this you can either write out the entire element:
<input type="text" id="Name" name="Name" />
Or you can use the #Html helpers.
#Html.Editor("Name")
When you provide the name for the #Html helper it will set that value to as the id property and to the name property as well.
ViewBag is a server-side concept. It does not exist once the page has been rendered.
There is no way that I know of to declaratively link a field on the page with an action parameter.
To do what you want you have two options:
- get rid of the Ajax.ActionLink helper, and write some Javascript (sorry, Ican't really help you there)
- Use to Ajax.BeginForm instead and put the relevant fields in the form, so that a click on the submit button will submit the form back to your action through ajax.
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...
The main problem is that a method from controller is not called when i press a button.
I have this in my Index view for MyController :
#using (Html.BeginForm())
{
#* .... *#
<form action="DoSomethingAction" method="post">
<input type="text" id="IdString" name="IdString" placeholder="Enter id"/>
<input id="Submit1" name="Submit1" type="submit" value="DoSomething1" />
<input id="Submit2" name="Submit2" type="submit" value="DoSomething2" />
</form>
#* ..... *#
}
In MyController I have DoSomethingAction method. I want to call this method and be able to see IdString when I press a button: DoSomething1 or DoSomething2. This is DoSomethingAction method from controller:
public ActionResult DoSomethingAction()
{
string id= Request.Form["IdString"];
//string button=...
// ...
}
When I put a breakpoint for DoSomethingAction method, I observed that it's never called.
I tried to put [Httppost] attribute for this method, but it didn't solve my problem.
What am I doing wrong?
After that, how can I see in DoSomethingAction method which button was pressed?
a HTML form can not nest a HTML form. Please read https://www.w3.org/TR/html5/forms.html#the-form-element
If you need multiple form you can define them as siblings.
Either use html.BeginForm or type="Submit". Next thing to keep in mind, html.BeginForm is a post method, so if u want to use it, give an attribute over Action and if u don't state what view action should return, he will assume that view is of the same name as action, in ur case DoSomethingAction, that's why u get server error. Either make that view or state in return View() which view u want to return (Index or some other).
I am unable to post data from a form to a controller action. I've created the form with HTML.BeginForm() and I have a controller which works fine when I manually create the query string, but I don't understand how to make a form work with my controller action.
<form class="navbar-form navbar-left">
<div class="form-group>
#using (Html.BeginForm("GeneralSearch", "Search", FormMethod.Post))
{
#Html.TextBox("searchString")
<button type="submit" class="default">Submit</button>
}
</div>
</form>
And then in my controller I currently have the HttpGet attribute that ASP.NET automatically placed there. However, if I change it to HttpPost the problem still occurs.
[HttpGet]
public ActionResult GeneralSearch(string searchString)
{
return View("SearchResult", viewModel);
}
When I enter text and submit the form, a network request is sent to:
http://localhost:64562/?searchString=test
Which simply loads the default controller and action instead of the "Search" controller I specified in the using statement. How do I correctly post to a specific action?
Html.BeginForm( adds a <Form> tag but I see you are trying to add the form tag inside another form tag as seen below; which is wrong.
<form class="navbar-form navbar-left">
<div class="form-group>
#using (Html.BeginForm("GeneralSearch", "Search",
Again, your controller must expose different action method to cater GET and POST request and you should rather have
public ActionResult GeneralSearch()
{
return View();
}
[HttpPost]
public ActionResult GeneralSearch(string searchString)
{
return View("SearchResult", viewModel);
}
You are POSTing to a method that is listening to GET.
Switch the FormMethod
#using (Html.BeginForm("GeneralSearch", "Search", FormMethod.Get))
I have a page with partial view that contains DevEx ComboBox with Add button and DevEx GridView ( I omitted GridView code). Page is showing properly with that partial view, only I have a problem with refreshing it.
//_ProductAppsGridViewPartial
<div class="form-horizontal">
<h4>Apps</h4>
#using (Html.BeginForm("AppsGridViewPartialAddNew", "Products", new { ProductID = ViewBag.ProductID }))
{
<div class="form-group">
<h5>Add new App:</h5>
#Html.DevExpress().ComboBox(settings =>
{
//..do some settings for ComboBox - some code omitted
settings.Properties.ValueField = "ApplicationID";
settings.Properties.TextField = "Name";
}).BindList(Model.AppsNotInProduct).GetHtml()
<input type="submit" value="Add" class="btn btn-default" />
</div>
}
</div>
I have action on my controller that adds selected app in database and returns a PartialView with the same (but refreshed) model, but response shows only that partial View. Here is a part of Controller's action that returns PartialView after updating database:
public ActionResult ProductAppsGridViewPartialAddNew(int ProductID)
{
//....update DB code - WORKS FINE
..
var model = GetProductAppsPartialModel(ProductID);
ViewBag.ProductID = ProductID;
ViewBag.CanEdit = true;
return PartialView("_ProductAppsGridViewPartial", model);
}
Is it possible to refresh a partial view wihout AJAX, maybe something i wrote above? So the main problem here is that i get new page showing only a partial view.
To refresh part of a page you will need to use ajax to replace only the needed content. You will also need to use JavaScript to re-render the HTML contained in the partial. MVC comes with some ajax helpers or you can do it yourself with jquery. At the moment the action result is returning the partial as requested but the browser is being told it is receiving a whole new page and is displaying as such.
Adding this link to Microsoft ajax to show some of your options.
I would use jquery and do this yourself. Also try to remember that mvc is a server side framework to help you return http messages to the browser. You are trying to manipulate things client side. Live client side updates always need ajax to get data. Replacing items in the DOM needs some form of JavaScript. Libraries like jquery make this a lot easier. Have a look at jquery ajax here.
I think you need to try this code.
Note here we need to keep ajax call for update the partial view
#using (Ajax.BeginForm("ActionName", "Controller", new { model = #Model.ID },
new AjaxOptions
{
OnSuccess = "onSuccessRefresh "
}))
{
<table>
<td>
</td>
<td> <input type="button" value="AddValue" /> </td>
</table>
}
Handle the code onsuccess event using jquery:-
function onSuccessRefresh {
// refersh your page or table
}
This is not the full code. but I think it will help to you
I am using ASP.NET MVC to post a strong typed view to a controller this way:
#using MyApp.Model
#model UserTest
#{
Layout = null;
}
#using (Html.BeginForm())
{
<div>
<p>Name: #Html.TextBoxFor(u => u.Data, new { Name = "txtName" })</p>
</div>
<div style="clear:left; padding-top: 15px">
<input type="submit" value="Create" id="btnSubmit" />
</div>
}
On the Controller:
[HttpPost]
public ActionResult Create(UserTest userdata)
{
}
When I post the form, the userdata received has its only property as a null value
But, if I remove the htmlAttribute that changes the name property of the textbox this way:
#using (Html.BeginForm())
{
<div>
<p>Name: #Html.TextBoxFor(u => u.Data)</p>
</div>
<div style="clear:left; padding-top: 15px">
<input type="submit" value="Create" id="btnSubmit" />
</div>
}
When I post the form, the userdata received has a valid property with a value that is correctly bind.
I wonder if I am missing something here because this looks like a bug. If this is the case, should I avoid changing the names of the generated HTML objects on the MVC helpers altogether?.
The version of MVC I have is 5.2.2.0 and the runtime version of the framework is: v4.0.30319
I appreciate the insight on this.
This is not a bug. This is expected behaviour.
Model binding works by binding the key/value pairs sent by the browser in a form post to model properties (or view data). A form input's name attribute is what is used as its key in the form data submitted in a POST request.
When you use HTML helpers to render form fields, the framework automatically generates the appropriate name attributes required to ensure that the field will bind properly to the property specified in the expression you pass to the helper.
If you change the name, you break the only connection between the form input and the property it binds to.
should I avoid changing the names of the generated HTML objects on the MVC helpers altogether?.
Yes. The input elements' names are what makes model binding work.
So no, not a bug. Don't change them.
You don't explain why you want to change them, but you may be able to use a different attribute to accomplish what you want.