Return a view from Post method - asp.net-mvc-3

I have this post method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Invitations(SuperInvitationsEditModel model)
{
...
var newmodel = new SuperInvitationsEditModel();
if (hasErrors)
{
SuperInvitationsErrorModel newErrorModel = new SuperInvitationsErrorModel();
newErrorModel.Errors = model.Errors;
return View(newErrorModel);
}
return View(newmodel);
}
When this code in the if(hasErrors) executes I get this error.
The model item passed into the dictionary is of type 'MyProject.Models.SuperInvitationsErrorModel', but this dictionary requires a model item of type 'MyProject.Models.SuperInvitationsEditModel'.
I thought I can do this since the return value of the method is a generic ActionResult. Can anyone tell me why is this not working?

because your current view is strongly typed. change the code as
return View("yourviewname",newErrorModel);

It has nothing to do with casting ViewResult to ActionResult. The problem is, that you have strongly typed view that expects the model of type SuperInvitationsEditModel (see #model on the top of Invitations.cshtml), but you are passing the model of type SuperInvitationsErrorModel to it.
You should merge the two view model classes (SuperInvitationsEditModel and SuperInvitationsErrorModel) into one, or create a standalone view for each of them.

Related

Get route {id} value in view?

I known if I have something like /controller/action/{id} I can access id as a function parameter. But how would I access it via the view without using the viewbag?
You can pass that function parameter to the View as part of a model. The model can be staticly or dynamically typed. The example code below demonstrates how to pass the value as a property on a dynamic model.
public ActionResult Edit(string id)
{
dynamic model = new System.Dynamic.ExpandoObject();
model.Id = id;
return View(model);
}
You would access this value in the view as follows:
#Model.Id
You can parse the URL to get the ID when in the view:
var id = Request.Url.LocalPath.SubString(LastIndexOf("/",Request.Url.LocalPath)+1);
It will be put directly into the ViewBag.id or you can access it via ViewData["id"]. hey seem like the same object

MVC3 System.Collections.Generic.List pass the wrong model item

Hello everyone I have checked my controller and view it seems there is no problem but I get System Colletion error.
Here is my controller
public ViewResult Index()
{
return View(db.banner.ToList());
}
Here is My View
{
#model IEnumerable<icerik.Models.banner>
}
And I get this error
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[icerik.Models.banner]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[icerik.Models.contents]'.
Maybe you have a partial in your main view:
#Html.Partial("SomePartial")
and this partial is strongly typed to IEnumerable<contents>:
#model IEnumerable<icerik.Models.contents>
So make sure that you are passing the correct model to this partial. If you do not specify anything to the Partial helper (as in my example) the main model will be passed to this partial.
So always specify the correct model:
#Html.Partial("SomePartial", SomeModelInstance)

Returning a list to view and manipulating it in MVC3, Database first approach

I have a function that triggers a stored procedure that runs a
select * from tbl_admin where id=".." and username=".."
The returned output of the select statement is stored in a complex return type object spa_user_Result and stored onto a list.
I want to pass this list to the view and use it to display data, How do I do that??
code is smthing like this:
public ViewResult Index()
{
<spa_users_Result> result = new <spa_users_Result>();
System.Data.Objects.ObjectResult<spa_users_Result> r;
r = db.adminUser("s","superuser");
result = (<spa_users_Result>)r.ToList();
return View();
}
You need to pass your object(s) to the View method
public ActionResult YourAction()
{
var result = db.adminUser("s","superuser").ToList();
return View(result );
}
Assuming your db.adminUser("s","superuser") method returns a Collection of spa_users_Result object.
Make your View strongly typed to List of spa_users_Result object
#model IEnumerable<spa_users_Result>
#foreach(var item in Model)
{
<p>#item.Name</p>
}
Assuming your spa_users_Result class has a Property called Name
I'm not entirely sure what level of detail you're looking for with this question, but passing the list to the view is as simple as:
return View(result);
EDIT: Also don't you want result to be a list?
List<spa_users_Result> result = new List<spa_users_Result>();

.NET MVC3/Holding temp model

I have a situation where i have to take input(form) from user. After continue button is pressed next view page is displayed. But after continue is pressed i don't want to store the model in the DB. I have to display some details(combining some tables) according to input given by the user earlier and again get some data from user. Only then i want to store the model in the respective tables.
How can i perform this? I tried getting Model from user and passing to the function that generates next page. Is this is way to do it? or there is other way around?
Store the model submitted by the first form in session.
[HttpPost]
public ActionResult ContinueForm1(Model1 model1)
{
if(ModelState.IsValid)
{
Session["Model1"] = model1;
return View("Form2");
}
return View();
}
[HttpPost]
public ActionResult ContinueForm2(Model2 model2)
{
if(ModelState.IsValid)
{
... model2 is already here, get the model1 from session
... and save to datatbase finally return a different view or redirect to some
... other action
}
return View();
}
You are heading down the right track.
You need to grab the model that is passed back from the first view - preferably you are using ViewModels here rather than binding directly to your db models. Have a look at http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ and Why should I use view models? as to why these are good things.
The easiest way to do this is to pass the model in as an argument to your method e.g.
Assuming that your views are using the same ViewModel ( which may or may not be true) then you can send the viewmodel straight to your new view - else you can copy the elements into a new viewModel and send that.
e.g.
[HttpPost]
public ViewResult Step1(MyViewModel viewModel)
{
//Do some validation here perhaps
MySecondViewModel secondViewModel = new MySecondViewModel{
Id = viewModel.Id,
// etc. etc.
};
return View("Step2", secondViewModel);
}
Then you can carry on as you need until you have to persist the entity to the database.
NB as you do not need to do anything special in the form to make it post the model as an argument as long as the view is strongly typed to that ViewModel.

dynamic model and ModelState

I have an Action like this:
Update([Bind(Prefix = "CurrentModel")] dynamic edited)
but when I use dynamic the ModelState.IsValid always returns true so it seems like there is no validation on the dynamic object? If not, how can I solve this?
There are two cases:
You are using view models as action arguments in which case the default model binder automatically assigns the properties and sets possible errors to the model state:
public ActionResult Update([Bind(Prefix = "CurrentModel")] EditViewModel edited)
{
if (ModelState.IsValid)
{
}
...
}
You are using some weak typing with either dynamic or FormCollection in which case the default model binder doesn't kick in and doesn't perform any validation at all as it is not capable of infering your real model type. In this case you need to manually call TryUpdateModel and indicate your model type:
public ActionResult Update(dynamic edited)
{
var model = new MyViewModel();
if (!TryUpdateModel(model, "CurrentModel"))
{
// The model was not valid
}
...
}
Conclusion: using dynamic as action argument in a controller action makes very little sense.

Resources