Share Json data between Asp.Net MVC 2 and Asp.Net server side C# code? - json

I created and love my Asp.Net MVC2 application. It's a very nice DDD app with Domain Model classes, View Model classes, a repository, and Json action methods to expose data.
My coworker wants to share my data with his Asp.Net Forms based C# code. He wants to pull through the Internet a class definition (like a Data Contract), then fill it with my Json results, effectively using something like a remote repository.
Any links or ideas on how to provide him with data contracts and data?
Darin Dimitrov had an excellent idea of consuming JSON data using data contracts here. Just wondering if it's possible to use MVC as the source for these items, then let him create the objects on his side, filled with data from my side.
The key to this question is how to send him my data classes, then send him my data.
class Program
{
[DataContract]
class Person
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "surname")]
public string Surname { get; set; }
[DataMember(Name="age")]
public int Age { get; set; }
}
static void Main(string[] args)
{
var json = #"{""name"" : ""michael"", ""surname"" : ""brown"", ""age"" : ""35""}";
var serializer = new DataContractJsonSerializer(typeof(Person));
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var person = (Person)serializer.ReadObject(stream);
Console.WriteLine("Name : {0}, Surname : {1}, Age : {2}",
person.Name, person.Surname, person.Age);
}
}
}

Write an OData service. The format is JSON, but the tools to consume it easily -- from many languages -- are already written for you.
The nice thing about this is that your data is now not only consumable by your JS and your friend's ASP.NET app, it's consumable by Excel, PHP, etc.

Related

Returning a Json-field from SQL to ASP.NET Core API

I'm building a relatively simple Get-method in an ASP.NET Core (3+) application. (Currently 3.1 - to be migrated to 5)
The object I need to return looks like this:
public class Data
{
public int ID { get;set;}
public string Name { get;set;}
public string Settings { get; set;}
}
And the Get-method is simply this:
public IActionResult<Data> GetData()
{
var data = _dbContext.GetData<Data>();
return Ok(data);
}
This works perfectly - except for one thing.
In SQL - the settings column (varchar(8000)), contains JSON data. In some cases, a setting can be something simple like : { "threshold": 8754 } and sometimes it can be a large complex object with many fields, but it is always valid Json.
On the ASP side, it does exactly what you would expect. It turns a serialized Json object that contains an INT and 2 x strings.
I would like for it to return an INT, ONE String and One Json Object.
Is there any way that I can tell the serializer that the Settings-property contains Json?
In a perfect world, I would love something like this:
public class Data
{
public int ID { get;set;}
public string Name { get;set;}
[SerializeContentAsJson]
public string Settings { get; set;}
}
Is there a way to do this or is there some other fairly elegant solution to this problem?
Btw. I fully realize that the caller can specify the content types that he/she will accept. In this case, the API is purely for use inside my team and we will always want JSON, so I can compromise on this being a relatively custom solution that might not work if you wanted text/html or some other content type.

Web API POST, get both, object and JSON plain text

Visual Studio 2019 / Net Framework 4.7.2
I'm working on a new project that uses a Rest API to receive orders from a customer using POST method.
As example, this could be the Order object:
public class Order
{
public string Id { get; set; } = "";
public string Data { get; set; } = "";
}
And that the Post method of my API controller:
public HttpResponseMessage Post([FromBody] Order value)
{
if (OrderProcessed(value))
return Request.CreateResponse(HttpStatusCode.Created);
else
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Order cannot be processed.");
}
It works fine, deserialized JSON object is mapped to Order's properties.
But, in addition, I'd like to store in my DB the JSON string received within the POST command.
This question: ASP .NET Web API - Get plain JSON in POST method shows how to get the JSON text, but:
Is there a way to get both, Order's object and the body's text?

Anonymous object blob in database not serializing as JSON when queried

I have a need to store an unknown data structure in a SQL Server database table field via ORMLite. This is to support a timeline feature on a website where each step on the timeline contains different information, and I want to store them as generic "Steps", with the variable data in a "StepData" property. I have the POCO set up like this:
public class ItemStep
{
public ItemStep()
{
this.Complete = false;
}
[Alias("ItemStepId")]
public Guid Id { get; set; }
[References(typeof(Item))]
public Guid ItemId { get; set; }
[References(typeof(Step))]
public int StepId { get; set; }
public object StepData { get; set; }
[Reference]
public Step Step { get; set; }
public bool Complete { get; set; }
public DateTime? CompletedOn { get; set; }
}
My front-end send a JSON object for StepData, and it's saved to the database appropriately.
{itemAmount:1000,isRed:False,isBlue:True,conversion:True}
Now, when I go to retrieve that data using...
List<ItemStep> itemSteps = Db.Select<ItemStep>(q => q.ItemId == request.ItemId).OrderByDescending(q => q.StepId).ToList<ItemStep>();
...the "StepData" node of the JSON response on the client is not a Javascript Array object as I'm expecting. So, on the client (AngularJS app using Coffeescript),
ItemStep.getItemSteps(ItemId).then((response) ->
$scope.StepData = response.data.itemSteps[0].stepData
is a double-quoted string of the JSON array.
"{itemAmount:1000,isRed:False,isBlue:True,conversion:True}"
Can anybody help me with this? I've tried parsing that string as JSON and I can't seem to get it to work:
JSON.parse($scope.StepData)
I'm using the exact same methodology in other areas of the app to store and retrieve things like addresses, with the only difference I can see being that there is a specified Address class.
Thanks!
Found this link that solved my problem: https://github.com/ServiceStackV3/mythz_blog/blob/master/pages/314.md
Essentially I added a "Type" field to the ItemStep class, and set that when I create a new row (create the next step in the timeline). Then, when I retrieve that record, I call a method like "GetBody" in the referenced link (GetStepData for me), that deserializes the object using the stored Type. I then stuff that back into a generic "object" type in the return POCO so that I can include many steps of varying types in the same call. Works great!
Thanks Mythz for the blog post!

Want to design a REST API but I have too much parameter to send , is it okay to replace them with one JSON?

I am designing a REST API one of my resources is all about to getting some basic data from user side.
Here are two points that I needs to mention:
all the user's information needs to send to server side with only one http request
the user's information is about 30 different fields.
So I think having a long list of argument in server side can not be that much good and I want to replace this part with a single argument which is accepting a JSON.
Do you think is it correct to do that?
Yes. You will want to change the method to a POST instead of a GET and in the request body send the JSON formatted data.
Example using C# syntax:
Assume you have a method that returns an object called ObjectList and in order to generate the list you the constructor requires an ObjectListRequest object -
public ObjectList GetObjectList(ObjectListRequest request)
{
return new ObjectList(request)
}
Your ObjectListRequest class could contain various different parameters that the request would use -
public class ObjectListRequest
{
public string SearchText { get; set; }
public string CreatedBy { get; set; }
public int SequenceStartRange { get; set; }
public int SequenceEndRange { get; set; }
public bool HasMetaData { get; set; }
}
Now to call this method using a POST with JSON in the body you would send the following
Method: POST
Url: http://your.service.com/GetObjectList
Headers:
Content-Type: application/json
Body:
{
"request":{
"SearchText":"test text",
"CreatedBy":"myusername",
"SequenceStartRange":0,
"SequenceEndRange":15,
"HasMetaData":"true"
}
}
This is a specific example which assumes you are using C# and built in Serialization libraries from microsoft, but if not, you can still use the same basic idea to do what you are trying to do.

How do I populate a Data Access Layer Model Efficiently?

I'm working on developing my first Data Driven Domain using Dependency Injection in ASP.net.
In my Data Access Layer if have created some domain data models, for example:
public class Company {
public Guid CompanyId { get; set; }
public string Name { get; set; }
}
public class Employee {
public Guid EmployeeId { get; set; }
public Guid CompanyId { get; set; }
public string Name { get; set; }
}
I have then developed an interface such as:
public interface ICompanyService {
IEnumerable<Model.Company> GetCompanies();
IEnumerable<Model.Employee> GetEmployees();
IEnumerable<Model.Employee> GetEmployees(Guid companyId);
}
In a separate module I have implemented this interface using Linq to Sql:
public class CompanyService : ICompanyService {
public IEnumerable<Model.Employee> GetEmployees();
{
return EmployeeDb
.OrderBy(e => e.Name)
.Select(e => e.ToDomainEntity())
.AsEnumerable();
}
}
Where ToDomainEntity() is implemented in the employee repository class as an extension method to the base entity class:
public Model.EmployeeToDomainEntity()
{
return new Model.Employee {
EmployeeId = this.EmployeeId,
CompanyId = this.CompanyId,
Name = this.Name
};
}
To this point, I have more or less followed the patterns as described in Mark Seeman's excellent book 'Dependency Injection in .NET' - and all works nicely.
I would like however to extend my basic models to also include key reference models, so the domain Employee class would become:
public class Employee {
public Guid EmployeeId { get; set; }
public Guid CompanyId { get; set; }
public Company { get; set; }
public string Name { get; set; }
}
and the ToDomainEntity() function would be extended to:
public Model.Employee ToDomainEntity()
{
return new Model.Employee {
EmployeeId = this.EmployeeId,
CompanyId = this.CompanyId,
Company = (this.Company == null) ? null : this.Company.ToDomainEntity()
Name = this.Name
};
}
I suspect that this might be 'bad practice' from a domain modelling point of view, but the problem I have encountered would also, I think, hold true if I were to develop a specific View Model to achieve the same purpose.
In essence, the problem I have run into is the speed/efficiency of populating the data models. If I use the ToDomainEntity() approach described above, Linq to Sql creates a separate SQL call to retrieve the data for each Employee's Company record. This, as you would expect, increases the time taken to evaluate the SQL expression quite considerably (from around 100ms to 7 seconds on our test database), particularly if the data tree is complex (as separate SQL calls are made to populate each node/sub-node of the tree).
If I create the data model 'inline...
public IEnumerable<Model.Employee> GetEmployees();
{
return EmployeeDb
.OrderBy(e => e.Name)
.Select(e => new Model.Employee {
EmployeeId = e.EmployeeId,
/* Other field mappings */
Company = new Model.Company {
CompanyId = e.Company.CompanyId,
/* Other field mappings */
}
}).AsEnumerable();
}
Linq to SQL produces a nice, tight SQL statement that natively uses the 'inner join' method to associate the Company with the Employee.
I have two questions:
1) Is it considered 'bad practice' to reference associated data classes from within a domain class object?
2) If this is the case, and a specific View Model is created for the purpose, what is the right way of populating the model using without having to resort to creating inline assignment blocks to build the expression tree?
Any help/advice would be much appreciated.
The problem is caused by having both data layer entities and domain layer entities and needing a mapping between the two. Although you can get this to work, this makes everything very complex, as you are already experiencing. You are making mappings between data and domain, and will soon add many more mappings for these same entities, because of performance reasons and because other business logic and presentation logic will need different data.
The only real solution is to ditch your data entities and create POCO model objects that can directly be serialized to your backend store (SQL server).
POCO entities is something that is supported in LINQ to SQL from day one, but I think it would be better to migrate to Entity Framework Code First.
When doing this, you can expose IQueryable<T> interfaces from your repositories (you currently called your repository ICompanyService, but a better name would be ICompanyRepository). This allows you to do efficient LINQ queries. When querying directly over a query provider you can prevent loading complete entities. For instance:
from employee in this.repository.GetEmployees()
where employee.Company.Name.StartWith(searchString)
select new
{
employee.Name,
employee.Company.Location
};
When working with IQueryable<T>, LINQ to SQL and Entity Framework will translate this to a very efficient SQL query that only returns the employe name and company location from the database with filtering inside the database (compared to do filtering in your .NET application when GetEmployees() returns an IEnumerable<T>).
You can ask Linq2Sql to preload certain entities (as opposed to lazy load them) using DataLoadOptions.LoadWith method see: http://msdn.microsoft.com/en-us/library/bb534268.aspx.
If you do this with the Company entity then I think Linq2Sql won't have to reach to the database to fetch it again.