Insertion on Asp.Net Mvc Failed - asp.net-mvc

On my asp.net mvc project, the table data will be displayed on a grid view using Index Method.
After doing Insertion, it would redirect to Index using RedirectToAction. But for the First time, the new row is getting added to the grid. When tried second time, the insertion is not possible.
But if i reload the page using browser reload again, for the first time only insertion takes place. Please help me to resolve this issue.
When I tried to debug, "the process has been changed since the last step" takes place. So, the values during the first debug also coming for insertion on second time which break the operation. Give Solution pls..
public ActionResult Index()
{
X_DEVEntities Entity = new X_DEVEntities();
var outPut=Entity.Model.ToList();
return View(outPut);
}
public ActionResult Insert(Model modelData)
{
X_DEVEntities Entity = new X_DEVEntities();
modelData.create_user_id = "ty";
modelData.last_mod_dtm = DateTime.Now;
modelData.last_mod_user_id = "gdf";
Entity.Model.Add(modelData);
Entity.SaveChanges();
return RedirectToAction("Index");
}

On second insertion you are getting error because on each insertion you'll have same create_user_id and last_mod_user_id based upon the your Insert method you posted.
I'm guessing it should be something like this
public ActionResult Insert(Model modelData)
{
X_DEVEntities Entity = new X_DEVEntities();//try not to do this in your Insert method, rather have a constructer where you place this instantiation.
Entity.yourTableName.UserId=modelData.create_user_id;//(UserId should be the field where you want to place the username you get from the view)
modelData.last_mod_dtm = DateTime.Now;
Entity.yourTableName.LastModUserId=modelData.last_mod_user_id;//again LastModUserId is the field where you want to save your modelData.last_mod_user_id in table.
Entity.Model.Add(modelData);
Entity.SaveChanges();
return RedirectToAction("Index");
}

Related

Data source not bound error in MVC 4 WebGrid upon refresh. TempData reseting

I have an MVC 4 application that displays a list of results from a search in a WebGrid. The results page loads correctly displaying all of the data matching the search. If I reload the page I get...
"A data source must be bound before this operation can be performed."
I am not display the WebGrid is a partialView, as I have seen questions similar to this with relation to a partial view. Anyone have an idea as to why a refresh would cause a loss of data?
EDIT:
Here is my controller method for the Results page.
public ActionResult Results()
{
var model = TempData["Results"] as List<iCap.Business.Complaint>;
return View(model);
}
I noticed TempData["Results"] resets upon refresh. Is there anyway to prevent that?
Thanks always,
Rock
Found the answer to my problem here: https://stackoverflow.com/a/11194300/2682614. TempData does reset upon refresh so I am now using seesion instead.
[HttpPost]
public ActionResult Index(SearchView search)
{
Session["Results"] = null;
var results = RCCADao.RCCASearch(search);
Session["results"] = results;
return RedirectToAction("Results");
}
public ActionResult Results()
{
var model = Session["Results"] as List<iCap.Business.Complaint>;
return View(model);
}
Hope this helps anybody else with a similar problem!
Rock

Why does creating a new ViewModel return the same data as the old ViewModel?

I'm just learning MVC3 now and this is really confusing me.
I have a ViewModel that contains some child ViewModels. Each of the ChildViewModels get rendered with a different Partial View, and when submitting execute a different action on the Controller. All the ChildViewModels should perform some custom validation on their data, and if successful it should move on to the next page. If the validation fails, it should simply return to the ParentView and display the errors.
[HandleError]
public class MyController: Controller
{
public ActionResult Index()
{
var viewModel = new ParentViewModel();
return View("ParentView", viewModel);
}
[HttpPost]
public ActionResult ChildViewModelB_Action(ChildViewModelB viewModel)
{
if (ModelState.IsValid)
{
return View("ChildViewModelB_Page2", viewModel);
}
else
{
// I'm having trouble returning to the ParentView and
// simply displaying the ChildViewModel's errors, however
// discovered that creating a new copy of the VM and displaying
// the ParentView again shows the existing data and any errors
// But why??
var vm = new ParentViewModel();
return View("ParentView", vm);
}
}
}
For example,
The page loads with 3 options.
User selects option B and fills out a form.
Upon submit, the child ViewModel B gets validated and fails.
Page returns to ParentView, with ChildB all filled out, however ChildB errors are now also showing.
Why does creating a new copy of the ParentViewModel display the ParentView with the same data as the original ParentViewModel?
And is there a different way I should be returning to the ParentView after doing server-side validation?
You need to clear the modelstate if you intend to modify values in your POST action
else
{
ModelState.Clear();
var vm = new ParentViewModel();
return View("ParentView", vm);
}
The reason for that is because Html helper such as TextBoxFor will first look in the modelstate when binding their values and after that in the model. And since the modelstate already contains the POSTed values, that's what's used => the model is ignored. This is by design.
This being said the correct thing to do in your case is to simply redirect to the GET action which already blanks the model and respect the Redirect-After-Post pattern:
else
{
return RedirectToAction("Index");
}
Why does creating a new copy of the ParentViewModel display the
ParentView with the same data as the original ParentViewModel?
Because the values of the fields are retrieved from the POSTed form and not from the model. That makes sense right? We don't want the user to show a form filled with different values from what they submitted.

Add Value to RoutValues and keep Current Values in ASP.NET MVC 3

I have a view with two form one of them for declare rows per page. In post action I need my Url be the same and just add new parameter. at now I use like this:
[HttpPost]
public ActionResult Index(FormCollection collection) {
//Calculate Row Count
return RedirectToAction("Index", new { RC = RowCount });
}
with this implementation my all parameters lost and just RC = rowcountnumber replaced.
How can I keep parameters and just add new RC to it? what is fastest way to do it? is any performance issue here?
check this, I am not sure is fastest or about performance issue, but worked:
RouteValueDictionary rt = new RouteValueDictionary();
foreach(string item in Request.QueryString.AllKeys)
rt.Add(item, Request.QueryString.GetValues(item).FirstOrDefault());
rt.Add("RC", RowCount);
return RedirectToAction("Index", rt);
Unfortunately I can't test it right now, but I suspect this would work (though it does mutate the collection parameter). And it would perform well, as it's not copying over any items from the old collection; just adding one item to it.
[HttpPost]
public ActionResult Index(FormCollection collection)
{
//Calculate Row Count
collection.Add("RC", RowCount);
return RedirectToAction("Index", collection);
}
Make the form GET not POST because the request is not changing anything on the server , so GET verb is more appropriate , and also the GET verb will pass all the form values as a query string parameters so you'll get the desired effect
to do that in the Html.BeginForm the third parameter should be FormMethod.Get

ASP.NET MVC: Keeping last page state

Here's the situation: i have a SearchPage where an user can make a complex search. Nothing really unusual. After the results are displayed, the user can select one of them and move to another Page (Like a Master/Detail).
I have a breacrumb which holds the places where the user has been and it can have more than 4 levels (Like Main -> 2Page -> 3Page -> 4Page -> NPage). What i want is to maintain the state of each control on my complex search page, if the user uses the breacrumb to navigate backwards, since i don't want them to manually set all those search filters again.
So far, i've been using javascript:history.back(), but since i can have multiple levels on my breadcrumb, this hasn't been very useful. I was thinking about using OutputCache to do it, but i don't know how i would proceed.
UPDATE
I've just talked to a co-worker and he told me that some of our combobox (dropdownlist) are dynamically generated. So if the user select one item on the first combobox, the second will be filled with data related to the first selection.
OutputCache would cache the results for every user. Why don't you try to store the information in a cookie with page url and filter information. Each time an action is executed, read the cookie and populate the model (custom model for search) with those values found (if they match the page url, action in this situation). Pass the model to the view and let it repopulate the search criteria text boxes and check boxes.
UPDATE:
When a user fills in the search filter text boxes, you are passing that information back to a controller somehow. Probably as some kind of a strongly typed object.
Let's say your users get to enter the following information:
- Criteria
- StartDate
- EndDate
There is a model called SearchCriteria defined as:
public class SearchCriteria
{
public string Criteria { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
}
Your action could look something like this:
[HttpGet]
public ViewResult Search()
{
SearchCriteria criteria = new SearchCriteria();
if (Request.Cookies["SearchCriteria"] != null)
{
HttpCookie cookie = Request.Cookies["SearchCriteria"];
criteria.Criteria = cookie.Values["Criteria"];
criteria.StartDate = cookie.Values["StartDate"] ?? null;
criteria.EndDate = cookie.Values["EndDate"] ?? null;
}
return View(criteria);
}
[HttpPost]
public ActionResult Search(SearchCriteria criteria)
{
// At this point save the data into cookie
HttpCookie cookie;
if (Request.Cookies["SearchCriteria"] != null)
{
cookie = Request.Cookies["SearchCriteria"];
cookie.Values.Clear();
}
else
{
cookie = new HttpCookie("SearchCriteria");
}
cookie.Values.Add("Criteria", criteria.Criteria);
if (criteria.StartDate.HasValue)
{
cookie.Values.Add("StartDate", criteria.StartDate.Value.ToString("yyyy-mm-dd"));
}
if (criteria.EndDate.HasValue)
{
cookie.Values.Add("EndDate", criteria.EndDate.Value.ToString("yyyy-mm-dd"));
}
// Do something with the criteria that user posted
return View();
}
This is some kind of a solution. Please understand that I did not test this and I wrote it from top of my head. It is meant to give you an idea just how you might solve this problem. You should probably also add Action to SearchCriteria so that you can check whether this is an appropriate action where you would read the cookie. Also, reading and writing a cookie should be moved into a separate method so that you can read it from other actions.
Hope this helps,
Huske

ASP.NET MVC session lost between page loads

I am trying to use session state in MVC and I have been stuck for the entire evening!
I realise session state should be used sparingly in MVC - but I am sure I want to use it for this one page - so would appreciate solutions rather than opinions.
Basically, I have a contact form with a CAPTCHA image. When the page loads I want to set the session to the characters used in the CAPTCH image (dynamically generated image).
I have an 'new image' link which async creates a new code, sets the session and dynamically loads a new image to screen.
The session stays sets as long as the page doesn't load or reload. I need to be able to validate the user input against the code in session (which should reflect what is displayed to the user) but the session is empty.
If I perform an AJAX reload on the image i.e. set the session asynchronously - the session is set when I perform a post!!
What's going on?
I need to be able to persist the session value - arrrhhhh!
I have this is a base controller:
public new HttpContextBase HttpContext
{
get
{
HttpContextWrapper context = new HttpContextWrapper(System.Web.HttpContext.Current);
return (HttpContextBase)context;
}
}
and in the controller I have:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Contact(ContactForm c, string button)
{
string sessCaptcha = HttpContext.Session["CAPTCHA_Contact"] == null ? "" : HttpContext.Session["CAPTCHA_Contact"].ToString();
}
Any ideas????? pretty pls with a cherry on top :)
Thanks!
I am so embarrased right now...
Never ever set a session value before a Response.End() (and i believe also the same applies to response.redirect).
OMG - that's 4 hours I will never ever get back again!
Here is the demo code to illustrate my ineptitude...
public ActionResult Page1()
{
Session["test1"] = "hello world";
// This means the session won't be set
// It's is used in valid circumstances..e.g. setting session, then dynamically generating an image based on that value.
Response.End();
return View();
}
public ActionResult Page2()
{
ViewBag.Test = Session["test1"].ToString();
return View();
}
[HttpPost]
public ActionResult Page2(FormCollection fc)
{
ViewBag.Test = "...is still..." + Session["test1"].ToString();
return View();
}
You may want to look into using the TempData object
http://blog.donnfelker.com/2010/02/26/aspnet-mvc2-tempdata-now-persists/

Resources