AspNet Categorize the messages by UserName when asking for Query - asp.net-mvc

My database is structured as below
public partial class AspNetUserMessage
{
public string From { get; set; }
public string To { get; set; }
public string Text { get; set; }
public System.DateTime SentDate { get; set; }
public Nullable<System.DateTime> ReadDate { get; set; }
public int Id { get; set; }
}
I have an API point which returns all the messages sent by a user e.g
[
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "i love this backend!!",
"SentDate": "2020-04-10T00:00:00",
"ReadDate": "2020-04-10T00:00:00",
"Id": 1
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "this is a sample msg",
"SentDate": "0001-01-01T00:00:00",
"ReadDate": null,
"Id": 2
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "id test",
"SentDate": "0001-01-01T00:00:00",
"ReadDate": null,
"Id": 3
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "blocked test",
"SentDate": "0001-01-01T00:00:00",
"ReadDate": null,
"Id": 4
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "blocked other way test",
"SentDate": "0001-01-01T00:00:00",
"ReadDate": null,
"Id": 5
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "date test",
"SentDate": "2020-04-11T00:00:00",
"ReadDate": null,
"Id": 6
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "date test",
"SentDate": "2020-04-11T00:00:00",
"ReadDate": null,
"Id": 7
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "id test",
"SentDate": "0001-01-01T00:00:00",
"ReadDate": null,
"Id": 8
},
{
"From": "0617c281-5488-4009-bf37-761f6cfea2df",
"To": "f54b7bf4-c7b5-482c-83b8-5b61e78ea398",
"Text": "id test",
"SentDate": "0001-01-01T00:00:00",
"ReadDate": null,
"Id": 9
}
]
My code is the following:
public IEnumerable<AspNetUserMessage> GetAllMessages([FromBody]MessageRequest Request)
{
try
{
// Get all the messages sent or received by the user
var messages = db.AspNetUserMessages.Where(o => o.From == Request.From || o.To == Request.From).ToList();
return messages;
}
catch (Exception e)
{
// Log the error to the database
LogException(e);
return null;
}
}
What I want to do is instead of returning all the messages, I want to return a categorized version of the messages. E.g
User1 sent 4 messages to User2;
User1 sent 2 messages to User3
For user1 output should be
[
{
"SentTo": "User2"
"Messages": [All 4 Messages sent to User2 here]
},
{
"SentTo": "User3"
"Messages": [All 2 Messages sent to User3 here]
}
]
How can I achieve this modifying my GetAllMessages function

You have to make a a new model that uses your AspNetUserMessage and fill it.
Make a new model, for now I named it SentMessagesModel
public class SentMessagesModel{
public string SentTo {get;set;}
public List<AspNetUserMessage> Messages {get;set;}
// All 4 Messages sent to User2 here
}
Then make a new controller action that uses the new model. Use the code below
public List<SentMessagesModel> GetAllMessages([FromBody]MessageRequest Request)
{
try
{
// Get all the messages sent or received by the user
var messages = db.AspNetUserMessages.Where(o => o.From == Request.From).ToList();
var groupByTo = messages.GroupBy(m=>m.To);
List<SentMessagesModel> sentMessages = new List<SentMessagesModel>();
foreach(var currentGroup in groupByTo){
sentMessages.Add(new SentMessagesModel(){ SentTo = currentGroup.Key, Messages = currentGroup.ToList() })
}
return sentMessages;
}
catch (Exception e)
{
// Log the error to the database
LogException(e);
return null;
}
}

Related

Rest Assured Post request erase previous data

I am using json-server and have a dummy json. When i am adding a new student (say id=100) using post request. Every time it erase previous student (id=14) and then create new student.
Below is the payload.
{
"data": {
"studname": null,
"student": [
{
"name": "JJJ",
"location": null,
"phone": null,
"courses": null,
"id": 14
}
]
}
}
Here is my rest assured code which i am running through eclipse:
#Test
public void addStudentData() {
StudentList Studentdetails = new StudentList();
StudentsDetails mainDetails = new StudentsDetails();
mainDetails.setName("JJJ");
mainDetails.setId(15);
List < StudentsDetails > details = new ArrayList < StudentsDetails > ();
details.add(mainDetails);
Studentdetails.setStudent(details);
given()
.contentType("application/json")
.body(Studentdetails)
.when()
.post(EndPoints.CREATE_STUDENTS)
.then()
.extract().response().asString();
}
output: Status 201
"data": {
"studname": null,
"student": [
{
"name": "James",
"location": null,
"phone": null,
"courses": null,
"id": 101
}
]
}

Invalid ReplaceNamedRangeContent request

I can successfully create a name range using batchUpdate api, however, replaceNameRangeContent gives the following error:
{ "error": { "code": 400, "message": "Invalid requests[0].replaceNamedRangeContent: Named range with ID kix.ydbik9q4xmna contains content that cannot be replaced.", "status": "INVALID_ARGUMENT" } }
The request for this was:
{ "requests": [ { "replaceNamedRangeContent": { "namedRangeId": "kix.ydbik9q4xmna", "text": "" } } ] }
Am I using the API properly? I created the name range giving start/endindex and naming it. It creates the NameRangeId that I used in the replace content post.
There was content in the index range above. However, below is a sample doc structure for an empty doc (with doc styles, etc. omitted). I tried a
{
"requests": [
{
"createNamedRange": {
"range": {
"startIndex": 1,
"endIndex": 2
},
"name": "ApplicantName"
}
}
]
}
followed by
{
"requests": [
{
"replaceNamedRangeContent": {
"namedRangeId": "kix.f7g9w0sr3kyp",
"text": "Applicant Name"
}
}
]
}
and get the same error. But when doing the create named range it would not accept any start/end index besides 1 and 2.
I must not understand the actual intent of named ranges!
Sample:
{
"title": "Test mule",
"body": {
"content": [
{
"endIndex": 1,
"sectionBreak": {
"sectionStyle": {
"columnSeparatorStyle": "NONE",
"contentDirection": "LEFT_TO_RIGHT",
"sectionType": "CONTINUOUS"
}
}
},
{
"startIndex": 1,
"endIndex": 2,
"paragraph": {
"elements": [
{
"startIndex": 1,
"endIndex": 2,
"textRun": {
"content": "\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
}
]
}
I can reproduce your error when creating a named range with "startIndex": 0
Mind that indices for paragraphs (and thus text) in Google Docs refer to the position of a character in the text and start with 1.
So if you create a name range specifying the indices correctly, you will not get the error mesage
{ "error": { "code": 400, "message": "Invalid requests[0].replaceNamedRangeContent: Named range with ID kix.ydbik9q4xmna contains content that cannot be replaced.", "status": "INVALID_ARGUMENT" } }
Sample request for creating named ranges:
{
"requests": [
{
"createNamedRange": {
"range": {
"startIndex": 5,
"endIndex": 7
},
"name": "test3"
}
}
]
}

Generate response example values using swagger with GRPC

I'm generating swagger json file using protoc-gen-swagger with gRPC service. The output json is being generated with empty response examples, I want to add response examples to the definition so it gets automatically populated in the generated json.
This is my current definition.
service UserService {
rpc GetUser (GetUserRequest) returns (UserResponse){
option (google.api.http) = {
get: "/api/v1/user/{username}"
response_body: "*"
};
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
description: "Returns user object";
operation_id: "get_user";
summary: "Get User";
};
}
}
message GetUserRequest {
string username = 1;
}
message UserResponse {
User user = 1;
}
message User {
string first_name = 1;
string last_name = 2;
string username = 3;
}
When I generate the swagger file using the command
protoc -I ${PROTOPATH} \
-I $GOPATH/src \
--swagger_out=logtostderr=true:${OUT_PATH}
I get a swagger file with this user object definition
"User": {
"type": "object",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"username": {
"type": "string"
},
}
}
What I want is to generate it with example values like this:
"User": {
"type": "object",
"properties": {
"first_name": {
"type": "string",
"example": "Adam"
},
"last_name": {
"type": "string",
"example": "Smith"
},
"username": {
"type": "string",
"example": "asmith79"
},
}
}
Found the answer to this here: https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto#L197
Simple by adding grpc.gateway.protoc_gen_swagger.options.openapiv2_schema as an option to the message.
import "protoc-gen-swagger/options/annotations.proto";
message User {
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
example: { value: '{ "first_name": "Adam", "last_name":"Smith", "username":"asmith79"}' }
};
string first_name = 1;
string last_name = 2;
string username = 3;
}

Owner_id field does not pass validation error. What is wrong with my schema?

I am looking into what is wrong with my schema. I'm attempting to insert an entry into my collection and I have gotten a slew of errors as I've changed things around but this seems to be the closest I have gotten to successfully inserting a document. I am using the mongodb-stitch-browser-sdk in a React Ionic project and I have a valid user logged in.
I am using the StitchUser.id which is a string as my owner_id (matches the id of my valid user in users collection).
Here is my schema followed by the error in Stitch logs. I was simply trying to insert a document to my Goals table. Also, there are no filters on this collection and there is only one role with the following rule.
{
"owner_id": "%%user.id"
}
This gives the user read and write permissions on the collection's that they created.
{
"bsonType": "object",
"required": [
"goalTitle",
"startDate",
"endDate",
"owner_id"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"owner_id": {
"bsonType": "string",
"validate": {
"%or": [
{
"%%prevRoot.owner_id": {
"%exists": false
}
},
{
"%%prevRoot.owner_id": "%%this"
}
]
}
},
"goalTitle": {
"bsonType": "string",
"minLength": {
"$numberInt": "1"
},
"maxLength": {
"$numberInt": "30"
}
},
"goalDescription": {
"bsonType": "string",
"minLength": {
"$numberInt": "0"
},
"maxLength": {
"$numberInt": "600"
}
},
"startDate": {
"bsonType": "string"
},
"endDate": {
"bsonType": "string"
}
}
}
Error:
role "owner" in "todo_list.Goals" does not have insert permission for document with _id: ObjectID("5e6aa8d11d233536e3ea8604"): could not validate document:
owner_id: Does not pass validation
Stack Trace:
StitchError: insert not permitted
Details:
{
"serviceAction": "insertOne",
"serviceName": "mongodb-atlas",
"serviceType": "mongodb-atlas"
}
{
"arguments": [
{
"collection": "Goals",
"database": "todo_list",
"document": {
"goalTitle": "Test Goal",
"goalDescription": "Test Description",
"endDate": "2020-03-11",
"startDate": "2020-03-10",
"owner_id": "5e6891382e6039c1c32f7d46",
"_id": {
"$oid": "5e6aa8d11d233536e3ea8604"
}
}
}
],
"name": "insertOne",
"service": "mongodb-atlas"
}
I've created another collection with no schema and the same rule checking for owner_id and documents in that collection are able to be inserted just fine. I'd have to imagine it is a schema error.

How to store business ID in elasticsearch?

I'm trying to store tweets in some Elasticsearch index using Spring Data Elasticsearch (for tweet requesting , I'm using twitter4j).
I have followed some basic example and I'm using this basic annotated POJO (metadatas with complex type have been removed) :
#Document(indexName = "twitter", type = "tweet")
public class StorableTweet {
#Id
private long id;
private String createdAt;
private String text;
private String source;
private boolean isTruncated;
private long inReplyToStatusId;
private long inReplyToUserId;
private boolean isFavorited;
private boolean isRetweeted;
private int favoriteCount;
private String inReplyToScreenName;
private String userScreenName = null;
// Getters/setters removed
}
To store a tweet using this model, I use :
public interface TweetRepository extends ElasticsearchRepository<StorableTweet, Long> {
}
and in my storing service :
tweetRepository.save(storableTweet);
It works fine, but my tweet Id is stored in "_id" (why not) and some other number coming from nowhere is stored in "id" (why....?) :
{
"_index": "twitter",
"_type": "tweet",
**"_id": "655008947099840512"**, <-- this is the real tweet id
"_version": 1,
"found": true,
"_source":
{
**"id": 655008947099840500**, <-- this number comes from nowhere
"createdAt": "Fri Oct 16 15:14:37 CEST 2015",
"text": "tweet text(...)",
"source": "Twitter for iPhone",
"inReplyToStatusId": -1,
"inReplyToUserId": -1,
"favoriteCount": 0,
"inReplyToScreenName": null,
"user": "971jml",
"favorited": false,
"retweeted": false,
"truncated": false
}
}
What I would like is either my tweet id stored in "_id" (and no "id" field), either my tweet id stored in "id" an having a generated number in "_id", and get rid of this random useless number in "id".
EDIT
mapping :
{
"twitter":
{
"mappings":
{
"tweet":
{
"properties":
{
"createdAt":
{
"type": "string"
},
"favoriteCount":
{
"type": "long"
},
"favorited":
{
"type": "boolean"
},
"inReplyToScreenName":
{
"type": "string"
},
"inReplyToStatusId":
{
"type": "long"
},
"inReplyToUserId":
{
"type": "long"
},
"retweeted":
{
"type": "boolean"
},
"source":
{
"type": "string"
},
"text":
{
"type": "string"
},
"truncated":
{
"type": "boolean"
},
"tweetId":
{
"type": "long"
},
"user":
{
"type": "string"
}
}
}
}
}
}
EDIT 2 : It looks like the problem is not about #Id annotation but about "long" type. Some other longs (not all) are transformed (a few units more or less) when stored into elasticsearch via Spring Data Elasticsearch.

Resources