Using Ajax gives stale results - ajax

EDIT
My Ajax form gets correct Id to update a content and a replace option.
Submitting is by clicking <input type="submit" value="submit!" />.
Problem: When I clicked on submit I didn't see any update. Second trial gave the expected result. When I refreshed the page the lost record (first hit was successful) was on spot.
Model
[Serializable]
public abstract class AbstractEntity {
public Guid Id { get; set; }
public DateTime LastModified { get; set; }
}
[Serializable]
public class Product : AbstractEntity {
public Product() {
this.Attachments = new HashSet<Attachment>();
}
public String Title { get; set; }
public String Commentary { get; set; }
public DateTime PlacedOn { get; set; }
public String User { get; set; }
public ICollection<Attachment> Attachments { get; set; }
}
[Serializable]
public class Attachment {
public String MimeType { get; set; }
public String Description { get; set; }
public String Filename { get; set; }
}
Controller
[HandleError]
public class ProductController : Controller {
private readonly IDocumentSession documentSession;
public ProductController(IDocumentSession documentSession) {
this.documentSession = documentSession;
}
public ActionResult ListRecent() {
return View(ListAll());
}
[Audit, HttpPost]
public ActionResult Delete(Guid id) {
documentSession.Delete<Product>(documentSession.Load<Product>(id));
documentSession.SaveChanges();
return PartialView("ProductsList", ListAll());
}
[Audit, HttpPost]
public ActionResult Create(Product product) {
if(ModelState.IsValid) {
documentSession.Store(product);
documentSession.SaveChanges();
}
return PartialView("ProductsList", ListAll());
}
private IEnumerable<Product> ListAll() {
return documentSession.Query<Product>().ToArray();
}
}
Views ('scriptless')
Layout
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/stylesheets/normalize.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/stylesheets/site.core.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.7.2.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
</head>
<body>
<div id="main-wrapper">
<div id="header">[#Html.ActionLink("List", "ListRecent", "Product")]</div>
<div id="content">#RenderBody()</div>
</div>
</body>
ListRecent.cshtml
#model IEnumerable<lamp.DomainLayer.Entities.Product>
#{
ViewBag.Title = "ListRecent";
var options = new AjaxOptions {
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "productsList"
};
}
<h2>List</h2>
#Html.Partial("ProductsList", Model)
#using(Ajax.BeginForm("Create", "Product", options)) {
<fieldset>
<p>
<label class="autoWidth">Title</label>
#Html.Editor("Title")
#Html.ValidationMessage("Title")
</p>
<p>
<label class="autoWidth">Commentary</label>
#Html.TextArea("Commentary")
#Html.ValidationMessage("Commentary")
</p>
#* Some fields I have omitted.. *#
<input type="submit" value="submit" />
<input type="reset" value="clear" />
</fieldset>
}
ProductsList.cshtml
#model IEnumerable<lamp.DomainLayer.Entities.Product>
#{
var options = new AjaxOptions {
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "productsList"
};
}
<div id="productsList">
#foreach(var p in Model) {
<div class="productCard">
<p class="title"><strong>Title</strong>: #p.Title</p>
<p class="author"><strong>User</strong>: #p.User</p>
<p class="date"><strong>Placed on</strong>: #idea.PlacedOn.ToShortDateString()</p>
<p class="link">#Html.ActionLink("details", "Details", "Product")</p>
<p class="link">
#using(Ajax.BeginForm("Delete", "Product", new { id = p.Id }, options)) {
<input type="submit" value="you!" />
}
</p>
</div>
}
</div>

I guess it is IE's fault (precisely the way,how IE cache AJAX requests). Look here-it could be solution:
http://viralpatel.net/blogs/ajax-cache-problem-in-ie/

Ok. Darin was right! I found out that changing my controller code to this one:
private IEnumerable<Product> ListAll() {
return documentSession
.Query<Product>()
.Customize((x => x.WaitForNonStaleResults()))
.ToArray();
}
fixes everything.
.Customize((x => x.WaitForNonStaleResults()))
is the solution!
Thanks everyone!

Related

ASP.NET MVC Ajax file upload with jquery form plugin?

I use Jquery Ajax Form Plugin to upload file. Codes:
AuthorViewModel
public class AuthorViewModel
{
public int Id { get; set; }
[Required(ErrorMessage = "{0} alanı boş bırakılmamalıdır!")]
[Display(Name = "Yazar Adı")]
public string Name { get; set; }
[Display(Name = "Kısa Özgeçmiş")]
public string Description { get; set; }
[Display(Name = "E-Posta")]
public string Email { get; set; }
public string OrginalImageUrl { get; set; }
public string SmallImageUrl { get; set; }
}
Form
#using (Html.BeginForm("_AddAuthor", "Authors", FormMethod.Post, new { id = "form_author", enctype = "multipart/form-data" }))
{
<div class="editor-label">
<input type="file" name="file" id="file" />
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
</div>
<div class="editor-field">
#Html.ValidationMessageFor(model => model.Name)
</div>
...
<div class="submit-field">
<input type="submit" value="Ekle" class="button_gray" />
</div>
}
Script
<script>
$(function () {
$('#form_author').ajaxForm({
beforeSubmit: ShowRequest,
success: SubmitSuccesful,
error: AjaxError
});
});
function ShowRequest(formData, jqForm, options) {
$(".loading_container img").show();
}
function AjaxError() {
alert("An AJAX error occured.");
}
function SubmitSuccesful(result, statusText) {
// Veritabanı işlemleri başarılı ise Index sayfasına
// geri dön, değilse partial-view sayfasını yenile
if (result.url) {
window.location.href = result.url;
} else {
$(".authors_content_container").html(result);
}
}
</script>
Controller
[HttpPost]
public ActionResult _AddAuthor(AuthorViewModel viewModel, HttpPostedFileBase file)
{
...
viewModel.OrginalImageUrl = file.FileName;
...
}
Above codes work fine
Question
As you see, I post file seperate from ViewModel. Is there a way to add HttpPostedFileBase file property to ViewModel and bind it to viewModel in view, And post it to controller in ViewModel?
I hope , I can explain.
EDIT:
This codes work fine. I dont want post , viewModel and HttpPostedFile seperately. I want something like this: (If it is possible.)
Model
public class AuthorViewModel
{
public int Id { get; set; }
[Required(ErrorMessage = "{0} alanı boş bırakılmamalıdır!")]
[Display(Name = "Yazar Adı")]
HttpPostedFileBase file{ get; set; }
...
}
Controller
[HttpPost]
public ActionResult _AddAuthor(AuthorViewModel viewModel)
{
var file = viewModel.file;
...
}
Thanks.
Yes you can add AliRıza Adıyahşi.
Here is the property to do it:
public HttpPostedFileBase File { get; set; }
Now in you form you should add enctype as Xiaochuan Ma said:
#using (Html.BeginForm("_AddAuthor", "Authors", FormMethod.Post, new { id = "form_author", enctype="multipart/form-data" }))
{
<div class="editor-label">
<input type="file" name="file" id="file" />
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
</div>
<div class="editor-field">
#Html.ValidationMessageFor(model => model.Name)
</div>
...
<div class="submit-field">
<input type="submit" value="Ekle" class="button_gray" />
</div>
}
On you Controller action:
[HttpPost]
public ActionResult _AddAuthor(AuthorViewModel viewModel, HttpPostedFileBase file)
{
if(file!=null)
{
viewModel.File=file; //Binding your file to viewModel property
}
//Now you can check for model state is valid or not.
if(ModelState.IsValid)
{
//do something
}
else
{
return View(viewModel);
}
}
Hope it helps. Is this what you need ?
EDIT
There is nothing additional to do. Its automatically binding to viewModel.
[HttpPost]
public ActionResult _AddAuthor(AuthorViewModel viewModel)
{
var uploadedfile = viewModel.File;// Here you can get the uploaded file.
//Now you can check for model state is valid or not.
if(ModelState.IsValid)
{
//do something
}
else
{
return View(viewModel);
}
}
This worked for me !
Yes, you can add HttpPostedFileBase in to your ViewModel, and add enctype = "multipart/form-data" to your From in HTML.
Check with this link:
MVC. HttpPostedFileBase is always null

MVC Dropdown list persting for each requests

I am working on a web app using MVC, where all pages have header section consiting of three dropdowns one text box and an image button. So no matter on which page user is, he/she has ability to select a combination out of three dropdowns, enter some text in text box and hit image button to search in database.
So i am using a strongly typed(BaseViewModel) master _Layoutthought, and then add two partial views on it, one to display user info and another one to display all dropdowns, text box and imaage button. Now, Models i have 3 models for each dropdown option/item and then a BaseViewModel which will have 3 properties as a list of each model and 3 int properties to hold selected item ID. And plan is to use this baseViewModel as parent class for all viewmodels so that i can fullfil my strongly tyed _Layout for each request and responce. OK i am not sure that if i have explained my requirement clearly :(.
so here is the code
all models:
namespace XYZNameSpace.Models
{
public class ManageCompany
{
public long ManageCompanyID { get; set; }
public string ManageCompanyName { get; set; }
}
}
namespace XYZNameSpace.Models
{
public class SuperCompany
{
public long SuperCompanyID { get; set; }
public string SuperCompanyName { get; set; }
}
}
public class User
{
public long UserID { get; set; }
public string UserName { get; set; }
public string UserLoginName { get; set; }
public string UserLevel { get; set; }
public int UserLevelId { get; set; }
}
namespace XYZNameSpace.Models
{
public class SearchResult
{
public string CompanyName { get; set; }
public string SubCompanyName { get; set; }
public string UserName { get; set; }
}
}
ViewModel
namespace XYZNameSpace.ViewModels
{
public class BaseViewModel : User
{
public long SelectedManageCompanyID { get; set; }
public List<SelectListItem> ManageCompanyList { get; set; }
public string SelectedManageCompanyName { get; set; }
public long SelectedSuperCompanyID { get; set; }
public List<SelectListItem> SuperCompanyList { get; set; }
public string SelectedSuperCompnayName { get; set; }
public int SelectedSearchOptionID { get; set; }
public List<SelectListItem> SearchOptionsList { get; set; }
public string SelectedSearchOptionName { get; set; }
public string SearchWord { get; set; }
}
public class SearchOption
{
public int SearchOptionID { get; set; }
public string SearchOptionName { get; set; }
}
}
namespace XYZNameSpace.ViewModels
{
public class SearchResultsViewModel : BaseViewModel
{
public List<SearchResult> ResultsList { get; set; }
}
}
Controller
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Home()
{
BaseViewModel bVM = new BaseViewModel()
{
ManageCompanyList = (new List<ManageCompany>() {
new ManageCompany()
{
ManageCompanyID = 1,
ManageCompanyName = "MC 1"
},
new ManageCompany()
{
ManageCompanyID = 2,
ManageCompanyName = "MC 2"
},
new ManageCompany()
{
ManageCompanyID = 3,
ManageCompanyName = "MC 3"
},
new ManageCompany()
{
ManageCompanyID = 4,
ManageCompanyName = "MC 4"
},
new ManageCompany()
{
ManageCompanyID = 5,
ManageCompanyName = "MC 5"
}
}).Select(x => new SelectListItem { Value = x.ManageCompanyID.ToString(), Text = x.ManageCompanyName }).ToList(),
SuperCompanyList = (new List<SuperCompany>(){
new SuperCompany(){
SuperCompanyID=6,
SuperCompanyName="SC 6"
},
new SuperCompany(){
SuperCompanyID=7,
SuperCompanyName="SC 7"
},
new SuperCompany(){
SuperCompanyID=8,
SuperCompanyName="SC 8"
},
new SuperCompany(){
SuperCompanyID=9,
SuperCompanyName="SC 9"
},
new SuperCompany(){
SuperCompanyID=10,
SuperCompanyName="SC 10"
}
}).Select(y => new SelectListItem { Value = y.SuperCompanyID.ToString(), Text = y.SuperCompanyName }).ToList(),
SearchOptionsList = (new List<SearchOption>(){
new SearchOption(){
SearchOptionID=11,
SearchOptionName="SO 11"
},
new SearchOption(){
SearchOptionID=12,
SearchOptionName="SO 12"
},
new SearchOption(){
SearchOptionID=13,
SearchOptionName="SO 13"
},
new SearchOption(){
SearchOptionID=14,
SearchOptionName="SO 14"
},
new SearchOption(){
SearchOptionID=15,
SearchOptionName="SO 15"
}
}).Select(y => new SelectListItem { Value = y.SearchOptionID.ToString(), Text = y.SearchOptionName }).ToList()
};
return View(bVM);
}
[HttpPost]
public ActionResult Search(BaseViewModel bVM)
{
SearchResultsViewModel sRVM = new SearchResultsViewModel();
sRVM.ResultsList = new List<SearchResult>(){
new SearchResult()
{
CompanyName = bVM.SelectedSuperCompanyID.ToString(),
SubCompanyName = bVM.SelectedManageCompanyID.ToString(),
UserName = "Duh"
}
};
return View("SearchResults", sRVM);
}
}
Views /Home/Home.cshtml
#{
ViewBag.Title = "Home";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div style="float: left; vertical-align: top;">
</div>
<br />
/Home/SearchResults.cshtml
#model XYZNameSpace.ViewModels.SearchResultsViewModel
<table width="100%">
<thead>
<tr>
<td>
COMPANY
</td>
<td>
SUB COMPANY
</td>
<td>
USER NAME
</td>
</tr>
</thead>
<tbody>
#foreach (XYZNameSpace.Models.SearchResult sr in Model.ResultsList)
{
<tr>
<td>
#sr.CompanyName
</td>
<td>
#sr.SubCompanyName
</td>
<td>
#sr.UserName
</td>
</tr>
}
</tbody>
</table>
/Shared/SearchDDLPartialView.cshtml
#model XYZNameSpace.ViewModels.BaseViewModel
<div>
<div style="float: left">
<span class="Label">Search: </span>
#using (Html.BeginForm("Search", "Home", FormMethod.Post))
{
#Html.DropDownListFor(x => x.SelectedSuperCompanyID, Model.SuperCompanyList)
#Html.DropDownListFor(x => x.SelectedManageCompanyID, Model.ManageCompanyList)
#Html.DropDownListFor(x => x.SelectedSearchOptionID, Model.SearchOptionsList)
<input type="image" src="../../Content/images/search.gif" />
}
</div>
</div>
/Shared/_Layout.cshtml
#model XYZNameSpace.ViewModels.BaseViewModel
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/BEClientProfile.css")" rel="Stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
<table>
<tr>
<td>
<img src="../../Content/images/logo124.gif" alt="Logo" />
</td>
<td valign="top">
<div style="float: left; vertical-align: top; text-align: left">
<img src="../../Content/images/user-info.gif" alt="User Infor" />
<span class="Label">Welcome </span><span class="HeaderLabelText">#Model.UserLevel</span>
</div>
<div>
<div style="float: left; width: 100%;">
<u><span class="Label">Currently Editing:</span> </u>
</div>
<div style="float: left; width: 100%;">
<span class="Label">Company:</span> <span class="HeaderLabelText">#Model.SelectedManageCompanyID</span>
</div>
<div style="float: left; width: 100%;">
<span class="Label">User:</span> <span class="HeaderLabelText">#Model.UserLoginName</span>
</div>
</div>
</td>
<td>
</td>
<td>
#{Html.RenderPartial("SearchDDLPartialViews", Model);}
</td>
</tr>
<tr>
<td colspan="4">
#RenderBody()
</td>
</tr>
</table>
</body>
</html>
/Shared/UserPartialView.cshtml
#model XYZNameSpace.Models.User
<div style="float: left; margin-left: .5em;">
<img src="../../Content/images/user-info.gif" alt="User Infor" />
<span style="font-weight: bold; float: left;">Welcome </span>
</div>
OK, i was able to select one item from each dropdown but when i click on image button at search Action in home control, the BaseViewModel has nothing other than selectedIDs, so when action is trying to display SearchResults view back, them _Layout.cshtml throughs error saying there nothing in lists that are used by dropdowns.
so how do we persist this information for every request...?
Quick solution is store the List < SelectListItem > or the viewmodel itself in session and reintroduce them to the view every time you return the viewmodel. However for cloud based solutions, same concept, but you'll need to use other caching storage such as appfabric, memcache or other addons allowed by your PaaS.

Date validation on search input/textbox for a razor view MVC

I would like to add a textbox (date) and button to my report, which filters the data.
The below mvc is working, but the input must still be validated (must be a DATE) on client side (and server side if possible)
My Model looks like this :
public class DailyReport
{
public int DailyReportID { get; set; }
public DateTime? ReportDate { get; set; }
}
View :
#model IEnumerable<project_name.Models.DailyReport>
#* text box and button: *#
#using (Html.BeginForm("Index", "DailyReport", FormMethod.Get))
{ <p>
Title: #Html.TextBox("SearchDateString")
<input type="submit" value="Filter" />
</p>
}
#* display dates*#
#foreach (var item in Model)
{ #Html.DisplayFor(modelItem => item.ReportDate)
}
my controller:
public ViewResult Index(String SearchDateString)
{
var dailyreport = db.DailyReport.Include(d => d.Site);
if (!String.IsNullOrEmpty(SearchDateString))
{
DateTime search_date = Convert.ToDateTime(SearchDateString);
dailyreport = dailyreport.Where(r => r.ReportDate == search_date);
}
return View(dailyreport.ToList());
}
Can someone help me please?
How do I make sure a valid date is entered in the textbox?
Should I create a another model with a date field for this input?
Utilize the DataTypeAttribute from the DataAnnotations namespace in your Model, like so:
public class DailyReport
{
public int DailyReportID { get; set; }
public DateTime? ReportDate { get; set; }
}
public class DrViewModel
{
[DataType(DataType.Date)]
public string DateTimeSearch { get; set; }
List<DailyReport> DailyReports { get; set; }
}
In your View, have something like:
#model project_name.Models.DrViewModel
#using (Html.BeginForm("Index", "DailyReport", FormMethod.Get))
{
<p>
Title: #Html.TextBoxFor(m => m.DateTimeSearch)
<input type="submit" value="Filter" />
</p>
}
#foreach (var item in Model.DailyReports)
{
#Html.DisplayFor(m => item.ReportDate)
}
#Shark Shark pointed me in the right direction to use a viewmodel, this is the end result that is now working. JS validation added as well.
(DBSet was not necessary because DrViewModel is a viewmodel.)
controllers :
public ActionResult Index(DrViewModel dvm)
{
var dailyreport = db.DailyReport.Include(d => d.Site);
if (dvm.DateTimeSearch != null)
{
dailyreport = dailyreport.Where(r => r.ReportDate == dvm.DateTimeSearch);
}
dvm.DailyReport = dailyreport.ToList();
return View(dvm);
}
models :
public class DrViewModel
{
public DateTime? DateTimeSearch { get; set; }
public List<DailyReport> DailyReport { get; set; }
}
public class DailyReport
{
public int DailyReportID { get; set; }
public DateTime? ReportDate { get; set; }
}
view :
#model myproject.Models.DrViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("Index","DailyReport", FormMethod.Get ))
{
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.DateTimeSearch)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DateTimeSearch)
#Html.ValidationMessageFor(model => model.DateTimeSearch)
<input type="submit" value="Filter" />
</div>
}
#foreach (var item in Model.DailyReport)
{
#Html.DisplayFor(modelItem => item.ReportDate)
}

MVC3 Client Side Validation not working with an Ajax.BeginForm form

I have the following form in a partial view
#model PartDetail
#using (Ajax.BeginForm("Create", "Part", null, new AjaxOptions { UpdateTargetId = "update_panel"}))
{
<h3>New #Model.PartType</h3>
<p> Serial Number:
<strong>
#Html.EditorFor(model => model.SerialNumber)
#Html.ValidationMessageFor(model => model.SerialNumber)
</strong>
</p>
<p> Name:
<strong>
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</strong>
</p>
...... more relatively boiler plate code here......
<p>
<input type="submit" class="btn primary" value="Save Part"/>
</p>
}
With a model of
public class PartDetail
{
public string DateCreated { get; set; }
[StringLength(255, MinimumLength = 3)]
public string Description { get; set; }
public Guid ID { get; set; }
public string IsActive { get; set; }
public string Manufacturer { get; set; }
public IEnumerable<SelectListItem> Manufacturers { get; set; }
[StringLength(100, MinimumLength = 3)]
public string Name { get; set; }
public string PartType { get; set; }
[Required]
[StringLength(100, MinimumLength = 3)]
public string SerialNumber { get; set; }
}
And I reference (in parent views of my partial view)
<script src="#Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"> </script>
And nothing gets validated. If I type nothing into the Serial Number text box and press submit it saves it to the database with no problems.
Try adding an OnBegin callback to the AjaxOptions and this should work.
function validateForm() {
return $('form').validate().form();
}
#using (Ajax.BeginForm("Create", "Part", null, new AjaxOptions { UpdateTargetId = "update_panel", OnBegin = "validateForm" }))
...
If this doesn't work for you, an alternative solution may be to submit the form using jQuery. This would be my preferred solution.
<div id="result"></div>
#using (Html.BeginForm())
{
<h3>New #Model.PartType</h3>
<p>Serial Number:
<strong>
#Html.EditorFor(model => model.SerialNumber)
#Html.ValidationMessageFor(model => model.SerialNumber)
</strong>
</p>
<p> Name:
<strong>
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</strong>
</p>
...... more relatively boiler plate code here......
<p>
<input type="submit" class="btn primary" value="Save Part"/>
</p>
}
jQuery/JS function to submit the form
$(function () {
$('form').submit(function () {
$.validator.unobtrusive.parse($('form')); //added
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#result').html(result);
}
});
}
return false;
});
});
In this case order of javascript file including process is important. Your order of including these file should be
jquery.js
jquery.validate.js
jquery.validate.unobtrusive.js
When I tried with re-ordering it works fine for me. Try it.
Check your root Web.config of the solution/project. Does it contain the following lines?
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
It not, add them.
you need to modified your controller action little bit to work validation in Ajax request
you catch RenderHtml of partial view and apply your validation on it for e.g
//In Controller
public string Create(PartDetail model)
{
string RenderHtml = RenderPartialViewToString("PartailViewName", model);
return RenderHtml;
}
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
you must be pass ViewName and Model to RenderPartialViewToString method. it will return you view with validation which are you applied in model.

Correct way to load a partial view into a view

I am wanting to create a view that allows me to add phone numbers for a person.
public class PersonModel
{
public string Name { get; set; }
}
public class PhoneModel
{
public string PhoneNumber { get; set; }
}
public class PersonDetailViewModel
{
public PersonModel PersonDetails { get; set; }
public IList<PhoneModel> PhoneNumbers { get; set; }
}
I am binding my main view to the viewmodel like
#model DynamicPhoneNumber.Models.PersonDetailViewModel
#{
ViewBag.Title = "Add";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Details</legend>Name #Html.TextBoxFor(a => a.PersonDetails.Name)
<input type="button" id="btnAdd" value="Press Me" />
<div id="mydiv">
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
My Partial view looks like
#model DynamicPhoneNumber.Models.PhoneModel
<p>
#Html.TextBoxFor(t => t.PhoneNumber)
</p>
Im using jquery to dynamically add the partial view.
On HttpPost I place a breakpoint and I can see the value from the PersonDetails.Name however none of the values from my loaded partialview are been bound to the PhoneModel.
What do I need to do to be able to return the data from the partial views into my viewmodel?
here is a good blog post that may help to resolve your problem
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Resources