How to convert a datatable to json ASP.NET - asp.net

I am trying to get data from database using ASP.NET CORE API the problem that I can't convert the datatable to JSON
I used this solution but i got the same problem.
This is what I get every time I test with Postman
"[{\"id_auxiliaire\":\"0000000008522450131\",\"identite_fiscal_cin\":\"0XDERTTOL45\",\"NOM_RAISON_SOCIALE\":\"HIGHTech\",\"CodePostale\":41225,\"Ville\":\"USA\"},}]"
This is my WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Configure Web API to return JSON
config.Formatters.JsonFormatter
.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
}
}
And this is my code
SqlDataAdapter da = new SqlDataAdapter($"select * from [UserDetail] WHERE CONVERT(date, dateOperation) BETWEEN '{dd}' AND '{df}' ", con);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
string res = JsonConvert.SerializeObject(dt, Formatting.None);
return new string[] { res };
}

Related

how to call to web api2 controller method from component http.post method in angular2

Component.ts
TableHeader(Id: any) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify(Id);
var sub = this.http.post('api/Customers/GetColumnNames/', body, options)
.map((res: Response) => res.json());
}
WebApiController
[AcceptVerbs("Post")]
[ActionName("GetColumnNames")]
public DataSet GetColumnNames(String id) {
DataSet ds = new DataSet();
if (Convert.ToInt32(id) > 0) {
//AccountingMethods objAcc = new AccountingMethods();
//return ds = objAcc.GetColumnsNames("GetColumns", id);
}
return new DataSet();
}
When calling webapi controller action name .i am not getting hit
We are going to need some extra information:
I am assuming that you have the following WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
I would also try to
[Route("api/Customers/GetColumnNames")]
[HttpPost]
If all else fails try changing the call to
var sub = this.http.post('api/Customers/GetColumnNames', body, options)
.map((res: Response) => res.json());
The trailing slash shouldn't affect the call but it's been mentioned in the past as a problem so it might be valuable to try.
What would greatly help is for you to add the error from the browser (in chrome it's F12 for the tools and Network to see the call.

No action was found on the controller 'Callback' that matches the request

I'm literally going crazy trying to fix this but nothing I do seems to make a difference. When I navigate to localhost:3978/api/callback it throws
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:3978/api/callback'.
</Message>
<MessageDetail>
No action was found on the controller 'Callback' that matches the request.
</MessageDetail>
</Error>
This is the controller in my Controllers/CallbackController.cs
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Autofac;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace VSTF_RD_Bot.Controllers
{
public class CallbackController : ApiController
{
[HttpGet]
[Route("api/Callback")]
public async Task<HttpResponseMessage> Callback([FromUri] string state, [FromUri] string code)
{
//parse out the userId and convoId from states parameter
string[] states = state.Split(new[] { "," }, StringSplitOptions.None);
string userId = states[0];
string conversationId = states[1];
// Check if the bot is running against emulator
var connectorType = HttpContext.Current.Request.IsLocal ? ConnectorType.Emulator : ConnectorType.Cloud;
// Exchange the Facebook Auth code with Access toekn
var token = await AdHelpers.ExchangeCodeForAccessToken(userId, conversationId, code, "redirect_uri");
// Create the message that is send to conversation to resume the login flow
var msg = new Message
{
Text = $"token:{token}",
From = new ChannelAccount { Id = userId },
To = new ChannelAccount { Id = Constants.botId },
ConversationId = conversationId
};
var reply = await Conversation.ResumeAsync(Constants.botId, userId, conversationId, msg, connectorType: connectorType);
// Remove the pending message because login flow is complete
IBotData dataBag = new JObjectBotData(reply);
PendingMessage pending;
if (dataBag.PerUserInConversationData.TryGetValue("pendingMessage", out pending))
{
dataBag.PerUserInConversationData.RemoveValue("pendingMessage");
var pendingMessage = pending.GetMessage();
reply.To = pendingMessage.From;
reply.From = pendingMessage.To;
// Send the login success asynchronously to user
var client = Conversation.ResumeContainer.Resolve<IConnectorClient>(TypedParameter.From(connectorType));
await client.Messages.SendMessageAsync(reply);
return Request.CreateResponse("You are now logged in! Continue talking to the bot.");
}
else
{
// Callback is called with no pending message as a result the login flow cannot be resumed.
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, new InvalidOperationException("Cannot resume!"));
}
}
}
}
What am I missing here?
This is my webApiconfig.cs
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace VSTF_RD_Bot
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Json settings
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Make your controller
[HttpGet]
[Route("api/Callback/{state}/{code}")]
public async Task<HttpResponseMessage> Callback(string state, string code)
{
and request url
"localhost:3978/api/Callback/samplestate/samplecode"

How to call a web api from url in mvc4

I have created a web api with two parameters. I want to test it from url that its working or not. I have tried but not able to call. My code is.
API routing...
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
[HttpGet]
public List<Library> GetLibrary(string DataType, int DataId)
{
List<Library> LibraryList = new List<Library>();
if (DataType == "Course")
{
using (ICA.LMS.Service.Models.Entities dbCourse = new Models.Entities())
{
LibraryList = (from c in dbCourse.COURSELIBRARies
where c.LIBITEMID == DataId
select new Library { Id = c.LIBITEMID, Name = c.GROUPNAME, Desc = c.DESCRIPTION }).ToList();
}
}
return LibraryList;
}
Url which i am putting in browser.
http://localhost:1900/api/librarybyid/?DataType='Course'&DataId=1
Result i am getting...
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:1900/api/librarybyid/?DataType='Course'&DataId=1'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'librarybyid'.
</MessageDetail>
</Error>

How to make Owin self host support Json output?

I am using Owin to build a self hosted server which support both file requests and web api. But the output for web api requests are always in xml format. How can I configure owin to output in json?
The code is as below:
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseFileServer(new FileServerOptions()
{
RequestPath = PathString.Empty,
FileSystem = new PhysicalFileSystem(#".\files")
});
// set the default page
app.UseWelcomePage(#"/index.html");
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute
(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
}
}
I have found the answer myself. All have to do is to add a json formatter as below:
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
config.Formatters.JsonFormatter.SerializerSettings =
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
If need to convert enum to string add StringEnumConverter to the settings.
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());

Internal server error in an ASP.NET Web API in-memory test

I get an "internal server error" (status code 500) when testing an ASP.NET Web API controller in an in-memory test.
[TestFixture]
public class ValuesControllerTest
{
private HttpResponseMessage response;
[TestFixtureSetUp]
public void Given()
{
var config = new HttpConfiguration
{
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { controller = typeof(ValuesController).Name.Replace("Controller", string.Empty), id = RouteParameter.Optional }
);
//This method will cause internal server error but NOT throw any exceptions
//Remove this call and the test will be green
ScanAssemblies();
var server = new HttpServer(config);
var client = new HttpClient(server);
response = client.GetAsync("http://something/api/values/5").Result;
//Here response has status code 500
}
private void ScanAssemblies()
{
PluginScanner.Scan(".\\", IsApiController);
}
private bool IsApiController(Type type)
{
return typeof (ApiController).IsAssignableFrom(type);
}
[Test]
public void Can_GET_api_values_5()
{
Assert.IsTrue(response.IsSuccessStatusCode);
}
}
public static class PluginScanner
{
public static IEnumerable<Type> Scan(string directoryToScan, Func<Type, bool> filter)
{
var result = new List<Type>();
var dir = new DirectoryInfo(directoryToScan);
if (!dir.Exists) return result;
foreach (var file in dir.EnumerateFiles("*.dll"))
{
result.AddRange(from type in Assembly.LoadFile(file.FullName).GetTypes()
where filter(type)
select type);
}
return result;
}
}
I have configured Visual Studio to break when any .Net exception is thrown. Code is not stopped at any exception nor can I find any exception details in the response.
What should I do to see what's causing the "internal server error"?
The exception is in Response.Content
if (Response != null && Response.IsSuccessStatusCode == false)
{
var result = Response.Content.ReadAsStringAsync().Result;
Console.Out.WriteLine("Http operation unsuccessful");
Console.Out.WriteLine(string.Format("Status: '{0}'", Response.StatusCode));
Console.Out.WriteLine(string.Format("Reason: '{0}'", Response.ReasonPhrase));
Console.Out.WriteLine(result);
}
You need to add a route so that it looks something like this:
var config = new HttpConfiguration()
{
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
config.Routes.MapHttpRoute(
name: "default",
routeTemplate: "api/{controller}/{id}",
defaults: new { controller = "Home", id = RouteParameter.Optional });
var server = new HttpServer(config);
var client = new HttpClient(server);
HttpResponseMessage response = client.GetAsync("http://somedomain/api/product").Result;
Btw, in the latest bits you get a 404 Not Found as you would expect.
Henrik
It sounds like you might have already found your answer, but that wasn't quite it for me so I want to add this for others with my issue.
To start out, it seems to be an issue with the new MVC 4 formatters. Setting any of the error policy flags will not work (IncludeErrorDetailPolicy, CustomErrors, etc), these formatters are ignoring them and just returning and empty "internal server error" 500.
I found this out by eventually overloading the formatters and checking their responses for errors:
public class XmlMediaTypeFormatterWrapper : XmlMediaTypeFormatter
{
public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext)
{
var ret = base.WriteToStreamAsync(type, value, stream, contentHeaders, transportContext);
if (null != ret.Exception)
// This means there was an error and ret.Exception has all the error message data you would expect, but once you return below, all you get is a blank 500 error...
return ret;
}
}
For now I am using Xml and Json formatter wrappers that simply look for ret.Exception and capture it so I at least have the data if a 500 happens. I couldn't really find an elegant way to make the error actually show up in the html response since Task.Exception is already set and this SHOULD be all the is required to pass the exception along.

Resources