Html.RenderAction in MVC with EntityFramework - asp.net-mvc

My problem is when I try to render a view with two Html.RenderAction. It says: "The operation cannot be completed because the DbContext has been disposed".
I have Ninject configured in this way:
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope;
But If I do in the default way...
Bind<IUnitOfWork>().To<UnitOfWork>()
there's no error.
I have to work with it in RequestScope (so I think), but how can I do it? It seems's that when second Html.RenderAction is called the previous DbContext it's disposed !
UPDATED:
This is the main view (summarized for brevity)
#model FoodAway.Model.Product
#Html.ValidationSummary(true)
<fieldset>
<legend>Producto</legend>
#using (Html.BeginForm())
{
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
#Html.HiddenFor(model => model.Id)
<p>
<input type="submit" value="Guardar" />
</p>
}
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.Ingredients)
</div>
<div class="editor-field">
#{Html.RenderAction("IngredientsToRemoveList", "Ingredients");}
</div>
</fieldset>
<fieldset>
#{Html.RenderAction("IngredientsToAddList", "Ingredients");}
</fieldset>
</fieldset>
and his controller/action:
public ActionResult EditProduct(string name)
{
Product product = unitOfWork.ProductRepository.Get(i => i.Name ==name).FirstOrDefault();
if (product == null)
return HttpNotFound();
return View(product);
}
So, the error in DBContext is when I have this 2 RenderAction methods, the strange thing is if I have only 1 RenderAction there is no problem!!!!!

You need to enumerate the set before passing it to the view. This means that you query the database within the valid scope of the DbContext.
You can do this by using .ToArray() in your controller

Related

using viewmodel with create view

I have a ViewModel with two models in it which works find when displaying data. My problem is I want to add a foreach() within the Create.cshtml file. Any ideas?
----Create.cshml-----
#model demo.Models.ViewModel
#{ ViewBag.Title = "Create Reference";}<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Submission Form </legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-field">
<!-- iterate through ExternalContentModel and make checkboxes. -->
#foreach (var item in Model.ExternalContentModel)
{
<label class="checkbox">
<input type="checkbox" name="users" value="#item.auth_lname"> #item.auth_lname
</label>
}
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OrganizationName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OrganizationName)
#Html.ValidationMessageFor(model => model.OrganizationName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
------Controller-----
//
// GET: /Create
public ActionResult Create() <=== can this be the problem????
{
demo.Models.ViewModel vm = new demo.Models.ViewModel();
vm.ExternalContentModel = _repository.ExternalContent();
// Return the content from the External Model to the Create.
return View(vm);
}
//
// POST: /MailingReferences/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Reference reference) <=== can this be the problem????
{
if (ModelState.IsValid)
{
db.References.Add(reference);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(reference);
}
If you have different models then why don't you just create a editor templates for each model?
You can do this by creating a folder called "EditorTemplates" in the same folder your Create.cshtml view lives in. Now add a view for your model into that folder. The view should be named the same as your model class. E.g. a class called FooBarModel would have an editor template called FooBarModel.cshtml.
You would then just use the editor template by doing #Html.EditorFor(x => x.FooBar)

Adding model with user input and hard coded values

Okay so I am using the MVC framework. I have a view for adding a model. At the moment I am using the default "Create" controller.
I want to be able to create a model with my own variables pre-set. For example the model.UserId I want to set to the users Id. I want some values to be inputed by the user and I want some to be already set. Is there a way I could do something like this
(pseudo code)
model.matchId = 123
model.prediction type = "user input"
add model
here is my current code below
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Predictions</legend>
<div class="editor-label">
#Html.LabelFor(model => model.MatchId, "Match")
</div>
<div class="editor-field">
#Html.DropDownList("MatchId", String.Empty)
#Html.ValidationMessageFor(model => model.MatchId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserId, "User")
</div>
<div class="editor-field">
#Html.DropDownList("UserId", String.Empty)
#Html.ValidationMessageFor(model => model.UserId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Type)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Type)
#Html.ValidationMessageFor(model => model.Type)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Prediction)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Prediction)
#Html.ValidationMessageFor(model => model.Prediction)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
In the controller, you would set the values on the model before returning it to the View.
public class HomeController : Controller
{
public ActionResult About()
{
var model = new MyModel();
model.SomeId = 123;
model.SomeOtherProperty = "Hello World";
return View(model);
}
}

How do I bind data from Telerik ComboBox to my data model

Why won't my Telerik ComboBoxFor bind my value and fill my ComboBox via AJAX?
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-field">
#(Html.Telerik().ComboBoxFor(model => model.VendorId)
.Name("ddlVendor")
.ClientEvents(events =>
{
events.OnLoad("onVendorLoad");
//events.OnChange("onVendorChange");
events.OnDataBinding("onComboBoxDataBinding");
}
)
.DataBinding(bind => bind.Ajax().Select("_AjaxGetVendors", "Car"))
)
</div>
<p>
<input type="submit" value="Зберегти" />
</p>
</fieldset>}
In my controller I get entity but VendorId == 0.
[HttpPost]
public ActionResult Create(Car obj)
{
dm.InsertModel(obj);
return RedirectToAction("Create");
}
Option 1
Remove .Name("ddlVendor") from your ComboBox if you don't need it.
Option 2
Rename your ComboBox as follows and update any client event references to the control:
.Name("VendorId")

Form not 'POST'ing with a FormMethod.Post attribute

I have a form in a view like so:
#using (Html.BeginForm("CreateDTActionBasedOnSelectedMetaAction", "TestCase", FormMethod.Post))
And an action method with the following signature:
[AcceptVerbs( new string[]{"GET","POST"})]
public void CreateDTActionBasedOnSelectedMetaAction(FormCollection fc)
However, when the 'submit' button (located in the form) is clicked, it comes to the action method, but the Request.HttpMethod property shows a "GET", and obviously the form data is then not available in the FormCollection object as it wasn't posted.
Any thoughts?
UPDATE:part of the View:
#using (Html.BeginForm("CreateDTActionBasedOnSelectedMetaAction", "TestCase", FormMethod.Post)){
<fieldset>
<legend>Test Case</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
<p>#DTContext.CurrentTestCase.Name</p>
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Criteria)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Criteria)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DTTestCaseReqSet.DTMetaReqProcessor.DTMetaActions)
</div>
<div class="editor-field">
#Html.ListBox("MyListBox", new SelectList(Model.DTTestCaseReqSet.DTMetaReqProcessor.DTMetaActions.Where(p => p.Enabled == true), "NameWithID", "NameWithID"));
</div>
<p>
<input type="submit" value="Select" />
</p>
</fieldset>
}
UPDATE2:
Okay that was silly. Turns out that the app has a custom routing system written by another dev, which expected a certain parameter in the query string to be preserved, which my code wasn't doing. This resulted in the routing system taking the POST from the form, being unable to find a suitable method, it converted it to a GET, which then found my actionmethod.
I would request this question to be deleted.
Create two action methods. One for get and one for post.
[HttpPost]
public void CreateDTActionBasedOnSelectedMetaAction(FormCollection fc)
[HttpGet]
public void CreateDTActionBasedOnSelectedMetaAction()

JQuery UI Tab with form in ASP.NET MVC 3

I try to make user registation form. I have two user types and want to make two JQuery UI tabs with forms. But tab is empty and in java script console error "GET http://localhost/ParcDocs/Admin/Users/AddWorker 500 (Internal Server Error)".
Code of user registration page:
<script type="text/javascript">
$(document).ready(function() {
$("#tabContainer").tabs();
});
</script>
<div id="tabContainer">
<ul>
<li>#Html.ActionLink("Пользователь", "AddUser", "Users", null, null)</li>
<li>#Html.ActionLink("Сотрудник", "AddWorker", "Users", null, null)</li>
</ul>
</div>
PartialView code:
#model ParcDocs.Models.WorkerUser
#using (Html.BeginForm("AddWorker", "Users"))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Пользователь</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.RoleId, ((IEnumerable<ParcDocs.Models.Role>)ViewBag.PossibleRoles).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.Name),
Value = option.Id.ToString(),
Selected = (Model != null) && (option.Id == Model.RoleId)
}), "Выберете роль пользователя")
</div>
<p>
<input type="submit" value="Добавить" />
</p>
</fieldset>
}
Controller code:
public ActionResult AddWorker()
{
var model = new WorkerUser();
return PartialView(model);
}
Same behavior this second tab.
You should be returning a PartialViewResult, rather than an ActionResult. Put a breakpoint on public ActionResult AddWorker() and see what exception you get. Paste it here so that we have more information.

Resources