EDIT: PER Felipe's answer, I changed the code in the webapiconfig to the following, and it works great-
config.Routes.MapHttpRoute( _
name:="DefaultApi", _
routeTemplate:="api/{controller}/{action}/{id}", _
defaults:=New With {.id = RouteParameter.Optional} _
)
config.Routes.MapHttpRoute(name:="API Default", routeTemplate:="api/{controller}/{action}/{id}", defaults:=New With { _
.id = RouteParameter.[Optional] _
})
I have a web api controller with 4 functions-
<HttpGet> _
<ActionName("AllCerts")> _
Public Function GetCerts() As Object
Dim LWCERTS As Array = objCert.GetCertificates
Return LWCERTS
End Function
<HttpGet> _
<ActionName("MyCerts")> _
Public Function GetMyCert() As Object
Dim lwMyCerts As Array = objCert.GetCertificates(Utilities.GetLogin())
Return lwMyCerts
End Function
<HttpGet> _
<ActionName("GetValueDDA")> _
Public Function GetDDABanks()
Dim objDDABankNum As New LucasEntities.Business.EF_DDA
Dim lwDDABankNum As Array = objDDABankNum.GetDDABankJSON()
Return lwDDABankNum
End Function
'' POST api/caapproval
<HttpPost> _
<ActionName("CertDtlsByID")> _
Public Function Post(value As CertDetailModel) As Object
Dim objCertPosting As New LucasEntities.Business.EF_CertificatePosting
Dim lwMyCertDetails As String = objCertPosting.GetBorrowingBaseAdvanceRequestJSON()
Return lwMyCertDetails
End Function
In my data service, I have the following ajax call-
var getallCertificates = function (CertificatesObservable) {
var dataObservableArray = ko.observableArray([]);
var newJ;
$.ajax({
type: "GET",
dataType: "json",
url: "/api/caapproval/AllCerts/",
async: false,
success: function (dataIn) {
newJ = $.parseJSON(dataIn);
CertificatesObservable([]);
dataIn.forEach(function (p) {
var certificate = new certificateModel(p.clientID, p.lwCertID, p.requestDate, p.userName, p.statusDescription, p.statusCode, p.statusDesc, p.ceoUserName, p.clientName, p.clientNumber, p.borrowBaseCount, p.advRequestCount, p.certType);
CertificatesObservable.push(certificate);
});
return CertificatesObservable(data);
},
error: function (error) {
jsonValue = jQuery.parseJSON(error.responseText);
//jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
}
});
return CertificatesObservable(newJ);
}
Here is my RouteConfig class-
Public Class RouteConfig
Public Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
routes.MapRoute( _
name:="Default", _
url:="{controller}/{action}/{id}", _
defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional} _
)
End Sub
End Class
When I put breakpoints in my controller, I see that the Post function under the CertDtlsByID actionName is always run, NOT GetCerts under the AllCerts ActionName. Being new to web api and routing, what am i doing wrong that causes the "Post" method to always be called?
When I run the web api directly in the browser, Chrome shows the following error-
Multiple actions were found that match the request: System.Object GetCerts() on type LucasNetApp.CAApprovalController System.Object GetMyCert() on type LucasNetApp.CAApprovalController System.Object GetDDABanks() on type LucasNetApp.CAApprovalController
In asp.net web api the routing is controlled by the WebApiConfig.cs file on the App_Start folder.
The ActionName attribute does not work because it is a behavouir of the asp.net mvc.
Open the WebApiConfig.cs file and try to add theses routes configurations:
config.Routes.MapHttpRoute(name:="DefaultApiGet",
url:="api/{controller}",
defaults:=New With {.action = "Get"},
constraints:=new With {.httpMethod = new HttpMethodConstraint(HttpMethod.Get)})
config.Routes.MapHttpRoute(name:="DefaultApiWithAction",
url:="api/{controller}/{action}")
I am not sure about the Vb.Net sintaxe, looks the same code in C#:
config.Routes.MapHttpRoute("DefaultApiGet",
"api/{controller}",
new {action = "Get"},
new {httpMethod = new HttpMethodConstraint(HttpMethod.Get)});
config.Routes.MapHttpRoute("DefaultApiWithAction",
"api/{controller}/{action}");
Related
I want to upload a image on server.I use ajax and webmethod, It works when I run code in local host but when I upload it in server it does not work.
I guess there are some problems in my webmethod but I could not find it.
function savefile(location, files, method_name) {
var data = new FormData();
var webmethod = "../WebService.asmx/" + method-name;
if (files.length > 0) {
data.append("UploadedFile", files[0]);
data.append("location", location);
}
var ajaxRequest = $.ajax({
type: "POST",
url: webmethod,
enctype: 'multipart/form-data',
contentType: false,
processData: false,
data: data
});
}
<WebMethod(EnableSession:=True)> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
Public Function savefile() As String
Try
Dim result As String = ""
Dim pdf As String = ""
If HttpContext.Current.Request.Files.AllKeys.Any() Then
Dim httpPostedFile = HttpContext.Current.Request.Files("UploadedFile")
If httpPostedFile IsNot Nothing Then
Dim location = HttpContext.Current.Request("location")
Dim extension As String = System.IO.Path.GetExtension(httpPostedFile.FileName)
Dim filename_widthout_extension As String = httpPostedFile.FileName.Substring(0, httpPostedFile.FileName.Length - extension.Length)
Dim file_name = httpPostedFile.FileName
Dim fileSavePath = System.IO.Path.Combine(Server.MapPath(HttpContext.Current.Request("location").ToString), filename_widthout_extension + postfix + extension)
result = (location + "/" + filename_widthout_extension + extension).ToString.Substring(2)
httpPostedFile.SaveAs(fileSavePath)
location = httpPostedFile.FileName
End If
Return ""
Catch ex As Exception
End Try
End Function
I am getting this error and I do not know how to get passed it. I am trying to do an ajax call to populate my data store. The error is:
Parsererror 'function' was not called when I do this :
var customStore = new DevExpress.data.CustomStore({
load: function () {
return $.ajax({
url: 'URL/Service/GetCustomers?callback=?fnsuccesscallback',
crossOrigin: true,
crossDomain: true,
jsonp: true,
type: 'GET',
dataType: 'jsonp',
contentType: "application/json; charset=utf-8",
jsonpCallback: 'fnsuccesscallback',
async: false,
success: function (res) {
console.log("success");
res = JSON.parse(res);
console.log("data _" + res);
},
error: function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
}
});
}
});
var fnsuccesscallback = function (data) {
alert(data);
};
var gridDataSourceConfiguration = {
store: customStore
};
My Service code for this function is :
Function GetCustomers() As Stream Implements IService.GetCustomers
Try
Dim Cust As List(Of Customers) = New List(Of Customers)
Dim SQLSTR As String = ""
SQLSTR = "Select Code, Name, ID FROM Table"
Dim ErrorMessage As String = ""
ErrorMessage = Obj.OpenConnection(SQLServer, UmbrellaDatabase, UserCode, UserPassword)
If ErrorMessage <> "" Then
System.Diagnostics.EventLog.WriteEntry("APP", ErrorMessage, EventLogEntryType.Error)
WebOperationContext.Current.OutgoingResponse.StatusCode = 501
WebOperationContext.Current.OutgoingResponse.StatusDescription = ErrorMessage
Return Nothing
Else
Dim CustomerDetails As DataSet
CustomerDetails = tObj.GetDataSQL(SQLSTR)
If Not CustomerDetails Is Nothing Then
CustomerDetails.DataSetName = "Companies"
CustomerDetails.Tables(0).TableName = "Companies"
Dim CustomerTable As DataTable
Dim CustomerRow As DataRow
If CustomerDetails.Tables.Count > 0 Then
CustomerTable = CustomerDetails.Tables(0)
If CustomerTable.Rows.Count > 0 Then
Dim i As Integer
For i = 0 To CustomerTable.Rows.Count - 1
CustomerRow = CustomerTable.Rows(i)
Dim CC As New Customers
CC.Code = CustomerRow.Item("Code")
CC.Name = CustomerRow.Item("Name")
CC.InternalID = CustomerRow.Item("InternalID")
Cust.Add(CC)
Next i
' Serialize the results as JSON
Dim serializer As DataContractJsonSerializer = New DataContractJsonSerializer(Cust.GetType())
Dim Stream As MemoryStream = New MemoryStream
serializer.WriteObject(Stream, Cust)
' Return the results serialized as JSON
Dim json As String = Encoding.Default.GetString(Stream.ToArray())
Return New MemoryStream(Encoding.UTF8.GetBytes(json))
Obj.CloseConnection()
WebOperationContext.Current.OutgoingResponse.StatusCode = 200
WebOperationContext.Current.OutgoingResponse.StatusDescription = "OK"
End If
End If
Else
System.Diagnostics.EventLog.WriteEntry("APP", ErrorMessage, EventLogEntryType.Error)
WebOperationContext.Current.OutgoingResponse.StatusCode = 501
WebOperationContext.Current.OutgoingResponse.StatusDescription = ErrorMessage
Cust = Nothing
Return Nothing
End If
End If
Catch ex As Exception
System.Diagnostics.EventLog.WriteEntry("Umbrella Mobile Service", ex.Message, EventLogEntryType.Error)
WebOperationContext.Current.OutgoingResponse.StatusCode = 501
WebOperationContext.Current.OutgoingResponse.StatusDescription = ex.Message
Return Nothing
End Try
Dispose()
End Function
How should my JSON output look like in my service in order to send out the correct callback? What should I do in order for this error not to show?
I have added two GET methods into webapi as follow:
public IList<ProductDTO> GetAllProducts()
{
ProductManager pm = new ProductManager();
return pm.RetrieveAllProducts();
//return pm.RetrieveAllProducts();
}
public ProductDTO GetProduct(int i)
{
ProductManager pm = new ProductManager();
return pm.RetrieveAllProducts().Where(c => c.Id == i).FirstOrDefault();
//return pm.RetrieveAllProducts();
}
Problem, when i only kept one get method GetAllProducts() then it works fine. but when i added GetProduct(int i) then giving me error as Not found 404 error.
Please guide me how i could keep both the mthod and allow to access method having argument.
calling as follow:
$.ajax({
type: 'GET',
url: 'api/values/GetProduct/1', //giving error as NOT FOUND
contentType: 'json',
dataType: 'json',
success: function (data) {
$.each(data, function (key, value) {
//stringify
alert(key);
alert(value);
var jsonData = JSON.stringify(value);
//Parse JSON
var objData = $.parseJSON(jsonData);
var id = objData.Id;
var Cost = objData.Cost;
var ProductName = objData.ProductName;
var Description = objData.Description;
$('<tr><td>' + id + '</td><td>' + ProductName +
'</td><td>' + Cost + '</td></tr>').appendTo('#ProductDivWebApi');
});
},
error: function (xhr) {
alert(xhr.responseText);
}
});
i have added this WEBAPI into MVC 4 project.
its route shows as below:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ProductManagement", action = "Index", id = UrlParameter.Optional }
);
}
Please guide
The routes on the ASP.NET WEB API is different than ASP.NET MVC. You have the GET methods, so, just call the controller using the GET verb and the framework will solve it for you. I recommend you rename the methods to a verb, Get, Post, Put, Delete, etc.
In your case, call the method by /api/{controller}/{id}. In this case, data is a single object (because you have returned only a ProductDTO), so do not loop in it.
You have specified json, so jquery will be deserialized it in a object for you. For sample:
$.ajax({
type: 'GET',
url: 'api/values/1',
contentType: 'json',
dataType: 'json',
success: function (data) {
// data is a single object, do not loop in it.
// you have specified json, so, it will be deserialized
var id = data.Id;
var Cost = data.Cost;
var ProductName = data.ProductName;
var Description = data.Description;
$('<tr><td>' + id + '</td><td>' + ProductName +
'</td><td>' + Cost + '</td></tr>').appendTo('#ProductDivWebApi');
});
},
error: function (xhr) {
alert(xhr.responseText);
}
});
I also recommend you to do some things like this on Web API:
[HttpGet]
public HttpResponseMessage GetProduct(int id)
{
ProductManager pm = new ProductManager();
var result = pm.RetrieveAllProducts().Where(c => c.Id == id).FirstOrDefault();
return Request.CreateResponse(HttpStatusCode.OK, result);
}
On the WebApiConfig.cs file I recommend you configure the routes like this:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("DefaultApiGet",
"api/{controller}",
new {action = "Get"},
new {httpMethod = new HttpMethodConstraint(HttpMethod.Get)});
config.Routes.MapHttpRoute("DefaultApiGetWithId",
"api/{controller}/{id}",
new {id = RouteParameter.Optional, action = "Get"},
new {id = #"\d+"});
config.Routes.MapHttpRoute("DefaultApiWithAction",
"api/{controller}/{action}");
config.Routes.MapHttpRoute("DefaultApiWithActionAndId",
"api/{controller}/{action}/{id}",
new {id = RouteParameter.Optional},
new {id = #"\d+(_\d+)?"});
}
I have a MVC Login page where I authenticate the user with an AJAX post method.
I want to redirect the user from Home/Index to another controller method Home/Main once the username and password are authenticated.
Here's my home controller:
Function Index() As ActionResult
Return View()
End Function
Function Main() As ActionResult
Return View()
End Function
Here is my ajax post method:
<script type="text/javascript">
$(document).ready(function () {
$('#BtnLogin').click(function () {
var userInfo = {
UserName: $('#txtusername').val(),
Password: $('#TxtPassword').val()
};
$.ajax({
url: '#Url.Content("~/api/Users/CheckUser")',
type: 'POST',
data: JSON.stringify(userInfo),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (responseData) {
for (var i = 0; i < responseData.length; i++) {
if (responseData[i].isErrorBool == '1') {
document.getElementById("LblErrors").innerHTML = responseData[i].isErrorMessage;
}
else {
//redirect
}
}
}
});
});
});
</script>
And my Web API:
<HttpPost>
Public Function CheckUser(LGIN As LoginModel) As List(Of VerifyReturnLogin)
Dim ReturnJson = Nothing
Dim sb As New StringBuilder()
Dim sw As New StringWriter(sb)
Try
Using jsonWriter As JsonWriter = New JsonTextWriter(sw)
jsonWriter.WriteStartArray()
jsonWriter.WriteStartObject()
Dim c As List(Of UserProfile) = userRepository.CheckUser(LGIN.UserName.Trim, LGIN.Password.Trim)
If c.Count = 0 Or c Is Nothing Then
jsonWriter.WritePropertyName("isErrorBool")
jsonWriter.WriteValue("1")
jsonWriter.WritePropertyName("isErrorMessage")
jsonWriter.WriteValue("Wrong Username or Password.")
jsonWriter.WriteEndObject()
jsonWriter.WriteEndArray()
ReturnJson = JsonConvert.DeserializeObject(Of List(Of VerifyReturnLogin))(sb.ToString)
Return ReturnJson
Else
'Redirect to Home/Main
End If
End Using
Catch ex As Exception
End Try
End Function
Where is the best place to redirect? Client or Server side?
And After login, is it wise to use Sessions in MVC like they are used in ASP.net, to ensure that the user is authenticated to go to Home/Main on every refresh?
Any help would be appreciated.
You should use in javascript window.location = "http://www.yoururl.com"; when you have
//redirect
Hi all i have ajax where i have some data And a controller action method ...i need to send the data to the controller action method ...when i am doing this it has null values in my controller method ,can any one correct me where am i doing worng...
<script type="text/javascript">
$(document).ready(function () {
$("#butValidateForm").click(function () {
UpdateMethod();
})
});
function UpdateMethod() {
var s = document.getElementById("EmployeeID");
var selecteditem1 = s.options[s.selectedIndex].value;
var a = document.getElementById("FromStatusId");
var selecteditem6 = a.options[a.selectedIndex].value;
var data = '{"AssignTo":"' + selecteditem1 + '","Status":"' + selecteditem6 + '"}';
alert(data);
$.ajax({
type: "POST",
url: "/ViewBug/Update/",
enctype: 'multipart/form-data',
data: data,
success: function () {
}
});
}
</script>
my contoller action method
[HttpPost]
public ActionResult Update(BugModel model, FormCollection form, string selecteditem1, string selecteditem6)
{
if (Session["CaptureData"] == null)
{
}
else
{
model = (BugModel)Session["CaptureData"];
}
ViewBag.AssignTo = new SelectList(GetEmployee(), "EmployeeID", "EmployeeName");
ViewBag.Status = new SelectList(GetFromStatus(), "FromStatusId", "FromStatus");
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand("sp_history", conn);
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
cmd.Parameters.Add("#Title", SqlDbType.VarChar).Value = model.Title;
cmd.Parameters.Add("#FixedById", SqlDbType.VarChar).Value = model.LoginName;
cmd.Parameters.Add("#AssignedId", SqlDbType.Int).Value = model.AssignTo;
cmd.Parameters.Add("#Resolution", SqlDbType.VarChar).Value = model.Resolution;
cmd.Parameters.Add("#FromStatus", SqlDbType.VarChar).Value =model.Status;
string fileName = string.Empty;
string StrFilePath = string.Empty;
foreach (BugAttachment objList in model.ListFile)
{
if (string.IsNullOrEmpty(StrFilePath))
{
fileName = objList.AttachmentName;
StrFilePath = objList.AttachmentUrl;
}
else
{
fileName = fileName + "," + objList.AttachmentName;
StrFilePath = StrFilePath + "," + objList.AttachmentUrl;
}
}
cmd.Parameters.Add("#AttachmentName", SqlDbType.VarChar).Value = fileName;
cmd.Parameters.Add("#BugAttachmentUrl", SqlDbType.VarChar).Value = StrFilePath;
cmd.Parameters.Add("#AttachedBy", SqlDbType.VarChar).Value = model.LoginName;
cmd.ExecuteNonQuery();
conn.Close();
}
return View("Edit");
}
Instead of
public ActionResult Update(BugModel model, FormCollection form, string selecteditem1, string selecteditem6)
give this a try:
public ActionResult Update(BugModel model, FormCollection form, string AssignTo, string Status)
You need to use the names of the property you have used in the object your sending back as you have named them AssignTo and Status. Hope this helps.
Edit:
Try sending the object like this:
var data ={};
data.AssignTo = selectedvalue1;
data.Status = selectedvalue6;
See if that makes any difference. If your still having issues can you inspect the request in firebug/developer tools?
Try this:
var data = { AssignTo: selecteditem1, Status: selecteditem6 };
also, as per Henry's answer, use the signature:
public ActionResult Update(BugModel model,
FormCollection form,
string AssignTo,
string Status)
tho, you should of course be able to get both the required values from the form[] collection, given that you are doing an HttpPost behind the scenes:
(i.e. var assignTo = form["AssignTo"]; etc).
[Edit] - out of curiousity, can I ask why you mix and match jquery syntax with more traditional javascript object syntax. one example being where you get the value of the EmployeeID option?? why not just use var selecteditem1 = $('#EmployeeID').val();.
I also notice the ViewBag object getting updated in your HttpPost action. Are you expecting to be able to use that on returning to the view -surely not (not in terms of the ajax request anyway). A quick explanation for my curiousity would be great. In my opinion, you are trying to do too much with this action (sure, keep it DRY - but) and I'm fearful that you'll end up getting into a corner with the number of different entry points you appear to be building up. I'd suggest a gentle rewind, just to keep things a little more focussed and each action having a single responsibility.
I ended up doing the following:
<script type="text/javascript">
$(document).ready(function () {
$("#butValidateForm").click(function () {
UpdateMethod();
})
});
function UpdateMethod() {
var s = document.getElementById("EmployeeID");
var selecteditem1 = s.options[s.selectedIndex].value;
var a = document.getElementById("FromStatusId");
var selecteditem6 = a.options[a.selectedIndex].value;
// var data = '{AssignTo:' + selecteditem1 + '}';
// alert(data);
var AssignTo;
var Title;
Title=$("#Title").val();
var FixedBy;
FixedBy = $("#LoginName").val();
var Resolution;
Resolution = $("#Resolution").val();
var Status;
Status = $("#FromStatusId").val();
$.ajax({
type: "POST",
url: "/ViewBug/Update/",
enctype: 'multipart/form-data',
data: {AssignTo:selecteditem1,Title:Title,FixedBy:FixedBy,Resolution:Resolution,Status:Status},
success: function () {
}
});
}
</script>