There is a note in the developer road map from December of 2013 saying, "Lock/Unlock – We’ve added support for locking and unlocking files into the V2 API."
I've been all through the V2 API (for c#) and cannot find it anywhere. I expected to find something in the BoxFilesManager class or as something you would pass to UpdateInformationAsync within the BoxFileRequest class.
So is there a way to lock/unlock a file?
Great question. In order to see the current lock status of a file do a
GET https://api.box.com/2.0/files/7435988481/?fields=lock
If there is no lock on the file, you'll get something like this back:
{
"type": "file",
"id": "7435988481",
"etag": "0",
"lock": null
}
If you want to lock a file, you need to do a PUT (update) on the /files/ endpoint with a body that tells us what type of lock, and when to release it. Like this:
PUT https://api.box.com/2.0/files/7435988481/?fields=lock
{"lock": {
"expires_at" : "2014-05-29T19:03:04-07:00",
"is_download_prevented": true
}
}
You'll get a response confirming your lock was created:
{
"type": "file",
"id": "7435988481",
"etag": "1",
"lock": {
"type": "lock",
"id": "14516545",
"created_by": {
"type": "user",
"id": "13130406",
"name": "Peter Rexer gmail",
"login": "prexer#gmail.com"
},
"created_at": "2014-05-29T18:03:04-07:00",
"expires_at": "2014-05-29T19:03:04-07:00",
"is_download_prevented": true
}
}
Since there isn't a lock/unlock yet, I created a Lock Manager based on the existing managers:
class BoxCloudLockManager : BoxResourceManager
{
#region Lock/Unlock Classes
[DataContract]
internal class BoxLockRequestInfo
{
[DataMember(Name = "status")]
public string Status { get; set; }
//[DataMember(Name = "expires_at")]
//public string ExpiresAt { get; set; }
[DataMember(Name = "is_download_prevented")]
public bool IsDownloadPrevented { get; set; }
}
[DataContract]
internal class BoxLockRequest
{
[DataMember(Name = "lock")]
public BoxLockRequestInfo Lock { get; set; }
}
#endregion
const string LockFileString = "{0}/?fields=lock";
public BoxCloudLockManager(IBoxConfig config, IBoxService service, IBoxConverter converter, IAuthRepository auth)
: base(config, service, converter, auth)
{
}
public async Task<BoxLockInfo> LockAsync(string documentId,bool isDownloadPrevented = true)
{
var lockRequest = new BoxLockRequest { Lock = new BoxLockRequestInfo { Status = "lock", IsDownloadPrevented = isDownloadPrevented } };
BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(LockFileString, documentId))
.Method(RequestMethod.Put)
.Payload(_converter.Serialize(lockRequest));
IBoxResponse<BoxLockInfo> response = await ToResponseAsync<BoxLockInfo>(request).ConfigureAwait(false);
return response.ResponseObject;
}
public async Task<BoxLockInfo> UnlockAsync(string documentId)
{
BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(LockFileString, documentId))
.Method(RequestMethod.Put)
.Payload("{\"lock\":null}");
IBoxResponse<BoxLockInfo> response = await ToResponseAsync<BoxLockInfo>(request).ConfigureAwait(false);
return response.ResponseObject;
}
public async Task<BoxLockInfo> GetLockInfoAsync(string documentId)
{
BoxRequest request = new BoxRequest(_config.FilesEndpointUri, string.Format(LockFileString, documentId))
.Method(RequestMethod.Get);
IBoxResponse<BoxLockInfo> response = await ToResponseAsync<BoxLockInfo>(request).ConfigureAwait(false);
return response.ResponseObject;
}
}
I derived a class from BoxClient, adding a LockManager and instantiate it within the Constructor.
Here is the Lock Info:
[DataContract]
public class BoxLockedBy
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "login")]
public string Login { get; set; }
}
[DataContract]
public class BoxLockDetails
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "created_by")]
public BoxLockedBy CreatedBy { get; set; }
[DataMember(Name = "created_at")]
public string CreatedAt { get; set; }
[DataMember(Name = "expires_at")]
public string ExpiresAt { get; set; }
[DataMember(Name = "is_download_prevented")]
public bool IsDownloadPrevented { get; set; }
}
[DataContract]
public class BoxLockInfo
{
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "etag")]
public string Etag { get; set; }
[DataMember(Name = "lock")]
public BoxLockDetails LockDetails { get; set; }
}
Related
I am developing an endpoint in C# to accept JSON posted from an external provider (Telnyx). Here is a sample of the data:
{
"data": {
"event_type": "fax.received",
"id": "e15c28d4-147e-420b-a638-2a2647315577",
"occurred_at": "2021-11-19T16:37:02.863682Z",
"payload": {
"call_duration_secs": 35,
"connection_id": "1771912871052051547",
"direction": "inbound",
"fax_id": "2a168c93-3db5-424b-a408-b70a3da625bc",
"from": "+12399999999",
"media_url": "https://s3.amazonaws.com/faxes-prod/999",
"page_count": 1,
"partial_content": false,
"status": "received",
"to": "+12399999999",
"user_id": "dc6e79fa-fe3b-462b-b3a7-5fb7b3111b8a"
},
"record_type": "event"
},
"meta": {
"attempt": 1,
"delivered_to": "https://webhook.site/27ef892c-c371-4976-ae22-22deea57080e"
}
}
I have verified this is valid JSON through https://jsonlint.com/. I created a model:
public class myDeserializedClass
{
public class Payload
{
public int call_duration_secs { get; set; }
public string connection_id { get; set; }
public string direction { get; set; }
public string fax_id { get; set; }
public string from { get; set; }
public string media_url { get; set; }
public int page_count { get; set; }
public bool? partial_content { get; set; }
public string status { get; set; }
public string to { get; set; }
public string user_id { get; set; }
}
public class Data
{
public string event_type { get; set; }
public string id { get; set; }
public DateTime occurred_at { get; set; }
public Payload payload { get; set; }
public string record_type { get; set; }
}
public class Meta
{
public int attempt { get; set; }
public string delivered_to { get; set; }
}
public class Root
{
public Data data { get; set; }
public Meta meta { get; set; }
}
}
The controller being posted to looks like:
[HttpPost]
public IActionResult InboundFax(myDeserializedClass json)
{
try
{
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(json.ToString().Trim());
return Content("OK");
}
catch(Exception ex)
{
return Content(ex.ToString());
}
}
I am receiving the error: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: K. Path '', line 0, position 0. each time the API tries to post to my endpoint. I have also tried posting data using Postman and receive the same error message. Additionally, there are examples of JSON posting on the API website at https://developers.telnyx.com/docs/v2/programmable-fax/tutorials/receive-a-fax-via-api. Since my application fails with both postman and real-time API calls, I'm am working on the assumption the problem is my code, but can't be 100% certain and don't know how to fix it. This is a mission critical problem that I need to solve. Any help would be appreciated.
First of all, the class is bad. Should be:
public class Payload
{
public int call_duration_secs { get; set; }
public string connection_id { get; set; }
public string direction { get; set; }
public string fax_id { get; set; }
public string from { get; set; }
public string media_url { get; set; }
public int page_count { get; set; }
public bool? partial_content { get; set; }
public string status { get; set; }
public string to { get; set; }
public string user_id { get; set; }
}
public class Data
{
public string event_type { get; set; }
public string id { get; set; }
public DateTime occurred_at { get; set; }
public Payload payload { get; set; }
public string record_type { get; set; }
}
public class Meta
{
public int attempt { get; set; }
public string delivered_to { get; set; }
}
public class myDeserializedClass
{
public Data data { get; set; }
public Meta meta { get; set; }
}
It depends on the data that you are getting, but if you are getting the object, you don't need to convert it to work:
[HttpPost]
public IActionResult InboundFax(myDeserializedClass json)
{
try
{
//Work directly with json as object, forget "root" is: myDeserializedClass
return Content("OK");
}
catch(Exception ex)
{
return Content(ex.ToString());
}
}
or if you are getting the json as string:
[HttpPost]
public IActionResult InboundFax(string json)
{
try
{
//Work directly with json as object
myDeserializedClass myInstance= JsonConvert.DeserializeObject<myDeserializedClass>(json);
return Content("OK");
}
catch(Exception ex)
{
return Content(ex.ToString());
}
}
UPDATE AFTER TESTING IT:
I test it with a dummy controller:
[HttpPost]
public ActionResult InboundFax(myDeserializedClass json)
{
try
{
//Just dummy test
if (json.meta.attempt == 1)
{
return Content("OK");
}
else {
return Content("NO");
}
//Work directly with json as object, forget "root" is: myDeserializedClass
}
catch (Exception ex)
{
return Content(ex.ToString());
}
}
in a HomeController (blank template from MVC Web just dummy)
So posting to:
https://localhost:44334/Home/InboundFax
METHOD: POST
With the following data:
{
"data": {
"event_type": "fax.received",
"id": "e15c28d4-147e-420b-a638-2a2647315577",
"occurred_at": "2021-11-19T16:37:02.863682Z",
"payload": {
"call_duration_secs": 35,
"connection_id": "1771912871052051547",
"direction": "inbound",
"fax_id": "2a168c93-3db5-424b-a408-b70a3da625bc",
"from": "+12399999999",
"media_url": "https://s3.amazonaws.com/faxes-prod/999",
"page_count": 1,
"partial_content": false,
"status": "received",
"to": "+12399999999",
"user_id": "dc6e79fa-fe3b-462b-b3a7-5fb7b3111b8a"
},
"record_type": "event"
},
"meta": {
"attempt": 1,
"delivered_to": "https://webhook.site/27ef892c-c371-4976-ae22-22deea57080e"
}
}
Little quickwatch you see it map everything:
Could mean the POSTMAN is wrong configurated?
I use the following header:
Content-Type: application/json
I'm using TALEND API TESTER for Chrome, but every REST client is similar
With POSTMAN, same result, OK. Check for body: raw, type JSON, and header with the content type applicantion/json
Well, I am not sure if I have an answer or not, however, I did manage to get the application working by changing the endpoint to a WebApi instead of a MVC controller. I was under the impression a MVC controller could accept json data, however, I was unable to ever get it working. Once I changed it, everyting worked perfectly.
I am calling the API and trying to store the Jsonresult into a IEnumerable model class. The json result has group header column consolidated_weather.
when I run the program the following error is coming
JsonSerializationException: Cannot deserialize the current JSON object into type 'System.Collections.Generic.IEnumerable`.
How can I call the given json result into the IEnumerable model class after avoiding group header from json result.
I am using the following two model.
public class Weather
{
[Key]
public long id { get; set; }
public string weather_state_name { get; set; }
public string weather_state_abbr { get; set; }
public string wind_direction_compass { get; set; }
public DateTime created { get; set; }
public DateTime applicable_date { get; set; }
public decimal min_temp { get; set; }
public decimal max_temp { get; set; }
public decimal the_temp { get; set; }
public double wind_speed { get; set; }
public decimal wind_direction { get; set; }
public decimal air_pressure { get; set; }
public decimal Humidity { get; set; }
public string Visibllity { get; set; }
public decimal Predictability { get; set; }
}
public class WeatherList
{
public IEnumerable<Weather> consolidated_weather { get; set; }
}
public async Task<IEnumerable<Weather>> GetWeatherAsync(string woied)
{
var url = SD.APIBaseUrl + woied;
var request = new HttpRequestMessage(HttpMethod.Get, url);
var client = _clientFactory.CreateClient();
HttpResponseMessage response = await client.SendAsync(request);
IEnumerable<Weather> weather = new List<Weather>();
WeatherList weatherList = new WeatherList();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var jsonString = await response.Content.ReadAsStringAsync();
weatherList = JsonConvert.DeserializeObject<WeatherList>(jsonString);
return weatherList;
}
return null;
}
The API result is coming as
<!-- language: lang-html -->
{
"consolidated_weather": [
{
"id": 4577625064341504,
"weather_state_name": "Heavy Rain",
"weather_state_abbr": "hr",
"wind_direction_compass": "WSW",
"created": "2020-07-14T19:35:14.577740Z",
"applicable_date": "2020-07-14",
"min_temp": 11.11,
"max_temp": 15.05,
"the_temp": 14.32,
"wind_speed": 6.570953330777592,
"wind_direction": 254.13274105640758,
"air_pressure": 1016.5,
"humidity": 85,
"visibility": 7.654361031575599,
"predictability": 77
},
{
"id": 4896540210495488,
"weather_state_name": "Showers",
"weather_state_abbr": "s",
"wind_direction_compass": "WNW",
"created": "2020-07-14T19:35:17.569534Z",
"applicable_date": "2020-07-15",
"min_temp": 12.31,
"max_temp": 17.03,
"the_temp": 16.509999999999998,
"wind_speed": 7.600821124862802,
"wind_direction": 284.49357944800784,
"air_pressure": 1015.5,
"humidity": 82,
"visibility": 13.558008729022509,
"predictability": 73
},
]
"title": "Texas",
"location_type": "City",
"timezone": "US"
<!-- end snippet -->
From your json string, we can see that there is a list of weather object in object consolidated_weather.
So you need to parse json to WeatherList.
public class WeatherList {
public IEnumerable<Weather> consolidated_weather { get; set; }
}
[HttpPost("/weather")]
public async Task<IEnumerable<Weather>> GetWeatherAsync()
{
string jsonString = "{\"consolidated_weather\":[{\"id\":4577625064341504,\"weather_state_name\":\"Heavy Rain\",\"weather_state_abbr\":\"hr\",\"wind_direction_compass\":\"WSW\",\"created\":\"2020-07-14T19:35:14.577740Z\",\"applicable_date\":\"2020-07-14\",\"min_temp\":11.11,\"max_temp\":15.05,\"the_temp\":14.32,\"wind_speed\":6.570953330777592,\"wind_direction\":254.13274105640758,\"air_pressure\":1016.5,\"humidity\":85,\"visibility\":7.654361031575599,\"predictability\":77},{\"id\":4896540210495488,\"weather_state_name\":\"Showers\",\"weather_state_abbr\":\"s\",\"wind_direction_compass\":\"WNW\",\"created\":\"2020-07-14T19:35:17.569534Z\",\"applicable_date\":\"2020-07-15\",\"min_temp\":12.31,\"max_temp\":17.03,\"the_temp\":16.509999999999998,\"wind_speed\":7.600821124862802,\"wind_direction\":284.49357944800784,\"air_pressure\":1015.5,\"humidity\":82,\"visibility\":13.558008729022509,\"predictability\":73}]}";
IEnumerable<Weather> weather = new List<Weather>();
WeatherList weatherList = new WeatherList();
weatherList = JsonConvert.DeserializeObject<WeatherList>(jsonString);
return weatherList.consolidated_weather;
}
Test Result
UPDATE
public class WeatherList
{
public IEnumerable<Weather> consolidated_weather { get; set; }
public string title { get; set; }
public string location_type { get; set; }
public string timezone { get; set; }
}
There are two missings in your json string:
<!-- language: lang-html -->
{
"consolidated_weather": [
{
"id": 4577625064341504,
...
},
{
"id": 4896540210495488,
...
},
] <!-- missing , -->
"title": "Texas",
"location_type": "City",
"timezone": "US"
<!-- missing } -->
<!-- end snippet -->
Assuming that you cannot change the content of the Json, you can create a ConsolidatedWeather class that contains the List of Weathers
public class ConsolidatedWeather
{
public List<Weather> Consolidated_Weather { get; set; }
}
and in your deserialize part
return JsonConvert.DeserializeObject<ConsolidatedWeather>(jsonString).Consolidated_Weather;
I am currently learning how to work with EF Core with a simple one to many setup, where a user can have many items. In terms of retrieving the data from the tables, this is fine with some DTO models; however, when I try and add a user with multiple items via Postman, I noticed that for each item it had duplicated the user that many times (i.e. a user with 3 items will create 3 items and 3 users):
Postman (POST)
{
"username": "xxx",
"dob": "xxx",
"location": "xxx",
"items":[{
"item": "xxx",
"category": "xxx",
"type": "xxx"
},
{
"item": "xxx",
"category": "xxx",
"type": "xxx"
},
{
"item": "xxx",
"category": "xxx",
"type": "xxx"
}]
}
Context:
namespace TestWebApplication.Database
{
public class MyContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Items> Items { get; set; }
public MyContext(DbContextOptions<MyContext> options)
: base(options)
{
// erm, nothing here
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(i => i.Items)
.WithOne(u => u.User);
}
public override int SaveChanges()
{
var entities = from e in ChangeTracker.Entries()
where e.State == EntityState.Added
|| e.State == EntityState.Modified
select e.Entity;
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(entity, validationContext);
}
return base.SaveChanges();
}
}
}
Controller:
[HttpPost]
[Route("insertuseranditems")]
public ActionResult InsertUserAndItems(User user)
{
if (ModelState.IsValid)
{
using (MyContext myContext = _myContext as MyContext)
{
myContext?.Users?.Add(user);
int changes = myContext.SaveChanges();
if (changes > 0)
{
return Created("User saved", user);
}
}
}
return Accepted();
}
Items:
namespace TestWebApplication.Database
{
public class Items
{
[Key]
public int ItemId { get; set; }
public string Item { get; set; }
public string Category { get; set; }
public string Type { get; set; }
public virtual User User { get; set; }
}
}
Users:
namespace TestWebApplication.Database
{
public class User
{
[Key]
public int UserId { get; set; }
public string UserName { get; set; }
public string Dob { get; set; }
public string Location { get; set; }
public ICollection<Items> Items { get; set; }
}
}
I revisited my code and changed my Items.cs model to:
namespace TestWebApplication.Database
{
public class Items
{
[Key]
public int ItemId { get; set; }
public string Item { get; set; }
public string Category { get; set; }
public string Type { get; set; }
[ForeignKey("User")] // added this
public int? UserId { get; set; } // added this
public virtual User User { get; set; }
}
}
Now, when I send the above json via Postman, I get multiple items with the same user as a Foreign Key.
The site below seemed to help:
The ForeignKey Attribute
I dont have any problems but i don't know how API call data Nested Values
My Web API have Controller, Models and DataAccess that i call by use sql to call data
I want API call JSON Data format similar as below :
[
{
"Agent_Code": "123456",
"Name": "Miss Sara Manger",
"NickName": "Sara",
"BirthDay": "19690825",
"CardID": "9999999999",
"Address": "870 Goldleaf Lane Lyndhurst NJ New Jersey 07071",
"Mobile": "000000000",
"Email": "utv9hgn3h0k#classesmail.com",
"Bank": [
{
"AcctName": "Miss Sara Manger",
"Acctno": "9999999999",
"Bank": "KBANK"
}
]
}
]
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace Testdata.APIs
{
public class DashController : BaseApiController
{
[HttpPost]
public List<Models.AgentDto> TestJSON(Models.CountDashReq model)
{
DataAccess.DashDAL dal = new DataAccess.DashDAL();
List<Models.AgentDto> models = dal.TestJSON(model);
return models;
}
}
Model AgentDto And BankDto:
public class AgentDto
{
public string Agent_Code { get; set; }
public string Name { get; set; }
public string NickName { get; set; }
public string BirthDay { get; set; }
public string CardID { get; set; }
public string Address { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public string Bank { get; set; }
}
public class BankDto
{
public string AcctName { get; set; }
public string Acctno { get; set; }
public string Bank { get; set; }
}
DataAccess:
public List<Models.AgentDto> TestJSON(Models.CountDashReq model)
{
string sql = "[dbo].[tb_Json_Get]";
List<Models.AgentDto> result = new List<Models.AgentDto>();
if (model != null)
{
List<SqlParameter> reqParam = new List<SqlParameter>();
//reqParam.Add(new SqlParameter("#usrLogin", model.usrLogin));
DataSet ds = this.Execute(sql, CommandType.StoredProcedure, reqParam.ToArray(), false);
if (ds.Tables.Count > 0)
{
foreach (DataRow row in ds.Tables[0].Rows)
{
Models.AgentDto paramslist = DataAccessUtility.DataTableExtensions.AsEnumerable<Models.AgentDto>(row);
result.Add(paramslist);
}
}
}
return result;
}
Please help me to use Case-when Thank you very much
If you getting request JSON as:
[
{
"Agent_Code": "123456",
"Name": "Miss Sara Manger",
"NickName": "Sara",
"BirthDay": "19690825",
"CardID": "9999999999",
"Address": "870 Goldleaf Lane Lyndhurst NJ New Jersey 07071",
"Mobile": "000000000",
"Email": "utv9hgn3h0k#classesmail.com",
"Bank": [
{
"AcctName": "Miss Sara Manger",
"Acctno": "9999999999",
"Bank": "KBANK"
}
]
}
]
Then the CountDashReq class should be:
public class Bank
{
public string AcctName { get; set; }
public string Acctno { get; set; }
public string Bank { get; set; }
}
public class CountDashReq
{
public string Agent_Code { get; set; }
public string Name { get; set; }
public string NickName { get; set; }
public string BirthDay { get; set; }
public string CardID { get; set; }
public string Address { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public List<Bank> Bank { get; set; }
}
In controller method:
[HttpPost]
public List<Models.AgentDto> TestJSON(IList<Models.CountDashReq> model)
{
// Your code
}
I am trying to update a variable inside a class "Conversation" put the parameter objects are not binding for some reason. I don't know why not. As a result I am getting this error:
"Object reference not set to an instance of an object.",
Controller:
[HttpPut]
public async Task<IHttpActionResult> AddMember(string key, User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Conversation conver = await db.Conversations.FindAsync(key); //THIS IS NULL
if (conver == null)
{
return NotFound(); //METHOD IS ENDING HERE
}
conver.Members.Add(user); //THIS IS NULL
db.Entry(conver).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
return NotFound();
}
return StatusCode(HttpStatusCode.NoContent);
}
Model class User:
namespace AcademicAssistant.Models
{
[DataContract]
public class User
{
[Key]
[DataMember]
public string Email { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public bool Admin { get; set; }
}
}
Model Class Conversation:
[DataContract]
public class Conversation
{
[Key]
[DataMember]
public string Key { get; set; }
[DataMember]
public string ConversationName { get; set; }
[DataMember]
public string Administrator { get; set; }
[DataMember]
public virtual ICollection<User> Members { get; set; }
[DataMember]
public virtual ICollection<Message> Messages { get; set; }
}
I am testing this in Postman like this:
ROUTE = api/Conversations/AddMember/?key="1LM4"
JSON = {"user": { "Email": "56#56.com", "Password" : "Passw-1", "Admin" : true } }
SOLUTION:
The Route should have been
api/Conversations/AddMember/?key=1LM4
and the JSON formatted like this:
{
"Email": "56#56.com",
"Password" : "Passw-1",
"Admin" : true
}