MVC2 Partial View, Search Control - Design / Implementation - c#

I have a partial view that is a search textbox and button.
I am trying to make it a partial view so that I can render it in several places. When the user clicks search I want it to redirect to /Home/Search which will show a list of items based on what was put into the search box.
Is this the right approach or should I make the form just run the /Home/Search Index() action and not have a partial view controller at all?
Partial View
<% using (Html.BeginForm("Search", "SearchBox")) {%>
<%: Html.TextBoxFor(model => model.searchTerm) %>
<input type="submit" value="Search" />
<% } %>
Partial View Controller
public class SearchBoxController : Controller
{
public ActionResult Search(ViewModels.SearchViewModel item)
{
Models.DataClasses1DataContext db = new Models.DataClasses1DataContext();
List<Models.Item> retVal = (from p in db.Items
where p.Name.Contains(item.searchTerm)
select p).ToList();
return RedirectToAction("Search", "Home"); //No data... What to do????
}
}

or should I make the form just run the /Home/Search Index() action and not have a partial view controller at all?
Definitely yes. That's all, there is no real need for the partial controller, specially if it involves an extra redirect.

Related

Using partial view inside a Html.BeginForm sends null model to controller action method

My Get ActionMethod :
public ActionResult GetData(int id)
{
TestModel testModel = new DataAccess().GetData(id);
return View(testModel);
}
View
#model TestModel
#using (Html.BeginForm("UpdateRequest", "Home", FormMethod.Post))
{
<div>
#Html.Partial("_Information", Model.Information)
</div>
<input type="submit" id="btnSubmit" value="Save" />
}
The data is displayed correctly in the _Information partial view. But when I click on Save button the model passed to Controller is null.
Home Controller method is as follows :
[HttpPost]
public ActionResult UpdateRequest(TestModel testModel)
{
new DataAccess().UpdateData(testModel);
.....
}
But the model received for UpdateRequest is null
Please help to resolve this issue.
Note: The partial view does not contain any additional BeginForm Tags.
If the individual controls of the Partial view are added in the main View the model object is populated.
Have you checked what the form collection has in it when the controller posts back?
I would hazard a guess that the HtmlFieldPrefix is being set which is causing your form controls to have a strange name that doesn't match your POCO.
You can chance the HtmlFieldPrefix in your partial view to match the sub object that you want to set by using:
#ViewData.TemplateInfo.HtmlFieldPrefix = "Your sub object property name here"
HTH

c# - Returning multiple views in one

I am currently trying to display one of my views (partial view) inside of another one. Inside of my view, I have been using the following code: #{ Html.RenderPartial("_Pending"); }.
My partial view is inside of my Shared folder. My goal is to pull in two different views using logic from two different controllers. Given my two views (Transaction Index and Pending Transactions (partial)), I essentially want both of these to appear on the same page. The issue is that currently, I am essentially getting the same view twice.
In short, how do I display a partial view inside of another view, with the partial view returning results from a different controller?
If I understand correctly, what you want is getting result of same partial view but executed by two different controller.
Have you tried #Html.Action?
essentialy it is the same concept as calling Partial but with controller action involved.
to use it, just create two Action then call #Html.Action in your view, such as:
in your controller:
public ActionResult Action1() {
return PartialView("__Pending");
}
public ActionResult Action2() {
return PartialView("__Pending");
}
in your view - you can also call it within your partial view
#Html.Action("Action1")
#Html.Action("Action2")
More info abount Partial and Action difference check out
MVC Html.Partial or Html.Action
more info about hwo to use Html.Action
How can I use Html.Action?
The partial is always included in the main view. The only time you would return the partial on its own would be if you were updating via AJAX. Presumably you would use a partial to display a list of clients. You would, perhaps, use a foreach loop in your view to iterate over the lists (contained in the view model), passing each one to the partial as its model.
Find an example to use many partial views inside one view.
In aspx page:-
<asp:content id="content" contentplaceholderid="CenterContentPlaceHolder" runat="server">
<form id="frmCheckout" name="frmCheckout" method="post">
<div class="rzccartcont">
<%this.Html.RenderPartial("CheckoutProduct", Model);%>
<div class="rzcchkpmnt rzcchkpmnt-bg" id="divChkbottomArea">
<% this.Html.RenderPartial("CheckoutCartProfileInformation", Model); %>
<%this.Html.RenderPartial("CheckoutCartPaymentDetails", Model); %>
</div>
</div>
</form>
</asp:content>
Reloading part of a page via AJAX (note partial is rendered inline in initial page load)
<script type="text/javascript">
$(function() {
$('#someButton').click( function() {
$.ajax({
url: '/controller/action',
data: ...some data for action...,
dataType: 'html',
success: function(data) {
$('#partial').html(data);
},
...
});
});
});
</script>
Controller for AJAX:-
public ActionResult Action(...)
{
var model = ...
...
if (Request.IsAjaxRequest())
{
return PartialView( "Partial", model.PartialModel );
}
else
{
return View( model );
}
}
Hope it helps you.

ASPNET MVC 5 Html helper Action method view results input id missing (sometimes..) Possible Bug?

To recreate the issue I'm having I've set up two simple controller actions, two views and a view model:
MultiForms Action (in the form controller class)
public class FormController : Controller
{
[HttpGet]
public ActionResult MultiForms()
{
return View("MultiForms");
}
// ...
MultiForms.cshtml - Razor View
#Html.Action("MyFormGet", "Form")
Notice in the action method I call the controller method that returns the form partial view.
MyFormGet Action
[HttpGet]
public PartialViewResult MyFormGet()
{
var viewModel = new MyFormViewModel();
ViewData.TemplateInfo.HtmlFieldPrefix = Guid.NewGuid().ToString().Replace("-", "_");
return PartialView("MyForm", viewModel);
}
View Model
public class MyFormViewModel
{
public string TextInput1 { get; set; }
}
MyForm.cshtml - Razor View
#model Mvc5App.Controllers.MyFormViewModel
#using (Html.BeginForm("MyFormPost", "Form", FormMethod.Post))
{
<br />
#Html.TextBoxFor(m => m.TextInput1)
}
When I point my browser at /Form/MultiForms I get the output I expect:
<input type="text" value="" name="e166fa0d_46fe_40d4_a970_73c52a35f224.TextInput1" id="e166fa0d_46fe_40d4_a970_73c52a35f224_TextInput1">
Then I refresh the page and the output becomes this:
<input type="text" value="" name="48edc339_69ad_4b9b_9583_198038beab45.TextInput1">
Where did the id attribute go? Is this a bug in ASPNET MVC5 or have I done something wrong with this setup?
Thanks to #demo I think I figured out when the id doesn't show up...
If the id starts with a digit(or underscore) it will not render. So this GUID will render:
f3b1a447_3786_4472_9dfe_14c3ae8aae24
But this one will not:
1c26ce3d_5c71_408a_aae2_7be414f1d383
The solution for the above seems to be prefixing with something like this:
FOO_1c26ce3d_5c71_408a_aae2_7be414f1d383
And the problems go away.

How to handle PartialView with different model than parent View

I'm using VS2012 RC with MVC4, bot for all intents and purposes let's pretend it's MVC3. I would like to know what the standard best practice(s) is on how to handle PartialViews with a form that uses a different model than the parent View.
For example, here is a view that displays a table of all the available Roles and also has a form that allows the user to add more roles.
Main View - Roles.cshtml:
#model IEnumerable<RobotDog.Models.RoleModel>
<table>
#foreach(var role in Model) {
<tr>
<td class="roleRow">#role.Role</td>
</tr>
}
</table>
<div class="modal hide">
#Html.Partial("_AddRolePartial")
</div>
_AddRolePartial.cshtml
#model RobotDog.Models.RoleModel
#using(Html.BeginForm("AddRole","Admin", FormMethod.Post)) {
#Html.TextBoxFor(x => x.Role, new { #class = "input-xlarge", #placeholder = "Role"})
<input type="submit" value="Submit" class="btn btn-primary btn-large"/>
}
Model:
public class RoleModel {
[Required]
[DataType(DataType.Text)]
[Display(Name = "Role")]
public string Role { get; set; }
}
Controller for View:
public ActionResult Roles() {
var model = from r in System.Web.Security.Roles.GetAllRoles()
select new RoleModel {Role = r};
return View(model);
}
Controller for PartialView:
[HttpPost]
public ActionResult AddRole(RoleModel model) {
try {
System.Web.Security.Roles.CreateRole(model.Role);
RedirectToAction("Roles");
} catch(Exception) {
ModelState.AddModelError("", "Role creation unsuccessful.");
}
return ????; // not sure how to pass ModelState back to partialView
}
I thought about creating a ViewModel that held RoleModel and IEnumerable<RoleModel> but it seems like there would be a more stream lined way to accomplish what I wanted without having to create a ViewModel everytime I wanted to use this PartialView.
I think you are asking how to pass a RoleModel to the add RoleModel modal popup. Since you are creating a new Role, I am assuming you are needing an empty model. You can either pass it in like below:
<div class="modal hide">
#Html.Partial("_AddRolePartial", new RoleModel())
</div>
Or just do a #Html.RenderAction("AddRole") with the supporing GET method of the controller to support populating the item.
public ActionResult AddRole() {
var model = new RoleModel();
//populate with any items needed for the Add Role Model View
return View(model);
}
I personally don't like using Partial views with forms, because Partial Views do not render submodels correctly (ie, they don't take into account the hierarchy of the model).
This is why Display and EditorTemplates exist. They work well for rendering specific data types.
However, in your case, since your view doesn't have any forms of its own, and the end result is just a single item of the collection of your parent model, then a Partial View is actually a better approach simply because you CAN pass a different model to it than the views uses.
As others have pointed out, you can easily pass an empty model to the partial as the second parameter. I don't like newing up new objects in the view, but it doesn't look like there's a lot of choice there, as the alternatives would be pretty messy.
How about the form post is changed to an ajax form post with a target update partial id being the div which you will add to the parent view (effectively surrounding Roles.cshtml).
Add a new action public ActionResult _Roles() which will return PartialView("Roles", model)
Next, in the Post Action, Return RedirectToAction(...Roles Partial Action ...) at the end and remove RedirectToAction("Roles") in the try.

Using the same code in different (partial) views

Maybe this question is quite simple because I'm new to MVC2. I have a simple demo MVC project.
(1) A weak-typed view: Index.aspx
<% Html.RenderPartial("ArticalList", ViewData["AllArticals"] as List<Artical>); %>
(2) A strong-typed partial view: ArticalList.ascx
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<Artical>>" %>
<% foreach (Artical a in Model) { %>
<%= Html.ActionLink(a.Title, "About", new { id = a.ID })%><br />
<%} %>
(3) Here is the HomeController.cs
public ActionResult Index()
{
ViewData["AllArticals"] = Artical.GetArticals();
return View();
}
public ActionResult ArticalList()
{
return PartialView(Artical.GetArticals());
}
Sorry I'm using a Web-Form "angle", because if I'm using a Web-Form, when I visit Index.aspx, rendering ArticalList.ascx will call public ActionResult ArticalList(). But here I need to write Artical.GetArticals() twice in two actions. How can I put them in one?
From what I understand, as a recent newbie in MVC too, is that the partial view does not use a action method in a controller. The "ArticalList" is a reference to the partial view file only and does not make another request for an action method. The partial view gets all of it's data from the view it is called from.
Html.RenderAction might be the behavior you're getting confused with.

Categories