Calling the Model method will work (with or without) using the .Tolist() - asp.net-mvc-3

i have the following model method inside my asp.net MVc web application:-
public IQueryable<User> searchusers(string q, int id)
{
return from u in entities1.Users
where (!u.Users_Classes.Any(c => c.ClassID == id) && (u.UserID.Contains(q))
select u;
}
which will be called using the following action method:-
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult Search(string q, int classid)
{
var users = r.searchusers(q, classid).ToList();
ViewBag.id = classid;
// code does here
}
now if i remove the .ToList() from my action method the code will still work fine,, so will using the .ToList() method bring any advantages or features ?
BR
Edit:-
here is the full code for my action method:-
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult Search(string q, int classid)
{
var users = r.searchusers(q, classid).ToList();
ViewBag.id = classid;
return PartialView("_usersearch", users);
}

When you call ToList, you ask the Entity Framework to execute the query immediately, and then you will work with in memory collection. Otherwise, the query will be executed when you loop through the result.

Related

ToPagedListAsync() - The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider

I have been trying to sort out this for hours and could not find a solution.
I am using a Web Api MVC project and trying to convert an IEnumerable list to a paged list async. I'm able to compile but I'm still getting a runtime error on the ToPagedListAsync() line.
The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider. Only providers that implement IDbAsyncQueryProvider can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068."
1st Layer:
public async Task<IEnumerable<MatchingCriteria>> GetMatchingCriterias(int id)
{
return await _ctx.MatchingCriterias.Include(mc => mc.RuleDefinition).Where(mc => mc.RuleDefinitionId == id).ToListAsync();
}
2nd Layer:
internal async Task<IEnumerable<MatchingCriteria>> GetMatchingCriterias(int id)
{
using (CrawlerDbContext db = new CrawlerDbContext())
{
var matchCriteriaMgr = new MatchingCriteriaManager(db);
return await matchCriteriaMgr.GetMatchingCriterias(id);
}
}
Controller:
public async Task<ActionResult> Index(int? id, string sortOrder, string currentFilter, string searchString, int? page){
var matchingCriterias = await _crawlerProvider.GetMatchingCriterias(id.Value);
//...
IQueryable<MatchingCriteria> matchCrit = matchingCriterias.AsQueryable();
//Error here -> return View(await matchCrit.ToPagedListAsync(pageNumber, pageSize));
}
if I do instead in the controller:
var matchingCriterias = _db.MatchingCriterias.Include(mc => mc.RuleDefinition);
then:
return View(await matchingCriterias.ToPagedListAsync(pageNumber, pageSize)
That works well!
I could return a DbSet on the nested methods but I could not use the ToListAsync() in the 1st layer;
Is there a way to make the list IQueryable?Any other ideas or suggestions?
Well, I fixed it myself by creating an AsyncQueryable extension as mentioned here
Then I could call the pagedListAsync() method like bellow:
return View(await matchingCriterias.AsAsyncQueryable().ToPagedListAsync(pageNumber, pageSize)

how to delete data from in mvc3

I want to delete the data. here is my code. when i trying to delete the data it gives an error.
this is my code
public ActionResult delete(Int32 id)
{
var contentdelete = (from m in _db.tb_content
where m.id == id
select m).First();
return View(contentdelete);
}
public ActionResult delete(MvcNTL.Models.tb_content contentdelete)
{
var content = (from m in _db.tb_content
where m.id == contentdelete.id
select m).First();
if (!ModelState.IsValid)
return View(content);
_db.ApplyCurrentValues(content.EntityKey.EntitySetName, contentdelete);
_db.SaveChanges();
return RedirectToAction("index");
}
this is the error
The current request for action 'delete' on controller type 'ContentController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult delete(Int32) on type MvcNTL.Controllers.ContentController
System.Web.Mvc.ActionResult delete(MvcNTL.Models.tb_content) on type MvcNTL.Controllers.ContentController
You need to add [HTTPPOST] At your second delete controller. They both are get controllers now, so mvc doesn't know which one to pick.
You cannot have 2 actions with the same name on the same controller accessible with the same HTTP verb. You should decorate the second one with the [HttpPost] attribute:
[HttpPost]
public ActionResult delete(MvcNTL.Models.tb_content contentdelete)
{
var content = (from m in _db.tb_content
where m.id == contentdelete.id
select m).First();
if (!ModelState.IsValid)
return View(content);
_db.ApplyCurrentValues(content.EntityKey.EntitySetName, contentdelete);
_db.SaveChanges();
return RedirectToAction("index");
}
This makes the second action that is actually performing the delete accessible only with the POST verb. The first action will be accessible with the GET verb and would render the form.
[HttpPost]
public ActionResult delete(MvcNTL.Models.tb_content contentdelete)
{
var content = (from m in _db.tb_content
where m.id == contentdelete.id
select m).First();
if (!ModelState.IsValid)
return View(content);
_db.ApplyCurrentValues(content.EntityKey.EntitySetName, contentdelete);
_db.SaveChanges();
return RedirectToAction("index");
}

Pass a value from one controller to another in asp.net mvc

I've been new to ASP.NET MVC. This is what I'm doing. I've 2 Controllers:Home and Customerservice.
Now I have a Customer list where when I click details gets redirected to the products he acquired.
So, I need to pass in the id so that the products of that customer can be displayed. So, my home consists of customer details. Now i need to pass that id to CustomerService controller ,Index action. This is what I've done in Home:
public ActionResult Customers()
{
var dc = new ServicesDataContext();
var query = (from m in dc.Customers
select m);
return View(query);
}
public ActionResult Details(int id)
{
var datacontext = new ServicesDataContext();
var serviceToUpdate = datacontext.Customers.First(m => m.CustomerId == id);
ViewData.Model = serviceToUpdate;
// return View();
return Redirect("/CustomerService");
}
[HttpPost]
public ActionResult Details(FormCollection form)
{
var id = Int32.Parse(form["CustomerID"]);
var datacontext = new ServicesDataContext();
var service = datacontext.Customers.First(m => m.CustomerId == id);
return Redirect("Customers");
}
}
Now I'm not sure whether I need to pass an id as parameter for index in CustomerService. SO can you please guide me in finishing this?
If you are using any Redirect (such as RedirectToAction) you can use TempData to store any parameters. The semantics have slightly changed in MVC 3 but TempData is designed to pass data between actions in a POST-Redirect-GET scenario.
Passing it as a parameter is probably your best option. Try using something like return RedirectToAction(ActionName, ControllerName, RouteValues);.

ASP MVC Edit Post Function has null Parameter

I'm trying to create a very basic MVC app based on a tutorial. I am using the default routing, and simple Views and Model.
The problem I am having is with the HttpPost Edit function. I am expecting an object of my "MyObject" type to be passed as the parameter, but it always comes back null.
Here are my Edit functions from the controller (the Get function works properly):
public ActionResult Edit(int? id)
{
if (!id.HasValue)
return RedirectToAction("Index");
var item = (from obj in mDB.MyDatabaseObjects
where obj.Id == id
select obj).First();
return View(item);
}
//
// POST: /Main/Edit/5
[HttpPost]
public ActionResult Edit(MyDatabaseObject someObject)
{
var original = (from obj in mDB.MyDatabaseObjects
where obj.Id == someObject.Id
select obj).First();
if (!ModelState.IsValid)
return View(original);
mDB.ApplyCurrentValues(original.EntityKey.EntitySetName, someObject);
mDB.SaveChanges();
return RedirectToAction("Index");
}
Note that my (nearly identical) Create method works as expected:
[HttpPost]
public ActionResult Create([Bind(Exclude="Id")] MyDatabaseObject newObject)
{
if (!ModelState.IsValid)
return View();
int max = mDB.MyDatabaseObjects.Max(data => data.TaskOrder);
newObject.TaskOrder = max + 1;
mDB.AddToMyDatabaseObjects(newObject);
mDB.SaveChanges();
return RedirectToAction("Index");
}
Thanks,
wTs
Ensure the values on your view for MyDatabaseObject are inside of the form. Validate these values are being posted over - inspect Request.Form or use change the method signature to use
FormsCollection collection
simply to validate the values are getting posted. If its choosing that method - it should be matching the properties to the form field - its generally very simple.

MVC Delete record but how to code this in Controller

I'm a beginner of MVC3 with ASP.Net (C#) but I don't get the next situation to delete a record.
I have a View that ask the user to confirm delete a item (record). As code I have this to initialize the view:
public ActionResult KeywordsDelete(Guid id)
{
_db = new BlaContext();
return _db.SearchTerms.Where(x => x.id.Equals(id)).First();
}
But when confirmed, then I have the next code.
[HttpPost]
public ActionResult KeywordsDelete(Guid id)
{
_db = new BlaContext();
var term = _db.SearchTerms.Where(x => x.id == id).First();
_db.SearchTerms.Remove(term);
_db.SaveChanges();
return View("Keywords", _db.SearchTerms.ToList());
}
Building is not possible because the signature of this method is already exists (same parameters and method name).
So I don't get how to delete a record in this situation. The view is created with a default Scaffold template (delete).
I found an alternative solution to this problem while reading up on MVC. Check out: Improving the Details and Delete Methods
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)
{
// Delete stuff...
}
This will route the action Delete to the method DeleteConfirmed.
You can give your post function another additional parameter
[HttpPost]
public ActionResult KeywordsDelete(Guid id, FormCollection collection)
{
_db = new BlaContext();
var term = _db.SearchTerms.Where(x => x.id == id).First();
_db.SearchTerms.Remove(term);
_db.SaveChanges();
return View("Keywords", _db.SearchTerms.ToList());
}
But your GET Action should also return a View not a data object, I think.
public ActionResult KeywordsDelete(Guid id)
{
_db = new BlaContext();
return View(_db.SearchTerms.Where(x => x.id.Equals(id)).First());
}

Resources