Why doesn't my partial view work? - asp.net-mvc-3

This is bugging me and I don't know what is going on. I created a partial view to format a number properly.
The file _PermitNumber.cshtml is in /Views/Shared and contains:
#model System.Int32
#Html.Raw(Model.ToString("00-0000"))
On my main page I do:
#Html.DisplayFor(model => model.BuildingPermit.PermitId, "_PermitNumber")
model.BuildingPermit.PermitId is defined as an int.
My output is 120456 instead of the expected 12-0456.
What is going on?

Why are you using a view for formatting your output? That seems like an unnecessary piece of complexity you are adding to your view. IMO a better location for this would be within a property of your view model:
public string FormattedPermitNumber
{
get
{
return PermitId.ToString("00-0000"));
}
}
But to answer your question, if you were delete your partial view, you will see that your number is still displaying as 120456. In order to render your partial view you need to render the partial as follows:
#{ Html.RenderPartial("_PermitNumber", Model.BuildingPermit.PermitId); }

Related

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

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.

Rendering a partial list view and partial form within a details view

So I am tryng to create a comment form and a comment view within a post view.
Basically i have a post view from my blog, and i want to show a comments form and a comment section on each.
I have the views all prepared, and so far i have my form displayed at the bottom of my post view.
What i am looking to do is add my comments view to the post view above the form.
Comment Controller
// GET: /Comments/_AllComments - Partial view
public ViewResult _AllComments(int postid)
{
TempData["PostId"] = postid;
return View("_AllComments");
}
Post Detail View
#model MyProject.Models.Post
//MARKUP OMITTED
//Comments Partial View
#Html.Partial("_AllComments", new Invest.Models.Comment())
//Comments Form Partial View
#Html.Partial("_Comment_Form", new Invest.Models.Comment())
Partial View - All Comments
#model IEnumerable<MyProject.Models.Comment>
//MARKUP OMITTED
The error that i get is:
The model item passed into the dictionary is of type 'MyProject.Models.Comment', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[MyProject.Models.Comment]'.
Could someone tell me how I get round this?. I have tried changing the partial to Html.RenderPartial which didnt work either.
If you look closely you will see that your partial view needs a collection and you are passing a single object.
To solve this you can change the line with partial to like below:
//Comments Partial View
#Html.Partial("_AllComments", new List<Invest.Models.Comment>(){ new Invest.Models.Comment()})
Note: Using Html.Partial won't make a call to Action _AllComments, if you want to use the result of that action (the partial view), Html.Action or Html.RenderAction are used to do that.

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)

Problems with RenderAction in MVC 3

I wanted use MVC and renderpartial to generate a menu but but could not get it to work, and from what I read it seemed maybe RenderAction would be more suitable. Still I have not gotten it to work.
What I intended to do was create a controller that selects certain articles from a database that will act as categories (this is put into HomeController):
public ActionResult MenuController()
{
var movies = from m in db.Art
where m.ArtikelNr.StartsWith("Webcat")
select m;
return View(movies);
}
And then send that information to a view:
#model IEnumerable<xxxx.Models.Art>
#{
Layout = null;
}
<ul>
#foreach (var item in Model)
{
<li>#Html.DisplayFor(modelItem => item.Benämning_10)</li>
}
This works when I just run it as a normal controller and view, it returns a list of what I want. But if I want to call it from _layout.cshtml (because this menu should appear on every page) like this:
<div id="sidebar">#Html.RenderAction(MenuController)</div>
Then it generates the following error:
CS0103: The name 'MenuController' does not exist in the current context
What is the proper way of calling an action/view/whatever from the _layout.cshtml file?
You should call
#Html.RenderAction("_MenuController")
and be sure that you have a working rule in your Global.asax
As suggested in another answer would be better to use
return PartialView();
I also suggest you to use the ChildActionOnlyAttribute to be sure that this action will never be called as a standard action.
So something like that:
[ChildActionOnly]
public PartialViewResult _MenuController()
{
var movies = from m in db.Art
where m.ArtikelNr.StartsWith("Webcat")
select m;
return PartialView(movies);
}
#{Html.RenderAction("MenuController");}
or
#Html.Action("MenuController")
Simply
#Html.RenderAction("MenuController")
You've forgotten quotes around your string parameter
<div id="sidebar">#Html.RenderAction("_MenuController")</div>
Quotes around your action name :) It might also be good practice to return a partial view:
return PartialView(movies);

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