An object specified for refresh is not recognized - c#

I have a update function like this:
public void Update(HomeBanner homebanner)
{
homebanner.EnsureValid();
DataSource.DataContext.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, homebanner);
DataSource.DataContext.SubmitChanges();
}
And i write a update controller
[AcceptVerbs(HttpVerbs.Post)]
//[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult ManageImages(int ? id,FormCollection form)
{
HomeBanner homebanner= BannerRepository.RetrieveById(id);
this.TryUpdateModel(homebanner);
string photoName = saveImage("photo");
if (photoName != string.Empty)
homebanner.ImageID = photoName;
BannerRepository.Update(homebanner);
return RedirectToAction("list", "Admin");
}
and then the view:
<% using (Html.BeginForm("ManageImages", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<h3>Manage Images</h3>
<div class="label-field">
<label for="ID">Chọn vị trí:</label>
<%= Html.DropDownList("ID", DataHelper.Banner().ToList().ToSelectList("value", "name",Model.HomeBanner.ID.ToString()))%>
</div>
<div class="label-field">
<label for="photo">
Chọn hình</label>
<input type="file" name="photo" value=""/>
</div>
<div class="label-field">
<label for="Link">
Liên kết</label>
<input type="text" name="Link"/>
</div>
<p>
<input type="submit" value="Lưu" />
</p>
<% } %>
It get data as well but update step is not success: It mark right here
DataSource.DataContext.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, homebanner);
and throw exception: An object specified for refresh is not recognized.
I dont know why, i see data filled to object when i debug. Plz someone help me!

Check the instance of DataContext there, maybe you are using different instance in which original object doesn't exists.
If it doesn't exist, you must first attach object to data context, then call refresh.
P.S. a tip: Make model or service for interacting with data, in controller it looks messy ;)'

I bump into this error because i was trying to update a just created object that did not exist yet on the database.

Related

Why do my checkboxes not pass their value to my controller in ASP.NET Core?

I feel this may be an easy fix but I cannot seem to get around it. I have an ASP.NET Core web application and I'm using an ajax form to submit data to my controller for processing. The problem I have is that my checkboxes always pass in as "false" even though they may be checked.
I searched for some answers but nothing I've tried has worked. Things like using the checked property, ensuring the name is correct.
Can anyone shed some light on why the values are ignored when the form is submitted to the controller and how I can fix it?
Form
<form asp-action="CreateCustomView" asp-controller="Data"
data-ajax="true"
data-ajax-method="POST">
<div class="row">
<div class="col">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="ColName" name="ColName" checked>
<label class="custom-control-label" for="ColName">Name</label>
</div>
</div>
<button type="reset">Reset</button>
<button type="submit">Save changes</button>
</form>
Model
namespace MyProject.Data
{
public class GridView : BaseEntity
{
public string Name { get; set; }
public bool ColName { get; set; }
}
}
DataController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MyProject.Data;
using Microsoft.AspNetCore.Mvc;
namespace MyProject.UI.Controllers
{
public class DataController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult CreateCustomView(GridView data)
{
//This method is incomplete, there is a break at the ActionResult to see what values are passed into `data`. In production, the values would be handled and the changes would be saved.
return View();
}
}
}
I have a breakpoint on the method CreateCustomView to see what values are passed, no matter what checkboxes I check, they are always being passed as false.
Can anyone help with this rather strange problem?
Update
As per the answer supplied by #Reyan-Chougle, if you're using CORE you need to supply the input as follows:
<input asp-for="#Model.ColType" type="checkbox" />
When the page is rendered, the control is automatically given a hidden field. Here is what the HTML of the above control renders as:
<input type="checkbox" class="custom-control-input" id="ColType" value="true" data-val="true" data-val-required="The ColType field is required." name="ColType">
<input type="hidden" value="false" id="ColType" name="ColType">
As you can see it creates a hidden checkbox with a value of false. This means that, as a boolean type it always has a value of true or false on submission.
As you are using ASP.NET Core, it is recommend to use the Tag Helpers:
<div class="form-group">
<label asp-for="#Model.ColName"></label>
<input asp-for="#Model.ColName" type="checkbox" />
</div>
If not using asp-for attribute , you can modify your codes to add a hidden field. It will be submitted regardless whether the checkbox is checked or not. If the checkbox is checked, the posted value will be true,false. The model binder will correctly extract true from the value. Otherwise it will be false :
<input type="checkbox" class="custom-control-input" data-val="true" id="ColName" name="ColName" value="true" checked>
<label class="custom-control-label" for="ColName">Name</label>
<input name="ColName" type="hidden" value="false">
I ran into a similar issue. There is a form we have that contains many fields that include textboxes, select (dropdown) menus, checkboxes and of course labels. All fields save to the database properly EXCEPT for the three checkbox options we have. I just figured out the fix after fooling with it off and on for weeks. I hope this helps someone:
This is what the code used to look like:
$(this).attr('data-val', 'true');
This is what fixed the problem:
$(this).val(true);
Here is the whole function that includes the fix:
$('form').on('change', ':checkbox', function () {
if (this.checked) {
$(this).val(true);
}
else {
$(this).val(false);
}
});
try to use
#Html.CheckBox("ColName", true)

List hidden value passes wrong value to controller

I have a list In my view. For each row, I view button and I am passing Id value as hidden. But when I click any button it is passing wrong hidden value to the controller. Always it passes the first-row hidden value to the controller.
View:
#foreach (var list in Model)
{
<div>
<div > #( ((int)1) + #Model.IndexOf(list)).</div>
<div >#list.details</div>
<div class="col-md-2 row-index">
<button class="btn btn-link" type="submit" name="action:view" id="view">View</button>
<input type="hidden" name="viewId" id="viewId" value="list.WId" />
</div>
</div>
}
Controller:
[HttpPost]
[MultipleButton(Name = "action", Argument = "view")]
public ActionResult ViewDetail(string viewId)
{
return RedirectToAction("ViewDetails");
}
To get all values you need to change the input value type in your controller to array of strings.
I hope that this solution can help you
[HttpPost]
[MultipleButton(Name = "action", Argument = "view")]
public ActionResult ViewDetail(string[] viewId)
{
return RedirectToAction("ViewDetails");
}
if you want to get the exact value you need to duplicate the form within your foreach
in this case you should write somthing like this :
#foreach (var list in Model)
{
<div>
<div > #( ((int)1) + #Model.IndexOf(list)).</div>
<div >#list.details</div>
<div class="col-md-2 row-index">
<form ... > // complete your form attributes
<button class="btn btn-link" type="submit" name="action:view" id="view">View</button>
<input type="hidden" name="viewId" id="viewId" value="list.WId" />
</form>
</div>
</div>
}
Note : You should delete the global form
You should have one form for each row. then you submit that row.
Otherwise as you state it passes first value.
You are setting each value to the same element ID (which is invalid anyway) and name. When you submit your form (which would be more helpful to fully answer your question) it is finding the first element that matches that criteria and submitting it.
There are multiple ways to resolve this such as the already mentioned form per entry but the other preference would be to modify you button to a div and add a click handler to pass the specific value to a js function which would then submit to the controller. Its a preference choice regarding how tightly coupled you want your front end. But the main problem is your element naming convention.

Asp.net MVC - form is not sent to controller

In a Asp.net MVC view, i created a form, with a input field.
The user Sets a first name (or part of it), presses the submit button.
This is the form section:
<div>
<form action="SearchCustomer" methos="post">
Enter first name: <input id="Text1" name="txtFirstName" type="text" />
<br />
<input id="Submit1" type="submit" value="Search Customer" />
</form>
</div>
This is the SearchCustomer in the Controller, that gets the data from the form:
CustomerDal dal = new CustomerDal();
string searchValue = Request.Form["txtFirstName"].ToString();
List<Customer> customers = (from x in dal.Customers
where x.FirstName.Contains(searchValue)
select x).ToList<Customer>();
CustomerModelView customerModelView = new CustomerModelView();
customerModelView.Customers = customers;
return View("ShowSearch", customerModelView);
When i run the program, and enter a first name ("Jhon" for example), the code returns to SearchCustomer function, but Request.Form is empty.
Why?
Thanks.
Your method is spelled wrongly should not read methos but method like below:
<form action="SearchCustomer" method="post">
....
</form>
You need to modify your code:
you need to provide a action name here, which should be defined in your controller(SearchController) with the same name as 'ActionName' you will put in the below code.
if SearchController is your action name then provide the controller in which the action is available.
<div>
<form action="SearchCustomer/<ActionName>" method="post">
Enter first name: <input id="Text1" name="txtFirstName" type="text" />
<br />
<input id="Submit1" type="submit" value="Search Customer" />
</form>
</div>
With Html.BeginForm :
#using (Html.BeginForm("<ActionName>","<ControllerName>", FormMethod.Post))
{
Enter first name: <input id="Text1" name="txtFirstName" type="text" />
<br />
<input id="Submit1" type="submit" value="Search Customer" />
}
Set [HttpPost] on your controller.
[HttpPost]
public ActionResult SearchFunction(string txtFirstName)
{
CustomerDal dal = new CustomerDal();
string searchValue = txtFirstName;
List<Customer> customers = (from x in dal.Customers
where x.FirstName.Contains(searchValue)
select x).ToList<Customer>();
CustomerModelView customerModelView = new CustomerModelView();
customerModelView.Customers = customers;
return View("ShowSearch", customerModelView);
}
If you View is the same name as your ActionResult method, try this:
#using(Html.BeginForm())
{
... enter code
}
By default, it'll already be a POST method type and it'll be directed to the ActionResult. One thing to make sure of: You will need the [HttpPost] attribute on your ActionResult method so the form knows where to go:
[HttpPost]
public ActionResult SearchCustomer (FormCollection form)
{
// Pull from the form collection
string searchCriteria = Convert.ToString(form["txtFirstName"]);
// Or pull directly from the HttpRequest
string searchCriteria = Convert.ToString(Request["txtFirstName"]);
.. continue code
}
I hope this helps!

ASP.NET : Error - Server Error in '/' Application

i'm working on ASP.NET MVC project and every time i tried to run my view Register.cshtml i get this error :
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /User/Register
i'm trying to develop a Registration page with a view code :
#{
ViewBag.Title = "Register";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Register</h2>
<form action='#Url.Action("Register", "Controller")'>
<input type="hidden" name="FormType" value="A" />
<input type="hidden" name="FormType" value="B" />
<input type="text" name="Name" placeholder="enter your name" />
<input type="text" name="Password" placeholder="enter your name" />
<input type="radio" name="typeOfForm" class="radioBtn" value="A">Form A
<input type="radio" name="typeOfForm" class="radioBtn" value="B">Form B
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div style="display: none" id="formA" action="/actionA">
<input type="text" name="City" placeholder="City" /> <input type="submit" value="Register Me!" />
</div>
<div style="display: none" id="formB" action="/actionB">
<input type="text" name="Age" placeholder="Age" /><input type="submit" value="Register Me!" />
</div></form>
<script>
$('.radioBtn').click(function () {
var formType = $(this).val();
//alert(formType);
if (formType == "A") {
$('#FormA').show();
$('#FormB').hide();
} else {
$('#FormB').show();
$('#FormA').hide();
}
});</script>
with a UserController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace BootstrapSite4.Controllers
{
public class UserController : Controller
{ [HttpGet]
[HttpPost]
// GET: User
public ActionResult Register(char FormType, string name, string password)
{
Seller S = new Seller();
DeliveryMan D = new DeliveryMan();
if (FormType=='A')
S.Name = name;
else
D.Name = name;
return View();}}}
i tried to change my RegisterRoutes but still getting the same error .. i think my error with the location only ! just a briefly description about the registration idea : i have tow types of users that will fill the registration form and depending on what they have chosen(in radio buttons) the rest of the form will appear in the same page to let them continue registration then add it to the right database .
You need to add an HttpGet Register method to the UserController as well:
[HttpGet]
public ActionResult Register()
{
return View();
}
Remember that you need 2 Register methods:
GET - Requests data from a resource - in this case requests to go to the Register view.
POST - Submitting data - in this case sends users info to the server, to register the user.
More reading on Http Get and Post

MVC razor form with multiple different submit buttons?

A Razor view has 3 buttons inside a form. All button's actions will need form values which are basically values coming input fields.
Every time I click any of buttons it redirected me to default action. Can you please guide how I can submit form to different actions based on button press ?
I really appreciate your time, guidance and help.
You could also try this:
<input type="submit" name="submitbutton1" value="submit1" />
<input type="submit" name="submitbutton2" value="submit2" />
Then in your default function you call the functions you want:
if( Request.Form["submitbutton1"] != null)
{
// Code for function 1
}
else if(Request.Form["submitButton2"] != null )
{
// code for function 2
}
This elegant solution works for number of submit buttons:
#Html.Begin()
{
// Html code here
<input type="submit" name="command" value="submit1" />
<input type="submit" name="command" value="submit2" />
}
And in your controllers' action method accept it as a parameter.
public ActionResult Create(Employee model, string command)
{
if(command.Equals("submit1"))
{
// Call action here...
}
else
{
// Call another action here...
}
}
in the view
<form action="/Controller_name/action" method="Post>
<input type="submit" name="btn1" value="Ok" />
<input type="submit" name="btn1" value="cancel" />
<input type="submit" name="btn1" value="Save" />
</form>
in the action
string str =Request.Params["btn1"];
if(str=="ok"){
}
if(str=="cancel"){
}
if(str=="save"){
}
You can use JS + Ajax.
For example, if you have any button you can say it what it must do on click event.
Here the code:
<input id="btnFilterData" type="button" value="myBtn">
Here your button in html:
in the script section, you need to use this code (This section should be at the end of the document):
<script type="text/javascript">
$('#btnFilterData').click(function () {
myFunc();
});
</script>
And finally, you need to add ajax function (In another script section, which should be placed at the begining of the document):
function myFunc() {
$.ajax({
type: "GET",
contentType: "application/json",
url: "/myController/myFuncOnController",
data: {
//params, which you can pass to yu func
},
success: function(result) {
error: function (errorData) {
}
});
};
This is what worked for me.
formaction="#Url.Action("Edit")"
Snippet :
<input type="submit" formaction="#Url.Action("Edit")" formmethod="post" value="Save" class="btn btn-primary" />
<input type="submit" formaction="#Url.Action("PartialEdit")" formmethod="post" value="Select Type" class="btn btn-primary" />
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit( Quote quote)
{
//code
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PartialEdit(Quote quote)
{
//code
}
Might help some one who wants to have 2 different action methods instead of one method using selectors or using client scripts .
The cleanest solution I've found is as follows:
This example is to perform two very different actions; the basic premise is to use the value to pass data to the action.
In your view:
#using (Html.BeginForm("DliAction", "Dli", FormMethod.Post, new { id = "mainForm" }))
{
if (isOnDli)
{
<button name="removeDli" value="#result.WeNo">Remove From DLI</button>
}
else
{
<button name="performDli" value="#result.WeNo">Perform DLI</button>
}
}
Then in your action:
public ActionResult DliAction(string removeDli, string performDli)
{
if (string.IsNullOrEmpty(performDli))
{
...
}
else if (string.IsNullOrEmpty(removeDli))
{
...
}
return View();
}
This code should be easy to alter in order to achieve variations along the theme, e.g. change the button's name to be the same, then you only need one parameter on the action etc, as can be seen below:
In your view:
#using (Html.BeginForm("DliAction", "Dli", FormMethod.Post, new { id = "mainForm" }))
{
<button name="weNo" value="#result.WeNo">Process This WeNo</button>
<button name="weNo" value="#result.WeNo">Process A Different WeNo This Item</button>
}
Then in your action:
public ActionResult DliAction(string weNo)
{
// Process the weNo...
return View();
}
Try wrapping each button in it's own form in your view.
#using (Html.BeginForm("Action1", "Controller"))
{
<input type="submit" value="Button 1" />
}
#using (Html.BeginForm("Action2", "Controller"))
{
<input type="submit" value="Button 2" />
}
You could use normal buttons(non submit). Use javascript to rewrite (at an 'onclick' event) the form's 'action' attribute to something you want and then submit it. Generate the button using a custom helper(create a file "Helper.cshtml" inside the App_Code folder, at the root of your project) .
#helper SubmitButton(string text, string controller,string action)
{
var uh = new System.Web.Mvc.UrlHelper(Context.Request.RequestContext);
string url = #uh.Action(action, controller, null);
<input type=button onclick="(
function(e)
{
$(e).parent().attr('action', '#url'); //rewrite action url
//create a submit button to be clicked and removed, so that onsubmit is triggered
var form = document.getElementById($(e).parent().attr('id'));
var button = form.ownerDocument.createElement('input');
button.style.display = 'none';
button.type = 'submit';
form.appendChild(button).click();
form.removeChild(button);
}
)(this)" value="#text"/>
}
And then use it as:
#Helpers.SubmitButton("Text for 1st button","ControllerForButton1","ActionForButton1")
#Helpers.SubmitButton("Text for 2nd button","ControllerForButton2","ActionForButton2")
...
Inside your form.
Simplest way is to use the html5 FormAction and FormMethod
<input type="submit"
formaction="Save"
formmethod="post"
value="Save" />
<input type="submit"
formaction="SaveForLatter"
formmethod="post"
value="Save For Latter" />
<input type="submit"
formaction="SaveAndPublish"
formmethod="post"
value="Save And Publish" />
[HttpPost]
public ActionResult Save(CustomerViewModel model) {...}
[HttpPost]
public ActionResult SaveForLatter(CustomerViewModel model){...}
[HttpPost]
public ActionResult SaveAndPublish(CustomerViewModel model){...}
There are many other ways which we can use, see this article ASP.Net MVC multiple submit button use in different ways
As well as #Pablo's answer, for newer versions you can also use the asp-page-handler tag helper.
In the page:
<button asp-page-handler="Action1" type="submit">Action 1</button>
<button asp-page-handler="Action2" type="submit">Action 2</button>
then in the controller:
public async Task OnPostAction1Async() {...}
public async Task OnPostAction2Async() {...}
Didn't see an answer using tag helpers (Core MVC), so here it goes (for a delete action):
On HTML:
<form action="" method="post" role="form">
<table>
#for (var i = 0; i < Model.List.Count(); i++)
{
<tr>
<td>#Model.List[i].ItemDescription</td>
<td>
<input type="submit" value="REMOVE" class="btn btn-xs btn-danger"
asp-controller="ControllerName" asp-action="delete" asp-route-idForDeleteItem="#Model.List[i].idForDeleteItem" />
</td>
</tr>
}
</table>
</form>
On Controller:
[HttpPost("[action]/{idForDeleteItem}"), ActionName("Delete")]
public async Task<IActionResult> DeleteConfirmed(long idForDeleteItem)
{
///delete with param id goes here
}
Don't forget to use [Route("[controller]")] BEFORE the class declaration - on controller.
Information acquired from:
http://www.codedigest.com/posts/46/multiple-submit-button-in-a-single-form-in-aspnet-mvc
For you chaps coming more recently, you can use the HTML 5 Formaction Attribute.
In your <input> or <button>
Just define:
<button id="btnPatientSubmit" type="submit" class="btn btn-labeled btn-success" formaction="Edit" formmethod="post">
Notice the addition of formation= "Edit", this specifies which ActionResult I want to submit to in my controller.
This will allow you to have multiple submit buttons, where each could submit to independent ActionResults (Methods) in your controller.
This answer will show you that how to work in asp.net with razor, and to control multiple submit button event. Lets for example we have two button, one button will redirect us to "PageA.cshtml" and other will redirect us to "PageB.cshtml".
#{
if (IsPost)
{
if(Request["btn"].Equals("button_A"))
{
Response.Redirect("PageA.cshtml");
}
if(Request["btn"].Equals("button_B"))
{
Response.Redirect("PageB.cshtml");
}
}
}
<form method="post">
<input type="submit" value="button_A" name="btn"/>;
<input type="submit" value="button_B" name="btn"/>;
</form>
In case you're using pure razor, i.e. no MVC controller:
<button name="SubmitForm" value="Hello">Hello</button>
<button name="SubmitForm" value="World">World</button>
#if (IsPost)
{
<p>#Request.Form["SubmitForm"]</p>
}
Clicking each of the buttons should render out Hello and World.

Categories