i'm trying to get my apicontroller to work. But somehow i cannot return Json().
Here's the error message from the compiler:
Error CS0029 Cannot implicitly convert type
'System.Web.Http.Results.JsonResult<>'
to
'System.Web.Mvc.JsonResult' Opten.Polyglott.Web D:\Development\git\Opten.Polyglott\src\Opten.Polyglott.Web\Controllers\NewsletterApiController.cs
I cannot explain why it cannot convert the Json() to the ActionResult even the Json()inherits ActionResult.
Here's my controller:
using MailChimp;
using MailChimp.Helper;
using Opten.Polyglott.Web.Models;
using Opten.Umbraco.Common.Extensions;
using System.Configuration;
using System.Web.Mvc;
using Umbraco.Core.Logging;
using Umbraco.Web.WebApi;
namespace Opten.Polyglott.Web.Controllers
{
public class NewsletterApiController : UmbracoApiController
{
public ActionResult Subscribe(Newsletter newsletter)
{
bool isSuccessful = false;
if (ModelState.IsValid)
{
isSuccessful = SubscribeEmail(newsletter.Email);
}
return Json(new { isSuccess = isSuccessful });
}
}
}
Thanks for any help.
Your problem is within the usings as the UmbracoApiController most likely inherits from ApiController (from System.Web.Http) not Controller (from System.Web.Mvc) and thus they have different dependencies. To fix your problem first remove the
using System.Web.Mvc;
and put the
using System.Web.Http;
as for the return in this case that would be IHttpActionResult so you would have something as follows:
using MailChimp;
using MailChimp.Helper;
using Opten.Polyglott.Web.Models;
using Opten.Umbraco.Common.Extensions;
using System.Configuration;
using System.Web.Http;
using Umbraco.Core.Logging;
using Umbraco.Web.WebApi;
namespace Opten.Polyglott.Web.Controllers
{
public class NewsletterApiController : UmbracoApiController
{
public IHttpActionResult Subscribe(Newsletter newsletter)
{
bool isSuccessful = false;
if (ModelState.IsValid)
{
isSuccessful = SubscribeEmail(newsletter.Email);
}
return Json(new { isSuccess = isSuccessful });
}
}
}
Let me know if that works for you.
It seems your Json is using class in System.Web.Http, not in System.Web.Mvc. In this case, you can use this code:
return new JsonResult{ isSuccess = isSuccessful };
When using ActionResult using Response.StatusCode is a good practice:
public ActionResult SomeMethod()
{
try
{
// ...
// doing something here...
// ...
// success:
Response.StatusCode = (int)HttpStatusCode.OK;
return Json(new { responseText = "OK" });
}
catch
{
// error:
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { responseText = "ERROR" });
}
}
Add the following line in your WebApiConfig.cs file:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Related
I just started learning c#, ASP.net, and I have this issue. This is the code. I have a model in the models folder called Role.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace xrakFRS.Models {
public class Role {
[Key]
public int ID { get; set; }
public string Rolename { get; set; }
public string Description { get; set; }
}
}
This is my RolesController
using xrakFRS.Data;
using xrakFRS.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
namespace xrakFRS.Controllers {
[EnableCors("*", "*", "*"), RoutePrefix("api/roles")]
public class RolesController : ApiController{
[HttpGet]
[Route("getroles")]
public IHttpActionResult GetRoles() {
try {
using (var context = new AppDbContext()) {
var entries = context.Roles.ToList();
return Ok(entries);
}
} catch (Exception ex) {
return BadRequest(ex.Message);
}
}
[HttpPost]
[Route("postrole")]
public IHttpActionResult PostRole([FromBody] Role role) {
if (!ModelState.IsValid) return BadRequest(ModelState);
try {
using (var context = new AppDbContext()) {
context.Roles.Add(role);
context.SaveChanges();
return Ok("Entry was created");
}
} catch (Exception ex) {
return BadRequest(ex.Message);
}
}
When I try to call the api using Postman, I get this:
When I try to inspect the variables at the breakpoints, I get null values:
I get null values for "Rolename" and "Description". I am not sure why my data is not binding on the controller.
try sending raw body from Postman
{
"rolename": "Admin user for the application",
"description": "Administrator"
}
go to postman body-> select raw and from dropdown menu json
then go to body and add
{
"roleId":1,
"rolename":" bla bla",
"description" : " bla bla"
}
Try using x-www-form-urlencoded via postman and remove [FromBody] attribute. It will automatically map varriables to the object. The code will look like:
[HttpPost]
[Route("postrole")]
public IHttpActionResult PostRole(Role role) {
//Any logic here
}
How the request should look like in the Postman
Postman should look like this
I have an error in this code. I deserialize a JSON file and stored that data in the database now I want to show that data from my database.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Helpers;
using System.Web.Mvc;
using ReadingFromDb.Dto;
namespace ReadingFromDb.Controller
{
public class StudentController
{
[HttpGet]
[AllowAnonymous]
public async Task<JsonResult> GetStudents()
{
using (var context = new UNIEntities1())
{
var query = #"Select ";
var dbQuery = context.Database.SqlQuery<StudentDto>(query);
var list = await dbQuery.ToListAsync();
return Json(list,JsonRequestBehavior.AllowGet);
}
}
}
}
Error is:
JSON can not be used like method.
What should I do?
Your contoller must be extend the base class Controller in which the Json() virtual method is available:
public class StudentController : Controller
{
// your code
}
To resolve this error you can try as below
public class StudentController : Controller
{
// your code
}
[HttpGet]
[AllowAnonymous]
public async Task<JsonResult> GetStudents()
{
using (var context = new UNIEntities1())
{
var list = await context.StudentDto.ToListAsync();
return Json(list,JsonRequestBehavior.AllowGet);
}
}
What you need to do is to extend your StudentCotroller with Controller then put your code under that.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Helpers;
using System.Web.Mvc;
using ReadingFromDb.Dto;
namespace ReadingFromDb.Controller
{
public class StudentController:Controller
{
[HttpGet]
[AllowAnonymous]
public async Task<JsonResult> GetStudents()
{
using (var context = new UNIEntities1())
{
var query = #"Select ";
var dbQuery = context.Database.SqlQuery<StudentDto>(query);
var list = await dbQuery.ToListAsync();
return Json(list,JsonRequestBehavior.AllowGet);
}
}
}
}
I am receiving the following error: The name 'Ok' does not exist in the current context.
How would I resolve this issue in my Controller API? Return Ok is already embedded in the controller.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using Newtonsoft.Json;
using WeatherTest.Models;
namespace WeatherChecker.Controllers
{
public class WeatherData
{
[HttpGet("[action]/{city}")]
public async Task<IActionResult> City(string city)
{
using (var client = new HttpClient())
{
try
{
client.BaseAddress = new Uri("http://api.openweathermap.org");
var response = await client.GetAsync($"/data/2.5/weather?q={city}&appid=YOUR_API_KEY_HERE&units=metric");
response.EnsureSuccessStatusCode();
var stringResult = await response.Content.ReadAsStringAsync();
var rawWeather = JsonConvert.DeserializeObject<OpenWeatherResponse>(stringResult);
// Error Here: ** The name 'Ok' does not exist in the current context **
return Ok(new
{
Temp = rawWeather.Main.Temp,
Summary = string.Join(",", rawWeather.Weather.Select(x => x.Main)),
City = rawWeather.Name
});
}
catch (HttpRequestException httpRequestException)
{
// Error Here: The name 'BadRequest' does not exist in the current context
return BadRequest($"Error getting weather from OpenWeather: {httpRequestException.Message}");
}
}
}
}
}
With Attribute routing feature, aspnet support POCO controller. It allow to use any class as controller. But you will we lose all utilities and helpers provided by framework base classes.
The class Controller inherite from ControllerBase and add view support. In your case, ControllerBase is enough.
public class WeatherData : ControllerBase // <-
{
// ...
}
I wan to make custom method in Api controller and call it from angularJS $http.(get/post).
I have a view .cshtml where i use ng-repeat to get data from database given below..
Now i want to make a custom method in web api to update only 1 field (Status=1) when admin click Approve
my Api controller is :
using AttributeRouting;
using AttributeRouting.Web.Mvc;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
namespace HRM_Project.Controllers
{
[RoutePrefix("api/EmployeeLeaveApi")]
public class EmployeeLeaveApiController : ApiController
{
private HRM27Entities db = new HRM27Entities();
// GET api/EmployeeLeaveApi
public IEnumerable<EmployeeLeave> GetEmployeeLeaves()
{
var employeeleaves = db.EmployeeLeaves.Include(e => e.Employee);
return employeeleaves.AsEnumerable();
}
// GET api/EmployeeLeaveApi/5
public EmployeeLeave GetEmployeeLeave(int id)
{
EmployeeLeave employeeleave = db.EmployeeLeaves.Find(id);
if (employeeleave == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return employeeleave;
}
PUT api/EmployeeLeaveApi/5
public HttpResponseMessage PutEmployeeLeave(int id, EmployeeLeave employeeleave)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (id != employeeleave.LeaveID)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
db.Entry(employeeleave).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
// POST api/EmployeeLeaveApi
public HttpResponseMessage PostEmployeeLeave(EmployeeLeave employeeleave)
{
if (ModelState.IsValid)
{
db.EmployeeLeaves.Add(employeeleave);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, employeeleave);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = employeeleave.LeaveID }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// DELETE api/EmployeeLeaveApi/5
public HttpResponseMessage DeleteEmployeeLeave(int id)
{
EmployeeLeave employeeleave = db.EmployeeLeaves.Find(id);
if (employeeleave == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.EmployeeLeaves.Remove(employeeleave);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, employeeleave);
}
// [Route("Api/goals/update/{id}")]
[HttpGet]
[Route("Api/EmployeeLeaveApi/ApproveLeave/{id}")]
public string ApproveLeave(int id, EmployeeLeave obj)
{
var leaveIdFound = db.EmployeeLeaves.FirstOrDefault(x => x.LeaveID == id);
if (leaveIdFound != null)
{
leaveIdFound.Status = obj.Status;
db.SaveChanges();
return "Customer updated successfully!";
}
return "Customer updated fails!";
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
I also installed AttributeRouting package.
But when i test the using "http://localhost:30429/Api/EmployeeLeaveApi/ApproveLeave/" link i got error! Error:
{"Message":"An error has occurred.","ExceptionMessage":"Multiple
actions were found that match the request:
\r\nHRM_Project.EmployeeLeave GetEmployeeLeave(Int32) on t....
I just wanna push a query like that
update leaveTable set status="1" where Leaveid=12"
others field will be remined unchanged.
,how can do this?
Anyone one tell how can i make and use a custome web api method from angular?
cshtml :
<a href="" ng-click="approveLeave(item.LeaveID)"
JS file:
$scope.approveLeave = function (a) {
$http.put('http://localhost:30429/api/employeeleaveApi/' + a)
.success(function (data) {
console.log("inserted succes");
}).error(function () {
});
I have an web api controller
using sport.BLL.Abstract;
using sport.BLL.Concrete;
using sport.DAL.Entities;
using sport.webApi.Models;
using AutoMapper;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web;
using System.Web.WebPages.Html;
namespace sport.webApi.Controllers
{
public class AccountManageController : ApiController
{
[HttpPost]
public System.Web.Mvc.ActionResult CreateAccount(CollaborateurModel item)
{
var user = new ApplicationUser { UserName = item.Username, Email = item.Email };
var result = UserManager.CreateAsync(user, item.Password);
if (result.Result.Succeeded)
{
var currentUser = UserManager.FindByName(item.Username);
var roleresult = UserManager.AddToRole(currentUser.Id, item.Role);
ajt_collaborator entity = Mapper.Map<CollaborateurModel, ajt_collaborator>(item);
entity.id_user_fk = currentUser.Id;
entity.is_deleted = false;
repo.CreateCollaborator(entity);
var response = new { Success = true };
return Json(response);
}
else
{
var errorResponse = new { Success = false, ErrorMessage = "error" };
return Json(errorResponse);
}
}
}
}
I got an error in this line :
return Json(response);
the Json Method is not recognized!!! when I googled about that I get this link which indicates that Json method is included in System.Web.Mvc. Even I try to import this namespace I get the same error?
So is the reason of this error?
How can I fix it?
The problem is that you are inheriting from ApiController but Json is a member of System.Web.Mvc.Controller.
Try using JsonResult:
return new JsonResult { data = yourData; }
You can set any object to a data as it will be serialized to a JSON.
For instance, if you need to return only a result of operation, you can use it this way:
return new JsonResult { data = true; } // or false
However, it is a good practice to describe a result class and return objects.
How can I fix it?
The reason is in the fact that you aren't inheriting from Controller but from ApiController, where the former has Json(object o) as a method in it's base class, but that doesn't actually matter, as there is a fundamental problem with your approach.
ApiController which is used with WebAPI isn't meant to return an ActionResult, which is a concept that belongs to MVC. Instead, you simply return your POCO and let the WebAPI framework handle serialization for you:
public object CreateAccount(CollaborateurModel item)
{
// Do stuff:
if (result.Result.Succeeded)
{
return new { Success = true }
}
else
{
return new { Success = false, ErrorMessage = "error" };
}
}
You can set your formatter configuration in your Global.asax.cs file, and tell it exactly which ones to use (in your case, you'll want the JsonMediaTypeFormatter).