I am working on an MVC application and I have an index view where I pass model from controller to index view. The index action has no parameters. Now On view I have a jquery calendar. I want to change all the data on view when a date is selected. do I need to use different action method for this as current action method doesn't have parameter. or I can use same ? Please suggest
Sounds like you need a DateTime parameter on that index view. You can then handle the case where it is null in the action:
public ActionResult Index(DateTime dateTime)
{
if (dateTime == null)
//Do default view
else
//Use date for view
}
Use a client-side event handler on the calendar, and call a different action on the controller via jQuery.ajax()
http://api.jquery.com/jQuery.ajax/
You can create the same Action method to handle both:
[HttpGet]
public ActionResult DoThis() { }
[HttpPost]
public ActionResult DoThis(FormCollection data) { }
It can be the same action, but it has to be a different action handler to handle the post to the server, where the post is from a form or a JQuery call.
Related
Can i send to the action method new record and then get the new id by the same method
public class HomeController : Controller
{
[HttpGet]
[HttpPost]
public JsonResult _sendConfirmation'(string subject,string mail)
{
Some Code--Some Code---Some Code
return Json(new { Success = true, id = newCreatedMailId });
}
}
Getting the id by jquery
$.getJSON('/Mails/_sendConfirmation', function (comingData) {
alert("success" + data);
jQuery.get('/Mails/_getNewMailSendConfirmation', { id: comingData }, function (data) {
jQuery('#myModal').modal('show');
jQuery('#myModal .modal-body').html(data);
});
enter code here
So your Ajax request is looking for an action named _sendConfirmation on your Mails controller and not finding it but you've chose. To just show us your home controller index action so we have no idea if the appropriate controller exists or not with that.
As far as having it decorated with a get and a post, when you do this you are essentially telling the action to look for data on the request in two different places which will most likely not end well for you unless you plan on doing that switch logic yourself inside the action. Your code would probably be a bit less error prone if you seperated the action and once extracted the data, you call the same helper methods to work your data.
I'm having a problem where the action in my controller called GiftCards is over-writing the actual URL/View page name.
public IActionResult SomeStupidName()
{
return ("Checkout");
}
my url turns into
www.mywebsite.com/GiftCards/SomeStupidName
while I want it to be
www.mywebsite.com/GiftCards/Checkout
Some further detail would be that this is execute with an form-submit where the form has an
asp-action="SomeStupidName"
You have to understand that www.mywebsite.com/GiftCards/SomeStupidName means SomeStupidName is an action of controller GiftCards so www.mywebsite.com/GiftCards/Checkout means Checkout is an action of controller GiftCards but in your code you are returning View from GiftCards action not redirecting to other action. Lets suppose I have action name Checkout.
public IActionResult Checkout()
{
return View("Checkout");
}
It will return the view Checkout when I enter www.mywebsite.com/GiftCards/Checkout so now I can redirect to action from any other action like:
public IActionResult SomeStupidName()
{
return RedirectToAction("Checkout");
}
You can use "Attribute Routing" in Asp.Net Core. Return the proper view in your controller.Try this code !!
[Route("GiftCards/Checkout")]
public IActionResult SomeStupidName()
{
return View("Checkout");
}
Attribute routing is set of attributes to map actions directly to route templates. We can mention rewrite url inside the "()" in "[Route("")]" Attribute.
More details about attribute routing in Asp.net core : click here
Scenario: How to update a model?
ASP MVC 6
I am trying to update a model. For passing the model information to the client(browser/app) I am using the DTO.
Question 1: For updating, should I post the whole object back?
Question 2: Is there a way I can easily pass only the information that is updated? If yes, how?
Question 3: Can I use JSON Patch for updation?
Question 2: Is there a way I can easily pass only the information that
is updated? If yes, how?
Yes. You should create a view model which should have only those properties needed for the view.
Let's assume your use case is to build a view which allows user to edit only their last name.
public class EditUserViewModel
{
public int Id {set;get;}
public string LastName {set;get;}
}
And in your Get
public ActionResult Edit(int id)
{
var user = yourUserRepository.GetUser(id);
if(user!=null)
{
var v = new EditUserViewModel { Id=id,LastName=user.LastName};
return View(v);
}
return View("NotFound");
}
And the view
#model EditUserViewModel
#using(Html.BeginForm())
{
#Html.TextBoxFor(s=>S.LastName)
#Html.HiddenFor(s=>s.Id)
<input type="submit" id="saveBtn" />
}
and your HttpPost action
[HttpPost]
public ActionResult Edit(EditUserViewModel model)
{
// Since you know you want to update the LastName only,
// read model.LastName and use that
var existingUser = yourUserRepository.GetUser(model.Id);
existingUser.LastName = model.LastName;
yourUserRepository.Save();
// TO DO: redirect to success page
}
Assuming yourUserRepository is an object of your data access classes abstraction.
Question 1: For updating, should I post the whole object back?
Depends on what you want from the end user. With this view model approach, It is going to post only the Id and LastName and that is our use case.
Can I use JSON Patch for updating?
Since you are only sending the data which needs to be updated (partial data), you should be fine.
If you want,you may simply serialize your form data(which has only Id and LastName) and use jQuery post method to send it to your server.
$(function(){
$("#saveBtn").click(function(e){
e.preventDefault(); //prevent default form submit
var _form=$(this).closest("form");
$.post(_form.attr("action"),_form.serialize(),function(res){
//do something with the response.
});
});
});
To prevent overposting, you can use a binding whitelist using Bind attribute on your HttpPost action method. But the safest strategy is to use a view model class that exactly matches what the client is allowed to send.
Instead of this
UpdateModel(model);
You now can call this
await TryUpdateModelAsync(model);
After form submit Html editor helpers (TextBox, Editor, TextArea) display old value not a current value of model.text
Display helpers (Display, DisplayText) display proper value.
Is there any way editor helpers to display current model.text value?
Model
namespace TestProject.Models
{
public class FormField
{
public string text { get;set; }
}
}
Controller
using System.Web.Mvc;
namespace TestProject.Controllers
{
public class FormFieldController : Controller
{
public ActionResult Index (Models.FormField model=null)
{
model.text += "_changed";
return View(model);
}
}
}
View
#model TestProject.Models.FormField
#using (Html.BeginForm()){
<div>
#Html.DisplayFor(m => m.text)
</div>
<div>
#Html.TextBoxFor(m => m.text)
</div>
<input type="submit" />
}
When you submit the form to an MVC action the values of the input fields are recovered from the POSTEd values available in the form and not from the model. That makes sense right? We don't want the user to show a different value in a textbox than they have just entered and submitted to the server.
If you want to show the updated model to the user then you should have another action and from the post action you have to redirect to that action.
Basically you should have two actions one action that renders the view to edit the model and another one saves the model to database or whatever and redirect the request to the former action.
An example:
public class FormFieldController : Controller
{
// action returns a view to edit the model
public ActionResult Edit(int id)
{
var model = .. get from db based on id
return View(model);
}
// action saves the updated model and redirects to the above action
// again for editing the model
[HttpPost]
public ActionResult Edit(SomeModel model)
{
// save to db
return RedirectToAction("Edit");
}
}
When using HTML editors such as HTML.EditorFor() or HTML.DisplayFor(), if you attempt to modify or change the model values in the controller action you won't see any change unless you remove the ModelState for the model property you want to change.
While #Mark is correct, you don't have to have a separate controller action (but you usually would want to) and you don't need to redirect to the original action.
e.g. - call ModelState.Remove(modelPropertyName)...
public ActionResult Index (Models.FormField model=null)
{
ModelState.Remove("text");
model.text += "_changed";
return View(model);
}
And if you want to have separate actions for GET and POST (recommended) you can do...
public ActionResult Index ()
{
Models.FormField model = new Models.FormField(); // or get from database etc.
// set up your model defaults, etc. here if needed
return View(model);
}
[HttpPost] // Attribute means this action method will be used when the form is posted
public ActionResult Index (Models.FormField model)
{
// Validate your model etc. here if needed ...
ModelState.Remove("text"); // Remove the ModelState so that Html Editors etc. will update
model.text += "_changed"; // Make any changes we want
return View(model);
}
I had some similar problem, I hope I can help others have similar problem:
ActionExecutingContext has Controller.ViewData.
as you can see:
new ActionExecutingContext().Controller.ViewData
This ViewData contains ModelState and Model. The ModelState shows the state of model has passed to controller for example. When you have an error on ModelState the unacceptable Model and its state passed to View. So you will see the old value, yet. Then you have to change the Model value of ModelState manually.
for example for clearing a data:
ModelState.SetModelValue("MyDateTime", new ValueProviderResult("", "", CultureInfo.CurrentCulture));
Also you can manipulate the ViewData, as here.
The EditorFor, DisplayFor() and etc, use this ViewData contents.
Date:
model.Date) %>--%> // Should I use this as Input type?
Number#:
Comment
I am trying to get these three fields on the screen while user enters I am retreving the user enter data on front end.. when I am debugging I am not seeing these fields..
On the view I am using beginForm
<% using (Html.BeginForm("Update", "Home", FormMethod.Post, new { #id = "id" }))
{ %>
my method..
public JsonResult Update(StudentInfo info)
{
///Update
return Json(Status.ToString());
}
when I see in info I am not getting these three fields..
can any one help me out thanks
You are returning a JsonResult but doing as Http post (Html.BeginForm). If you want to use a full form post then return a ActionResult.
public ActionResult Index()
{
// Add action logic here
return View();
}
you can call void controller
It makes no sense that you're returning a JsonResult from a HTML Post.
Do this instead.
[HttpPost]
public ActionResult Update(StudentInfo info)
{
///Update
if (updateWorked)
return View("Success", status);
}
You use JsonResult when you want to call a controller that returns JSON data, in order to display this data somewhere on your page.
A useful scenario for JsonResult in your scenario would be returning a json list of Students, executed from a click event maybe (call in JavaScript/jQuery).
Calling an action method on a HTTP Post which returns a JsonResult of a single string (not real JSON) makes no sense.