Is it possible to send Model data from a View to a Controller that is not the Controller for that View? - model-view-controller

I could not find the similar question yet, so I decided to ask it here.
I relatively new to MVC and may have some incorrect wording in my question, and I'm just wondering if that is possible to do it at all?
Usually, we are dealing with ModelViewController coupling and we return the View from a Controller with Models/Json as parameters to the returning View, so we can bind the Model to the View
I'm just wondering if we have a ViewA, ViewB ControllerA,ControllerB and a ModelA, is that possible to have a #Url.Action/Link or Ajax method to send the ModelA from the ViewA to an Action Method of a ControllerB, so, the data stored in the ModelA can be displayed in the ViewB when it is returned from the ControllerB?
I do not have any code yet and just want to know if that is possible and if so, what would be the right approach to achieve something like that?

You could do something like this:
Controller B:
public IActionResult ControllerB(ModelA data)
{
return View(data);
}
View A:
#foreach (var data in Model)
{
<li>#Html.ActionLink(#data.ModelAProperty, "ControllerB", "ControllerBFileName", new { id = data.Sys.Id })</li>
}
View B:
#model YourModel.Models.ModelA
<div>
<h3>#Model.ModelAProperty</h3>
<p>#Model.ModelAOtherProperty</p>
</div>
This should work I believe. I did this with a previous project but it was a slightly different set up, but I believe I have modified it correctly to fit your needs. Basically you are passing the data to the controller with the first view, and then using that controller to pass the data to the next view.

Related

EditorFor parameters in Action MVC3

Having a bit of trouble figuring something out.
I've got an Action:
public ActionResult FareTypeSelector(SearchTypes searchType, SearchSource searchSource)
{
IFareTypeOptionsRepository fareTypeOptionRespoitory = new FareTypeOptionsRepository();
FareTypeOptions fareTypeOptions = fareTypeOptionRespoitory.GetFareTypeOptions(searchSource, searchType, _authentication.UserLoggedIn.CallCentreUser, _authentication.UserLoggedIn.AgencyProfile.BranchCode);
return View();
}
I've created an 'Editor', i.e. a file in EditorTemplates called FareTypeSelector.cshtml.
I want to bind my editor to a property of the model of the page that contains the editor. But I also want to pass some parameters into my action, i.e. (SearchTypes searchType, SearchSource searchSource). The idea being that the data displayed in the editor is based on this information passed in. Now I can't quite figure out if:
Is this possible?
whats the markup needed in the main view to render
this, pass the parameters and bind the resulting selected value into the main model?
Ta in advance
EditorTemplates are used for Data items from your model, not Action methods. They're using only in your view to render a specific model (or member of a model)

How can we include a form in _layout?

I currently have a _layout.cshtml used by every page of my website.
I need to put a form on each page displayed as a popin.
So, i created a new PartialView (the content of my form) with its corresponding ViewModel and called it in _layout.cshtml.
However, i have a model conflict between ViewModels of pages using the layout and the ViewModel used by the new form (since we can't have directly two models for the same view).
The model item passed into the dictionary is of type 'XXX', but this
dictionary requires a model item of type 'YYY'.
How can we include a form in _layout without this conflict ?
The following has worked for me with a sidebar on every page.
Create a controller for your partial view
In that controller, create a method for the view you want to return, and be sure to use the [ChildActionOnly] filter
public class PartialController : Controller
{
[ChildActionOnly]
public PartialViewResult Alerts()
{
return PartialView("Alerts", messages);
}
}
In your _layout view, you'll have the following:
#Html.Action("Alerts", "Partial")
(instead of #Html.RenderPartial or #Html.Partial)
It sounds like you already have what you need for the view.
I have not used this with a form, but it should work similarly. Hope this helps.

MVC 3 Partial View and what I need to send to it?

I am wondering about a couple variations of forms and partial forms. The submit is on the parent page and I have varied what I pass to the partial view. I have a parent view with a related HomeViewModel (which has public properties Name and public Person Employee {get;set;}
1.) Scenario 1: The main view has something like the following
#model MasterDetailSample.Models.HomeViewModel
#using (Html.BeginForm()) {
<div>
#{Html.RenderPartial("_PersonView", #Model);}
</div>
<input type="submit" value="Save" />
}
In this scenario I am passing to the partial view _PersonView the entire HomeViewModel. Within _PersonView partial view I have to reference a property of the HomeViewModel i.e. Person object via #model.Employee.Name (in this scenario the submit is on the parent form (not within the partial view))
When I hit submit on the form (POST) in the controller i have to access the property of Employee "Name" via the following model.Employee.Name
This seems to work however notice the following variation scenario 2 (where I only pass to the partial the Employee object)
2.) Scenario 2
In this scenario I only want to send the Employee object to the partial view. Again the begin form and submit is on the parent form.
So from the parent form i have
#{Html.RenderPartial("_MasterView", #Model.Employee);}
and so within the partial view i reference the Name property of the Person object via #Employee.Name Now when I submit the form within the controller the Employee object is not available from the auto model binder. I can access the properties via formcollection but not from the model parameter
i.e.
[HttpPost]
public ActionResult Index(ModelViewModel model) {
**//model.Employee is null!**
return View();
}
Why? (is model.Employee null) I would like my partial view to only accept an object of type Person however after submitting from the parent page, the Employee property is null. On the partial view I am using the following on the #model line
#model MasterDetailSample.Models.Person
I would like the partial to only need a Person object to be sent to it, but I would like the submit on the main form. If i do it this way I can re-use the partial view in a few situations however IF i must send HomeViewModel i have significantly limited how I can use this partial view. So, again, I only want to use Person as the model with the partial view but I need to be able to access the properties when submitted from the parent view.
Can this be done? If yes how?
thx
You have a couple of options:
1) One I recommend -> Dont use partial views, instead use EditorFor and create an editor template for Person. With partial views the context is whatever model you pass into the view, this is why your example (1) works and (2) not. However with editor templates the parent context is taken into consideration with the html helpers and will generate the correct input names. Have a look at Darin Dimitrov's answer to a similar question.
2) Use your second example as is, but change the post action to look something like this:
[HttpPost]
public ActionResult Index(ModelViewModel model) {
TryUpdateModel(model.Employee);
**//model.Employee should now be filled!**
return View();
}
3) Use custom html helpers that accepts prefix for input, see this answer I posted a while back for example code. You could then use this inside your partial view.

Using two partial view in MVC3

In my asp.net mvc3 application i have created two partial views for two different action that is,
partialviewresult setcomment and
partialviewresult getcomment
i have created partial view using create a strongly type view and different scaffold template
for _setcomment i am using create template and for _getcomment i am using List template.
Now i want to call both _setcomment and _getcomment partial view in one view.
in my view file .cshtml
_setcomment -
#model <NAMESPACE>.<MODELNAME>
<some code>
_getcomment -
#model IEnumerable<<NAMESPACE>.<MODELNAME>>
<some code>
how can i call diiferent partial view in one view?
any suggestions?
There are different ways to do it.
If you already have the model class data in the Main view you can use like
In the main view call
#Html.Partial("PartialViewName1",model1)
#Html.Partial("PartialViewName1",model2)
If you do not have the model class data in the mail view then you can call the action on the controller and from there return the partial view.
#Html.Action("Controller","Action1")
#Html.Action("Controller","Action2")
In the Controller class
PartialResult Action1()
{
model = new ModelClass();
return PartialView(model);
}
Hope this helps.
The answer to your question is to use the following within a single view:
#{ Html.RenderAction("ActionName", "ControlerName"); }
#{ Html.RenderAction("ActionName2", "ControlerName2"); }
This would do what you are trying to achieve, however, I think there is a problem with design. What are you trying to achieve?

My controller viewmodel isn't been populated with my dynamic views model

Im creating an application that allows me to record recipes. Im trying to create a view that allows me to add the basics of a recipe e.g. recipe name,date of recipe, temp cooked at & ingredients used.
I am creating a view that contains some jquery to load a partial view clientside.
On post im having a few troubles trying to get the values from the partial view that has been loaded using jquery.
A cut down version of my main view looks like (I initially want 1 partial view loaded)
<div id="ingredients">
#{ Html.RenderPartial("_AddIngredient", new IngredientViewModel()); }
</div>
<script type="text/javascript">
$(document).ready(function () {
var dest = $("#ingredients");
$("#add-ingredient").click(function () {
loadPartial();
});
function loadPartial() {
$.get("/Recipe/AddIngredient", {}, function (data) { $('#ingredients').append(data); }, "html");
};
});
</script>
My partial view looks like
<div class="ingredient-name">
#Html.LabelFor(x => Model.IngredientModel.IngredientName)
#Html.TextBoxFor(x => Model.IngredientModel.IngredientName)
</div>
<div class="ingredient-measurementamount">
#Html.LabelFor(x => Model.MeasurementAmount)
#Html.TextBoxFor(x => Model.MeasurementAmount)
</div>
<div class="ingredient-measurementtype">
#Html.LabelFor(x => Model.MeasurementType)
#Html.TextBoxFor(x => Model.MeasurementType)
</div>
Controller Post
[HttpPost]
public ActionResult Create(RecipeViewModel vm,IEnumerable<string>IngredientName, IEnumerable<string> MeasurementAmount, IEnumerable<string> MeasurementType)
{
Finally my viewmodel looks like
public class IngredientViewModel
{
public RecipeModel RecipeModel { get; set; }
public IEnumerable<IngredientModel> Ingredients { get; set; }
}
My controller is pretty ugly......im using Inumerble to get the values for MeasurementAmount & MeasurementType (IngredientName always returns null), Ideally I thought on the httppost Ingredients would be populated with all of the on I would be able Ingredients populated
What do I need to do to get the values from my partial view into my controller?
Why don't you take a look at the MVC Controlstoolkit
I think they would do what you want.
Without getting in too much detail. Can you change the public ActionResult Create to use FormCollection instead of a view model? This will allow you to see what data is coming through if any. It would help if you could post it then.
Your view model gets populated by using Binding - if you haven't read about it, it might be a good idea to do that. Finally I would consider wrapping your lists or enums into a single view model.
Possible Problem
The problem could lay with the fact that the new Partial you just rendered isn't correctly binded with your ViewModel that you post later on.
If you inspect the elements with firebug then the elements in the Partial should be named/Id'ed something like this: Ingredients[x].Property1,Ingredients[x].Property2 etc.
In your situation when you add a partial they are probably just called Property1,Property2.
Possible Solution
Give your properties in your partial the correct name that corresponds with your List of Ingredients. Something like this:
#Html.TextBox("Ingredients[x].Property1","")
Of, after rendering your partial just change all the names en ID's with jquery to the correct value.
It happens because fields' names from partial view do not fit in default ModelBinder convention. You should analyze what names fields have in your partial view.
Also you should implement correct way of binding collections to MVC controller. You could find example in Phil's Haack post
Assuming RecipeViewModel is the model being supplied to the partial view, try just accepting that back in your POST controller like this:
[HttpPost]
public ActionResult Create(RecipeViewModel vm)
{
//
}
You should get the model populated with all the values supplied in the form.

Resources