ASP .NET API Ajax How to update only some properties? - asp.net

I have a datatable and for each row there's a button. When clicked, it should set a property (field AvailableToCall) in my class. So I call an Ajax for my update method API passing the value (true) for the property. The problem is that when I do that, all the other properties (for example, name, adress, etc.) are set to null. Is there a way that I can update only a specific property leaving all the other properties of my table the same as before the AJAX call?
$.ajax({
url: "/api/person/" + personId,
type: "put",
data: {
AvailableToCall: true
}
}).done(function () {
// something
}
Thanks for the help.

Another way you could achieve this is a different endpoint:
$.ajax({
url: "/api/person/" + personId + "/availabletocall",
type: "put",
data: true
}).done(function () {
// something
}
So your url is something like below which accepts a body with a boolean:
/api/person/123/availabletocall
Your controller action could simply receive that single value and update whichever datasource you're using.

First of all you need to show your ApiController method.
I assume your method is like this,
public HttpResponseMessage Put(int id)
{
var _AvailableToCall = HttpContext.Current.Request.Form["AvailableToCall"];
//I'm using HttpContext to fetch the data in the above line. You can fetch
//the bool value as your way
//Now you just need to fetch the data by personId, (here it is id).
myClass obj = contextObj.myClass().where(m=>m.personId ==
id).firstOrDefault();
obj.AvailableToCall = true;
//That's it. Now you can update it.
contextObj.Entry(obj).State = System.Data.Entity.EntityState.Modified;
contextObj.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK, new { Status = "OK",
Message = e.ToString() });
//You can return your data as your requirements or as you are writing in
//your project.
}
See here "contextObj" is the object of my Context Class. And "myClass" is my modal class that I want to update/save data.
You can write "Json" return type in place of "HttpResponseMessage".
Cheers...

Related

Angular JS - send data to .NET Controller API

I have this angular js code here:
$http.post('/reports/', JSON.stringify($scope.user));
and its hitting my Reports Controller Post method:
[HttpPost]
public dynamic Post(Array data){
//do something
}
but when I check the data in my Post method when it hits in my breakpoint it appears as null :( how do I pass the data from $scope.user to my Controller. I did a console.log of $scope.user and the data is there, it is an object but trying to pass it in as JSON.
I found this:
public HttpResponseMessage Post([FromBody]Customer cust)
{
var newCust = _Repository.InsertCustomer(cust);
if (newCust != null)
{
var msg = new HttpResponseMessage(HttpStatusCode.Created);
msg.Headers.Location = new Uri(Request.RequestUri + newCust.ID.ToString());
return msg;
}
throw new HttpResponseException(HttpStatusCode.Conflict);
}
would I have to put [FromBody] Reports report instead of Array data
Just do this simple as possible, you are missing the parameter name:
$http.post('/reports/', {data: $scope.user});
Make sure that $scope.user is an Array, else change the type.

Validating a field based on a different database table / entity

I am writing an MVC 4 application, and using Entity Framework 4.1. I have a validation question which I cannot seem to find the answer to.
Essentially, I have an Entity (object) called "Product" which contains a field "Name", which must follow strict naming conventions which are defined in a separate Entity called "NamingConvention". When the user enters a value, the system needs to check it against the rules established in the NamingConvention entity, and return an error if need be.
Where should this validation be done, and how? I need to check the NamingConvention entity when doing the validation, which means I would need a database context since I'm referencing a different entity. Is there any validation method which won't require me to create a new context? I was thinking of doing the validation in the Controller, since it already creates a data context, but this doesn't seem like the right place to do it.
Thanks for any help!
I have done things like this using a JQuery post (ajax) call from the webpage where the name is being entered. You then post (the value of name) to a method on your controller which can return a JSON value that contains a flag saying if the validation passed and also a message that you want to return to your user. For example :
Javascript in webpage :
$("#name").change(function () {
var nameVal = $(this).val();
$.post(getRoot() + "/NameController/ValidateName", { name: nameVal },
function (data) {
if (data.valid == "true") {
alert("A valid name was chosen");
} else
{
alert(data.message);
}
}, "json");
});
Controller (NameController) Code :
[HttpPost]
public ActionResult ValidateName(string name)
{
// actual validation carried out in a static utility class (Utils.IsNameValid)
// if you are loading the same validation rules from your table each time
// consider caching the data in the application cache or a static List.
bool nameIsValid = Utils.IsNameValid(name, out string ErrorMessage);
JsonResult result = new JsonResult();
result.Data = new { valid = (nameIsValid "true" : "false"), message = ErrorMessage };
return result;
}
I'm using EF 5 but believe you can use this method ... apologies in advance if I'm misleading you with this answer.
You could do the validation within your context (or a context decorator)
public override int SaveChanges()
{
var products = this.GetChangedProducts();
foreach (var product in products)
{
this.ValidateName(product);
}
return base.SaveChanges();
}
private IEnumerable<Product> GetChangedProducts()
{
return (
from entry in _context.ChangeTracker.Entries()
where entry.State != EntityState.Unchanged
select entry.Entity)
.OfType<Product>();
}
private void ValidateName(Product product)
{
//validate here
}

How to call non static method from AJAX?

Here is my code behind I am calling from AJAX...
[WebMethod]
[ScriptMethod]
public static string save(string parameter)
{
country_master obj_country = new country_master();
obj_country.Country_Name = Page.Request.Params["name"].ToString().Trim();
obj_country.saved();
return "";
}
Here I am not able to access parameters passed from the page via Page.Request.
string name = HttpContext.Current.Request.QueryString["name"].Trim();
return "error";
after writing the first line, return statement does not return anything to the AJAX.
Please Help me how to do that.
Thanks...
To get the current context you can use HttpContext.Current, which is a static property.
Once you have that you can access things like session or profile and get information about the state of the site
HttpContext.Current.Session etc..
This link may help you : Call Server Side via AJAX without a Static Method
The reason behind restricting the web method to be static is to avoid it access the controls of the instance page.
Yo could use the HttpContext.Current static class, however you can skip that if you declare on your method the parameters you want to use and just pass the parameters with your AJAX call
You should pass parameters directly to the method.
I have several working examples on my Github repository, feel free to browse the code.
As a summary, to call a PageMethod:
Note: how using AJAX the jobID PageMethod parameter is being passed along with the request and how is used inside the PageMethod transparently
AJAX call
$.ajax({
type: 'POST',
url: '<%: this.ResolveClientUrl("~/Topics/JQuery/Ajax/PageMethods_JQueryAJAX.aspx/GetEmployees") %>',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: '{"jobID" : ' + jobID +'}',
async: false,
cache: false,
success: function (data) {
$('#employees').find('option').remove();
$.each(data.d, function (i, item) {
$('<option />').val(item.EmployeeID).text(item.FirstName).appendTo('#employees');
});
},
error: function (xhr) {
alert(xhr.responseText);
}
});
Page Method
[WebMethod]
public static List<EmployeeModel> GetEmployees(int jobID)
{
var ctx = new PubsDataContext();
return (from e in ctx.employee
where e.job_id == jobID
orderby e.fname
select new EmployeeModel
{
EmployeeID = e.emp_id,
FirstName = e.fname
}).ToList();
}

open a new window of view when call controller from Jquery Ajax post call

I'm using ASP.Net MVC2. I'm trying to open a new window of view when call controller from Jquery Ajax post call.
here is my code..
in ascx page..
$('#DeleteButton').click(function () {
var isLineChecked = $(':checkbox:checked', '#providerSearchResultsTable').length;
if (isLineChecked == 0) {
alert("Please select at least one row ");
return false;
}
else {
var params = {
Id: gaiSelected.join(',')
};
alert(params);
$.ajax({
type: "Post",
url: "SelectProviderAndContact",
data: params,
success: function (html) {
**//$('#SelectProviderAndContact').html(html);**
}
});
}
});
here is my controller Action method
[SessionFilter]
public ActionResult SelectProviderAndContact(string Id)
{
try
{
List<ProviderBaseInfo> providerList = null;
string[] internalProviderIDs = Id.Split(",".ToCharArray());
//string[] billingProviderNames = billingProvider.Split(",".ToCharArray());
IStateBag stateBag = _commonModel.GetStateBag();
//stateBag.SetValue("InternalProviderId", Id);
List<Guid> internalProviderIds = new List<Guid>();
foreach (var a in internalProviderIDs)
{
internalProviderIds.Add(new Guid(a));
}
List<Contacts> providerContactList = _providerModel.GetProviderContactlist(internalProviderIds);
if (providerContactList.Count <= 0)
{
//IStateBag stateBag = GetStateBag();
List<ProviderBaseInfo> providers = (List<ProviderBaseInfo>)stateBag.GetValue(ProviderListCache);
if (providers == null)
{
providerList = _providerModel.GetProviderCompleteList(null, null, null, null, Id).ToList();
}
else
{
providerList = providers.Where(x => internalProviderIds.Contains(x.InternalProviderId)).ToList();
}
providerContactList = _providerModel.GetContactlistbyInsertingProviders(providerList);
}
ViewData["ProviderNotFound"] = false;
// ViewData["ProviderName"] = new SelectList(billingProvider.Select(x => new { value = x, text = x }), "value", "text");
var Provider = new[] {
new { ProviderId = "A", Providername = "A" }
//new DataContracts.RegionKeyValues { RegionId = "B", RegionValue = "B" },
//new DataContracts.RegionKeyValues { RegionId = "D", RegionValue = "D" }
};
ViewData["ProviderName"] = new SelectList(Provider, "ProviderId", "Providername");
**return View("SelectProviderAndContact",providerContactList);**
}
catch (FaultException<MedicareFault> ex)
{
if (ex.Code.Name == typeof(ArgumentException).Name)
{
ViewData["ProviderNotFound"] = true;
ViewData["Error"] = ex.Reason;
return View((object)null);
}
else
{
ViewData["Error"] = Errors.Common.UnknownError;
return View((object)null);
}
}
catch
{
ViewData["Error"] = Errors.Common.UnknownError;
return View((object)null);
}
}
and I have created SelectProviderAndContact.aspx in view.
Please any one help me to open another window with SelectProviderAndContact.aspx
from ajax post call.
Your jquery will have to do almost all the work in opening a window. Using the window.open() method in your javascript you can make your controller send back a specific argument that causes it to open a new window with a certain URL (i.e. TheSmallPopupPageThatViewsResults.aspx?resultId=12345 or something).
Your controller would just decide whether or not to tell the view to open the new window and the view would then open it if it is told to.
With your specific implementation, you may have to create a model or something that stores results in the database so that the controller can save the result and the action and view that are for the popup page can then access that result. Another way of doing it would be to have the arguments that the popup page is called with determine what is viewed on the page. This would eliminate the need for another model, but your urls could get really long really fast if you have a lot of data and I believe that there is generally a limit to how long those urls can be.
I would recommend using JSON or XML to return the data to the javascript so that you can extend the returned object as much as needed. The way I have done it in the past is made several XML tags like <alert>, <refresh>, <redirect>, <somePageSpecificAction>, etc that I have jquery parse using $(theEnclosingTag).each( function () { //...parse here }).
I use mainly MVC3 so I don't know if this is supported in MVC2, but changing ActionResult to JsonResult for the return type and using return this.Json(new { put = "data here" }); for your return statements makes it really easy to use json.
Also, It may be beneficial to use a different action method to process ajax requests. You would then have one action that displays the page, another action to process ajax requests from that page (it could be decorated with [HttpPost] or something), and another method for your popup page view. That would also keep your code short and easier to read. Having long controller methods can get really confusing later down the line when you try to find the location of a specific bug.
EDIT: A specific example: Assuming MVC3 (since that is what I use...I think you can find other ways of doing this...you could use an xml serializer and just output xml) you have your page (Action #1) that displays with all your buttons and stuff (this is where you javascript containing the $("#DeleteButton") and such goes as well). Your javascript makes its AJAX call to another action (SelectContactAJAX or something...this is action #2) with a few arguments which has a return type of JsonResult. Your javascript gets the response back from that ajax-specific action and the response tells it "open a window with the URL /SelectContactForm?choiceId=12345" (or something). The choiceId is a reference that would be used in the background for the SelectContactForm action (yet another separate action...action #3) to know what to display. Your ajax would then call window.open("/SelectContactForm?choiceId=12345") and when the window opens, it calls action #3 which looks up the reference for what it should be displaying and then shows that to the user.
As for getting feedback on what the user entered in the new window and having the original page react, there are various ways in javascript to listen for window closings and such, but I haven't ever had to use this in one of my applications and it is a bit out of the scope of this question.
use colorbox jquery plugin
http://www.jacklmoore.com/colorbox
write code in .aspx page to call .ascx page
parent.$.fn.colorbox({ href: '/IGTR/SaveIGTRPreference/' + id + '?t=' + Math.random(), height: "400", width: "800", overlayClose: false, escKey: false
});
Here SaveIGTRPreference is .ascx page

RedirectToAction not working when called by jQuery?

I am trying to call an action method by jQuery, and got help with passing parameters here: Calling action method in MVC with jQuery and parameters not working . However, even though the parameters are sent correctly now, in the action method I need to redirect (passing on those same parameters) to another action method. In the debugger I can see that the redirect is carried out, and the parameters are still there, but the View returned doesn't update accordingly...
Is there some problem with calling an action method that redirects by using jQuery?
Action method called by jQuery:
public ActionResult SelectDate(string date)
{
DateTime dateObject = DateTime.Parse(date);
MyCalendar calendar = new MyCalendar();
string number = calendar.GetWeekNumber(dateObject).ToString();
string year = dateObject.Year.ToString();
return RedirectToAction("Edit", new { number = number, year = year });
}
Action method redirected to:
public ActionResult Edit(string number, string year) //Why string here???
{
int n;
if (string.IsNullOrEmpty(number))
n = myCalendar.GetWeekNumber(DateTime.Today);
else
n = Int32.Parse(number);
int y;
if (string.IsNullOrEmpty(year))
y = DateTime.Today.Year;
else
y = Int32.Parse(year);
List<Customer> customers = _repository.Customers;
ViewData["Customers"] = new SelectList(customers, "CustomerId", "CustomerName");
ViewData["WeekNumber"] = n;
ViewData["Year"] = y;
return View();
}
Or is jQuery get() not the proper way to call an action method to load a new page? Note that doing the same thing with an ActionLink works fine, it's just that I need to call it by jQuery because I'm using the datepicker plugin and also a button as the way to call the action.
What am I doing wrong?
UPDATE:
Actually, the RedirectToAction doesn't seem to be the problem, I modified the code so that the jQuery now calls the final action method directly (by doing the job of the first action method directly in the jQuery, i.e. convert date to week and year). But I still don't get the new page with the new week and year.
Here's the new jQuery:
function selectWeek() {
$('#selectWeekButton').click(function (event) {
var date = $('#selectWeekId').val();
var selectedDate = new Date(date);
var year = selectedDate.getFullYear();
var week = selectedDate.getWeekOfYear();
var url = '<%: Url.Action("Edit") %>';
$.get(url, { number: week, year: year }, function (data) {
// alert('Test');
});
});
}
Again, is it using the get that is incorrect? I do not wish to load content in an html tag, I just want to use jQuery to do the exact same thing as an actionlink, i.e. call an action method to get the Edit View...
For instance, this actionlink works fine, calling an action method called Next that redirects to Edit and shows the new week and year View:
<a href="<%=Url.Action("Next", new { number=ViewData["WeekNumber"], year = ViewData["Year"] })%>">
>></a>
But I want to do that (or Edit directly) in jQuery...
jquery AJAX automatically follows redirect meaning that in the success callback you will get the result of the Edit action you have redirected to. In this callback you will get the partial HTML returned by the controller action. So if you want to update some part of the DOM you need to explicitly instruct it so:
$.ajax({
url: '<%= Url.Action("SelectDate") %>',
data: { date: '123' },
success: function(result) {
$('#someresultDiv').html(result);
}
});
or simply use the .load() method:
$('#someresultDiv').load('<%= Url.Action("SelectDate") %>', { date: '123' });

Resources