I have model:
public class MyModel
...fields
[Remote(ActionName, ControllerName)]
public string SomeNumber { get; set; }
..fields
And have a action in ControllerName controller:
public JsonResult ActionName(string someNumber)
{...}
But when actions is invoked the parameter someNumber is allways null.
And when I try to debug it I get
GET /ControllerName/ActionName?MyModel.SomeNumber =34189736
How can I make it work?
(I can't pass whole model MyModel, and cant change MyModel.SomeNumber name of field in my view)
UPD. Input in my view:
<input data-val="true" data-val-remote-additionalfields="*.SomeNumber" data-val-remote-url="/ControllerName/ActionName" id="MyModel_SomeNumber" name="MyModel.SomeNumber" type="text" value="34189734" class="valid">
UPD solved! :)
I create new model with single field SomeNumber and use prefix:
SomeNumber([Bind(Prefix = "MyModel")]MySingleFieldModel model)
If you're using nested ViewModels, you'll need to accept the parent ViewModel as the argument in your Validation action. For example:
public class ParentViewModel
{
public UserViewModel User {get; set; }
//....
}
public class UserViewModel
{
[Remote("UniqueUsername", "Validation")]
public string Username { get; set; }
//....
}
In ValidationController:
public class ValidationController : Controller
{
public JsonResult UniqueUsername(ParentViewModel Registration)
{
var Username = Registration.User.Username; //access the child view model property like so
//Validate and return JsonResult
}
}
Try using you model as the parameter.
So that it could bind the value to it.
public JsonResult ActionName(MyModel model)
{
//...
model.SomeNumber;
//...
return Json(validationResult, JsonRequestBehavior.AllowGet)
}
public JsonResult ActionName(string SomeNumber)
{...}
I think you may need to match case on your input parameter.
Related
Let's say that I have a Action method like this:
public ActionResult Page(int? id)
{
}
The question is, how can I read 'id' parameter in View?
Your code won't build successfully, until you return a view like this
public ActionResult Page(int? id)
{
return View();
}
and because you want to return id to your view you can do
Simple object
public ActionResult Page(int? id)
{
return View(id);
}
Just remember to accept the new value in your view, by dong the following at the top (very first line)
#model int?
ViewModel approach
public class MyViewModel
{
public int? Id { get; set; }
//Other properties here
}
public ActionResult Page(int? id)
{
var myViewModel = new MyViewModel()
{
Id = id
};
return View(myViewModel);
}
and then in your view
#model MyViewModel
You can access parameters from Request in view as below
Request.Params["id"]
I have this viewmodel that has some properties and stuff that i would like to apply
to the layoutpage:
public class BasicViewModel
{
public Page Page { get; set; }
public List<Settings> Settings { get; set; }
}
From other threads here have i understood that this is possible but i dont really understand how.
From what I understand I somehow need to modify a controller and this is where I get confused. How do I know what controller that has to be modified and how?
Any help appreciated.
In controller, Prepare an action like
public ActionResult BasicViewModelDemo
{
BasicViewModel obj=new BasicViewModel()
// assign properties
return View(obj);
}
and view write some jquery. (Here i am using knockout to make view model)
<script>
var model='#Html.Raw(Json.Encode(Model))';
var viewmodel = ko.mapping.fromJSON(model);
</script>
Here goes my solution -
Lets say you have a model of this way -
public class BasicViewModel
{
public Page Page { get; set; }
public List<Settings> Settings { get; set; }
}
public class Page
{
public string PageName { get; set; }
}
public class Settings
{
public string SettingName { get; set; }
}
Then in the controller you should initiate the model in this way -
public class HomeController : Controller
{
BasicViewModel model;
public HomeController()
{
model = new BasicViewModel();
model.Page = new Page();
model.Settings = new List<Settings>();
}
public ActionResult Index()
{
model.Page.PageName = "My Page";
ViewBag.LayoutModel = model;
return View();
}
}
So basically we used Constructor to initiate the model and then we assign proper values in the controller action.
Then in the Layout, we can use the Model property as shown below -
<div> #ViewBag.LayoutModel.Page.PageName </div>
If I have the following model:
public class Model
{
public int ModelID { get; set; }
public string Title { get; set; }
public DateTime Created { get; set; }
}
And the following controller method:
public ActionResult Create(Model model)
{
if (ModelState.IsValid)
{
model.Created = DateTime.Now;
// Save to DB
}
}
In the view the Created field is hidden as I want this to populate with the timestamp of when the Create controller method is called. This fails ModelState validation due to the model.Created property being null.
I don't want to make the model.Created property Nullable but I need to somehow specify that this field isn't required in the view. Can someone please advise how to accomplish this?
You'll want to exclude the Created property from binding using the [Bind] attribute, as follows:
public ActionResult Create([Bind(Exclude = "Created")] Model model)
{
....
}
It is also recommended for security reasons, as you don't want your client to set Created value for you.
I have to work with queries like:
Controller/Action?query ={"action":"test","id":"13037313353","pin":"452312"}
by GET.
My ViewModel:
public class ValidatePinViewModel
{
public ActionType action { get; set; }
public int Id { get; set; }
public int Pin { get; set; }
}
Controller
public JsonResult ValidateVisit(CommonViewModel model)
{
//model is null
return Json(new InvalidPin());
}
Now I got null for my view. How I can get the correct model
As there is very little supportive information on this question, I'm going to take a shot and say that you're not POSTING to an action. e.g.
[HttpPost] // <-- Make sure you define your POST action
public JsonResult ValidateVisit(CommonViewModel model)
{
...
}
A GET, as you speficy in your tags, is not going to post a model. Unless you are specifically denoting it both in where you define your form element as well as on the action itself, it will be null.
I could add a string to get object.
Something like:
public JsonResult ValidateVisit(string query)
{
ValidatePinViewModel model = Json.Deserialize<ValidatePinViewModel>(query);
return Json(new InvalidPin());
}
I use viewModels to communicate between my controller and my view.
To get model validation, i use a partial class like this :
[MetadataType(typeof(EvaluationValidation))]
public partial class Evaluation
{
public class EvaluationValidation
{
[DisplayName("Title of evaluation")]
[Required( ErrorMessage="Please give a title")]
public string Title { get; set; }
}
}
The Displayname is binded to view with no problem but when i try to submit the view, i get this error :
The model item passed into the
dictionary is of type
'FOOBAR.Models.Evaluation',
but this dictionary requires a model
item of type
'FOOBAR.Areas.Evaluation.ViewModels.EvaluationFormViewModel'.
This is the code used in my controller
[HttpPost]
public ActionResult Create(FormCollection formValues)
{
Models.Evaluation data = new Models.Evaluation();
if (TryUpdateModel(data, "evaluations"))
{
this.daoe.Create(data);
return RedirectToAction("Index");
}
return View(data);
}
And this is my viewModel
public class EvaluationFormViewModel
{
public FOOBAR.Models.Evaluation evaluations;
public SelectList selectlist_evaluationtypes { get; set; }
public SelectList selectlist_evaluationstatus { get; set; }
}
Have you got an idea ?
Thank's by advance
You are passing a Models.Evaluation instance to your view, which is bound to a model of another type.
Models.Evaluation data = new Models.Evaluation();
if (TryUpdateModel(data, "evaluations"))
{
// ...
}
return View(data);
If TryUpdateModel returns false (which happens when the form does not pass validation, for example), you are effectively passing data to the View, which is of type Models.Evaluation.
Try mapping it to type FOOBAR.Areas.Evaluation.ViewModels.EvaluationFormViewModel before passing it to the view.