All,
Still learning this stuff so not sure what I am missing.
Here is the path I want to pass to the server.
model.CreditReportHistoryRoute = Url.RouteUrl(CreditReportHistoryDialogController.RouteGetInitialData, new { databaseId = 12345 }).Replace("12345", "{databaseId}");
databaseId is null when I run the code (at the end of the above line).
A few lines above this code runs fine
model.ReportRoute = Url.RouteUrl(RequestReportRoute, new { subjectId = 12345 }).Replace("12345", "{subjectId}");
Here is the controller/route code
public sealed class CreditReportHistoryDialogController : WebAccessApiController
{
public const string RouteGetInitialData = "CreditReportHistoryDialog.GetDataForDatabase";
[Route("{databaseId:int}", Name = RouteGetInitialData), MemberAccess, HttpPost]
public IHttpActionResult GetInitialData(int databaseId)
{
return Ok(databaseId);
}
Thx
jonpfl
Related
I created a function that add a new user with Angular/WebAPI , so in angular i send the object like this :
AddUser(person : person):Observable<person>
{
return this.http.post<person>(this.baseUrl,person);
}
and in WebAPI i got the data :
[HttpPost]
public async Task<ActionResult<Person>> PostPerson(Person person)
{
Now I want to add a picture of each user, and i don't know how it's gonna be the objet in angular, should i add a property imageProfile as File which i'm not sure if it's possible , or it should be a string of the uploaded file.
export class person {
idPerson:number=0;
fname : string ="" ;
lname : string ="";
password : string ="";
idCategory? :number;
nameCategory:string="";
imageProfile :
}
That's very good info from Codemaze, as always. The remark from Lavstsen is not correct, there's no need for a separate call.
For example, you could have a form linked to the structure of the person-type:
initializeForm() {
this.personForm = this.form.group({
fname: [''],
})
}
In your onSubmit-method, you seize the date from your form and put in a dto, in this example through a getPersonDto-method
private getPersonDto(): PersonDto {
let dto = new PersonDto();
dto.fname = this.imageForm.controls.fname.value;
return dto;
}
and next you can solve it like this:
const formData = new FormData();
formData.append('Imagefile', this.selectedFile, this.selectedFile.name);
formData.append('fname', personDto.fname); // needs to be strings => toString()
this.personApiClient.uploadImageFile(this.personId, formData)
.subscribe((res: any) => {
this.uploadOrDeleteResults = res;
this.showToastrMessageSuccess("PAGES.COMMON.TOASTR.TITLE.SUCCESSFULCREATE", "PAGES.COMMON.TOASTR.MESSAGE.SUCCESSFULCREATE");
},
(error) => {
this.crudHasErrors = true;
this.errorHttpErrorResponse = error;
this.errors = this.errorHttpErrorResponse.error;
},
you don't need the dto-step as such, but if you structurally always use dto's in your application, it would make more sense
Take care and good luck
I have another workaround but this will only work for very small files where you don't need upload percentage to show on UI.
I have my controller like this:
[HttpPost("/api/sign-up")]
public void SaveUser([FromForm] UserModel info)
{
_logger.LogDebug(null, "Hello", info); // Just to see contents of info object in debugger
}
and make your model like this:
public class UserModel
{
[FromForm(Name = "avatar")]
public IFormFile Avatar { get; set; }
[FromForm(Name = "email")]
public string Email { get; set; }
}
I'm having trouble enabling logging for a ServiceStack.JsonServiceClient. I'm working from the documentation Capture HTTP Headers in .NET Service Clients but I must be missing something becasue I'm only ever getting an empty string.
Here's my code:
public class Client
{
private bool Logging { get; }
public Client(bool logging = false)
{
Api = new("https://api.service.com/");
Logging = logging;
if (Logging) Api.CaptureHttp(true, true);
}
public string GetInfo(string name)
{
if (Logging) Api.HttpLog.Clear();
var response = Api.Get(new Requests.GetInfo(name));
Debug.WriteLine(Api.HttpLog.ToString());
return response.Result;
}
}
[Route("/v1/getinfo/{name}")]
[DataContract]
public class GetInfo : Base, IReturn<Responses.GetInfo>
{
public GetInfo(string name) => Name = name;
[DataMember(Name = "name")]
public string Name { get; init; }
}
[TestMethod]
public void Client_GetInfo()
{
var client = new Client(true);
client.GetInfo()
}
Because I have Api.CaptureHttp(true, true) it is logging the info to the test log but I want to be able to capture the httpLog in code and like I said, it's only ever an empty string there.
CaptureHttp has 3 flags:
public void CaptureHttp(bool print = false, bool log = false, bool clear = true)
You're only setting Api.CaptureHttp(print:true,log:true) which should print to the console and log to your logger if IsDebugEnabled, your call only sets the first 2 flags but you're code is relying on capturing the log to print it out in which case you wanted to specify that it shouldn't clear the HttpLog after each request with:
Api.CaptureHttp(clear:false)
I am trying to loop through id's in a collection for a MongoDb database. The goal is to loop trough these id's and use the id's to create a json files with the different id's. I believe the query that I wrote is returning all the id's, but then i get the below error.
Inner Exception 1:
FormatException: '9a1c458c-82Dd-43b4-a963-76a96d374580' is not a valid 24 digit hex string.
Below is my query to get all the id's
var thingsDoc = demoThings.AsQueryable().Where(a => a._id != null).ToList();
Below is my class of properties for Things
public class Things
{
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId _id { get; set; }
}
I believe the issue is with how the properties are defined. Or maybe it is a problem with my query? From research I know the reason it is complaining is because of the dashes in the format. But not finding any work arounds to resolve this. Help is much appreciated.
I've been able to resolve my issue. It seems that using a Model and doing a conversion between ObjectId and String was throwing off my program. So the below approach solved the issue.
var demoThings = DBConnect.CosmosClient.GetCollection<BsonDocument>("Things");
foreach(var doc in demoThings.Find(x => x["_id"] != "").ToList())
{
thingList.Add(doc["_id"].ToString());
}
My goal was to grab the collection and add all the _id's and add them to a list so that I could I simulate data in a json file and attach an id to the JSON. With the above i was able to grab the id's and them to a list.
Changing [BsonRepresentation (BsonType.ObjectId)] to [BsonId] will most likely solve your problem.
How can I tell the MongoDB C# driver to store all Guids in string format?
Difference between decorating a property in C# with BsonRepresentation(BsonType.ObjectId) vs BsonId vs ObjectId
Edit:
I created a simple working example.
It's a model.
public class Model
{
[BsonId]
[BsonElement("id")]
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId ID { get; set; }
public Model(ObjectId id)
{
ID = id;
}
}
This is a simple service class:
public interface IModelService
{
Task<IEnumerable<string>> GetModelsIds();
Task AddModel();
}
public class ModelService : IModelService
{
private const string CollectionName = "Models";
private readonly MongoClient client;
private readonly IMongoDatabase _mongoDatabase;
private readonly IMongoCollection<Model> _modelsCollection;
public ModelService()
{
client = new MongoClient("mongodb://localhost:27017");
_mongoDatabase = client.GetDatabase("MongoStackOverFlow");
_productsCollection = _mongoDatabase.GetCollection<Model>(CollectionName);
}
public async Task<IEnumerable<string>> GetModelsIds()
{
var models = await _productsCollection.Find(p => p.ID != null).ToListAsync();
return models.Select(x => x.ID.ToString());
}
public async Task AddModel()
{
var model = new Model(new ObjectId());
await _productsCollection.InsertOneAsync(model);
}
}
And the entry point:
class Program
{
static async Task Main(string[] args)
{
IModelService modelService = new ModelService();
var modelsIds = await modelService.GetModelsIds();
if (!modelsIds.Any())
{
for (int i = 0; i <= 10; i++)
{
await modelService.AddModel();
}
}
Task.WaitAll();
foreach (var modelId in modelsIds)
{
Console.WriteLine($"ProductID: {modelId}");
}
}
}
So I have this simple (for others) exercise where i need to create a pharmacy and add to that 2 types of drugs. I have one class called Drugs which contains the attributes of the drugs:
public class drugattr
{
public int id;
public string drugName;
public string DrugDesc;
public int drugIntensity ;
public drugattr(int id, string drugName, string DrugDesc, int drugIntensity)
{
this.id = id;
this.drugName= drugName;
this.DrugDesc = DrugDesc;
this.drugIntensity = drugIntensity ;
}
}
Then i have a pharmacy class with the pharmacies attributes:
public class pharmacyatrr
{
public string PharmacyName;
public string PharmacyTown;
public List<drugattr> Atrributes= null; // the list with the drugs' attributes
public pharmacyatrr(string pharmacyName, string pharmacyTown, List<drugattr> atrributes)
{
this.PharmacyName = pharmacyName;
this.PharmacyTown = pharmacyTown;
this.Atrributes = atrributes;
}
and i have my main class where i need to create a pharmacy and assign to it a couple of drugs.
public class Program : pharmacyatrr
{
public Program(string PharmacyName, string PharmacyTown , List<drugattr> Atrributes) : base(PharmacyName, PharmacyTown , Atrributes)
{
this.PharmacyName = pharmacyName;
this.PharmacyTown = pharmacyTown;
this.Atrributes = atrributes;
}
static void Main(string[] args)
{
drugattr drugA = new drugattr(1, "DrugA_Name", "Very STrong", 20);
drugattr drugB = new drugattr(2, "DrugB_Name", "Mild Strong", 8);
pharmacyatrr pharmacy1 = new pharmacyatrr("PharmacyName", "Town", drugA); // the problem is here
}
}
So if I try to add drugB i get the expected error that it can only accept 3 parameters.
If i create a pharmacy2 with the same name and town but with drugB that wouldn't create a new pharmacy?
I need one pharmacy to have multiple drug entries...
any tips on how to solve this? I am fairly new to C# and programming so please don't go harsh on me!
This should work. Pretty much what everyone has said, but just the complete code.
Drugs Class
class DrugAttribute
{
public int id;
public string drugName;
public string drugDescription;
public int drugIntensity;
public DrugAttribute(int id, string drugName, string drugDescription, int drugIntensity)
{
this.id = id;
this.drugName = drugName;
this.drugDescription = drugDescription;
this.drugIntensity = drugIntensity;
}
}
And the Pharmacy Class
class PharmacyAtrribute
{
public string pharmacyName;
public string pharmacyTown;
public List<DrugAttribute> drugList = null;
public PharmacyAtrribute(string pharmacyName, string pharmacyTown, List<DrugAttribute> drugList)
{
this.pharmacyName = pharmacyName;
this.pharmacyTown = pharmacyTown;
this.drugList = new List<DrugAttribute>(drugList);
}
}
And the main class
class Program : PharmacyAtrribute
{
public Program(string pharmacyName, string pharmacyTown, List<DrugAttribute> drugList) : base(pharmacyName, pharmacyTown, drugList)
{
this.pharmacyName = pharmacyName;
this.pharmacyTown = pharmacyTown;
this.drugList = new List<DrugAttribute>(drugList);
}
static void Main(string[] args)
{
DrugAttribute drugA = new DrugAttribute(1, "DrugA_Name", "Very Strong", 20);
DrugAttribute drugB = new DrugAttribute(2, "DrugB_Name", "Mild Strong", 8);
List<DrugAttribute> listOfDrugs = new List<DrugAttribute>{ drugA, drugB };
PharmacyAtrribute pharmacy1 = new PharmacyAtrribute("PharmacyName", "Town", listOfDrugs);
}
}
I'm sure you may have noticed I changed some of the names. I'll just give you a couple of helpful tips regarding naming conventions. For Classnames, Microsoft encourages use of the Pascal capitalization style. So in your case, drugattr would be DrugAttr. For variables and attributes, Camel Case is encouraged. So
public string PharmacyName;
public string PharmacyTown;
public List<drugattr> Atrributes= null;
should become
public string pharmacyName;
public string pharmacyTown;
public List<drugattr> atrributes= null;
For more about naming conventions, have a look at this https://msdn.microsoft.com/en-us/library/x2dbyw72(v=vs.71).aspx
And with names, it's good to be as descriptive as possible, so calling your class DrugAttributes might be a good idea. Anyone who is reading your code will know exactly what it's about even without comments (Although comments are a must too).
Even if it's just a simple learning exercise, it's always good to practice with conventional styles.
You need to create a list of drugs to match your List parameter in the pharmacyattr constructor.
Create a new list like:
List<drugattr> drugList = new List<drugattr>();
And add to the list like this:
drugList.Add(drugA);
You can then create your pharmacy with the slight adjustment of:
pharmacyatrr pharmacy1 = new pharmacyatrr("PharmacyName", "Town", drugList);
var drugs = new List<drugattr> { drugA, drugB };
pharmacyatrr pharmacy1 = new pharmacyatrr("PharmacyName", "Town", drugs);
When a path is named...
[Route("api/[controller]/{id}/Existing", Name = "ExistingOrdersLink")]
public class OrdersController : Controller {...}
...it is easy to create an absolute path using its name:
var address = Url.Link("ExistingOrdersLink", new { id = 22 });
However, I need the ability to generate a relative path from a Route name. So I write code like this:
//Is there a built-in mechanism for this?
string partial = new Uri(Url.Link("ExistingOrdersLink", new { id = id })).PathAndQuery;
The above works but, in ASP.NET Core, is there a more direct way to get the same result?
Context
Why do I need this? Some of the controllers I make are actually generic:
[Route("api/Subscribers/{id}/[controller]", "SubscriberLink")]
[Route("api/Organization/{id}/[controller]", "OrganizationLink")]
public class OrdersController<T> : Controller where T : IOrder
{
private ICommand<Order<T>> createOrder;
protected OrdersController(ICommand<Order<T>> createOrder)
{
this.createOrder = createOrder;
}
[HttpPost("{otype}")]
public async Task<IActionResult> Create(
Guid id,
[FromBody] Order<T> order)
{
order.CustomerOrderId = Guid.NewGuid();
createOrder.Handle(order);
string[] segs = Request.Path.Value.Split(new char[] { '/' },StringSplitOptions.RemoveEmptyEntries);
//This will become either "SubscriberLink" or "OrganizationLink"
string route = $"{segs[1]}Link";
//Is there a built-in mechanism for this?
string partial = new Uri(Url.Link(route, new { id = id })).PathAndQuery;
partial = $"{partial}/{order.CustomerOrderId}";
CreatedResult reply = Created(partial, null);
return reply;
}
}
I think you are looking for Url.RouteUrl
Example:
Url.RouteUrl("ExistingOrdersLink", new { id = 22});