WEB API With database Post Method - c#

I need to make an API Post method where I insert data into the database.
The database has 3 fields: One field has default values given by the database, one I have to insert with a new Guid.NewGuid() method, and one is inserted by the user.
How can I do this? Never seen anything like this in a tutorial.
If you can give me an example I will appreciate.
I'm new in web APIs and have seen a bunch of tutorials since Wednesday and can't reach a solution.
EDIT:
Here is my code:
public HttpResponseMessage Post(Company value)
{
try
{
if(ModelState.IsValid)
{
bd.Companies.Add(value);
bd.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, "Invalid Model");
}
}
catch (Exception ex )
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
How can i put a Guid.NewGuid()in this code to give a value to one of my fields?
EDIT2: My class to receive the values from Post
public class CompanyPostViewModel : Company
{
public static Guid Guid.NewGuid(); -->how can i do this?
public string Name { get; set; }
public DateTime? CreatedDate { get; set; }
}

If you are looking for an example, that fully goes from the front-end, to using WEB API [Post], to writing to the database, please see the following site. It should provide you enough context to complete what you are trying to accomplish. If this is insufficient, please post your current code, and where you are having any issues.

Related

How can I create dynamic API's in ASP.net Core 2

I need to know how to create API's dynamically by calling another API then passing [API name] and [API parameters], let's we assume that we have this API, like the one shown here:
[HttpPost("GenerateApi")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public IActionResult GenerateApi(RootObject ro)
{
//Here I need piece of code to create API dynamically
return Ok(new { ro.apiName, ro.parameters });
}
Here are the models:
public class RootObject
{
public string apiName { get; set; }
public List<parameter> parameters { get; set; }
}
public class parameter
{
public string parameterName { get; set; }
public dynamic parameterType { get; set; }
}
Now what needs to be done, is to create dynamic API in controller.
So then we would have the API created they can be called from their URL like this
www.example.com/api/v1/[controller]/[apiName]/{[parameter1_value]}/{[parameter2_value]}
Can you please provide me some insight of this.
Found some thing can help in MVC. In case somebody else is looking for this, I need to overwrite the DefaultHttpControllerSelector. Here is a very nice article on the subject: link So basically for my use case mentioned above, I need to create a new AppDomain, start my service in it, and load my assemblies dynamically at runtime. I finally need to overwrite the DefaultHttpControllerSelector to catch the request. When the request arrive, it have then control on which controller I want to use. There I can update the controller dynamically by loading a new assembly, etc. Main thing to be careful on is that this is executed for each request so it could easily impact performance and memory. So I will implement my own caching of controller.

c# filter database results using EF similar to SQL WHERE Clause

I've connected to my database using Entity Framework and am building my first MVC app for use in a web page.
I can get the controller to populate public strings in my models with no problem... the issue I'm having is that I can't figure out how to filter responses from my database.
I expect to have only one item returned which I will display in the view with #Model.BusinessUnit
Here's my Model Class for the database table:
public partial class TBL_Wholesale_UWS_BusinessUnits
{
public int PrimaryID { get; set; }
public string BusinessUnit { get; set; }
public string Status { get; set; }
}
Here's what I have in my controller:
public ActionResult test(int PrimaryID)
{
var testing = new TBL_Wholesale_UWS_BusinessUnits();
// maybe putting new is the wrong thing to do as that would be wiping the class? IDK
return View(testing);
}
As you can see, the PrimaryID is passed to the controller via the querystring and this is recognised without issue, but I'm at a loss as to where to add the filter, I assumed it would be something like...
var testing = TBL_Wholesale_UWS_BusinessUnits.Where(TBL_Wholesale_UWS_BusinessUnits.PrimaryID = PrimaryID);`
but Visual Studio is telling me in no uncertain terms that this this wrong.
Had this been classic asp I would have just made a record set and used the where clause in SQL, but as this is built with the Entity Framework to do my connecting I don't really know where to start.
Any help would be greatly appreciated.
If you are only trying to return that one specific object to the view.. then you need to find that int PrimaryID in the database and retrieve that specific record.
What you are doing is simply creating a new instance of the TBL_Wholesale_UWS_BusinessUnits class which is empty.
Try this:
public ActionResult test(int PrimaryID)
{
var testing = db.TableName.Find(PrimaryID);
// db = Whatever the variable holding your connection string is.. maybe DbContext
// TableName = Whatever table in your database that holds the record you want
// This will return the specific object that you are looking for
return View(testing);
}
I hope this helps!

Data sent through post method results in a null object

this is my first time ever asking a question on stackoverflow. I have searched through this site many times to look for answers, but this is my first time asking my own! Hopefully I will give enough information so you guys can understand my question.
So basically I have created a new table in our database on sqlserver. I have created a new entity in our entity framework to map to this table as well. The problem is my post method in my odata controller for this database table. Here is the method:
[HttpPost]
[ODataRoute("TerminalPersonnelEmails/LoadEmail()")]
[ResponseType(typeof(TerminalPersonnelEmail))]
public async Task<IHttpActionResult> PostAsync(TerminalPersonnelEmail email)
{
if (email == null)
{
throw new ArgumentException("The data entry given is invalid");
}
portalDatabaseContext.TerminalPersonnelEmails.Add(email);
await portalDatabaseContext.SaveChangesAsync();
//return Created(email);
return Ok("test"); //will be replaced once post method is fixed
}
Here is what I am sending through postman:
{"TerminalEmail" :{
"Id" : 1,
"Name" : "NewEmail",
"Email" : "email#email.com",
"TerminalNumber" : 23084093284 } }
(Sorry for weird indentations/placement of brackets. When i pasted in the code, 1 or 2 indentations were off and my postman code was messed up so I fixed it as best as I could to get it into the code block box).
I have tried several ways to send this data. I have tried just sending the data without clumping it into "TerminalEmail", not sending Id because it is autonum in the database, and I have messed with the content type (json, text, etc.). None of this has worked.
I have made sure that the data matches up with the object so that it should be passing in a valid object to the c# method, but it still is null. I have tired out all of my options and need your help. Thanks!
edit: Here is declaration of terminalpersonnelemail class in the entityframework as requested:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marketing.EntityFramework.Portal
{
[Table("TerminalPersonnelEmails", Schema = "Portal")]
public class TerminalPersonnelEmail
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required, MaxLength(50)]
public string Name { get; set; }
[Required, MaxLength(50)]
public string Email { get; set; }
[Required]
public int TerminalNumber { get; set; }
}
}
Ok, so I found out how to fix it, but I couldn't tell you why this works. I took out the odata route, and in my odata config took out everything except the entityset that I had created. Here is the working code:
[HttpPost]
[ResponseType(typeof(TerminalPersonnelEmail))]
public async Task<IHttpActionResult> Post(TerminalPersonnelEmail email)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (email == null)
{
throw new ArgumentException("The data entry given is invalid");
}
portalDatabaseContext.TerminalPersonnelEmails.Add(email);
await portalDatabaseContext.SaveChangesAsync();
return Created(email);

C# Web API Help Documentation IHttpActionResult

I have a C# Web API and I am trying to get the auto created help documentation to work with IHttpActionResult. I stripped down the example below so its a little easier to read.
For the object, below is a simple example. BusinessObject is just a wrapper. The CollectionBase is CollectionBase : ObservableCollection<T>, ILoadable where T : BusinessObject. Its an older code base that is auto generated but reusing it for this.
public class Value : BusinessObject
{
public int Id { get; set; }
}
public class Values : CollectionBase<Value>
{
public override Value LoadObject(System.Data.IDataRecord record)
{
return new Value();
}
}
For the API side of things. The following works.
public class Values : ApiController
{
public IEnumerable<Value> GetThis()
{
Values values = new Values();
return values;
}
}
The issue comes when I try to do
public IHttpActionResult GetThis()
{
Values values = new Values();
return Ok(values);
}
It doesn't recognize that it should use a different return type. The 'Resource Description' ends up being IHttpActionResult with no sample output. Now I can add
config.SetActualResponseType(typeof(IEnumerable<Value>), "Values", "GetThis");
and it will show a sample output but the 'Resource Description' will still be IHttpActionResult. That is the main issue I am having. I would like to use IHttpActionResult because its very easy to use and can return error codes if needed very easily. I would just like to be able to auto construct the documentation.
UPDATE: Upon some further research, I did fine this post.
Resource Description on Web API Help page is showing "None."
Bascially, you add the response type attribute to the method.
[ResponseType(typeof(IEnumerable<Value>))]
public IHttpActionResult GetThis()
{
Values values = new Values();
return Ok(values);
}
Although this technically works and I have modified my existing code to use this. It would still be nice if there was a way to have it automatically figure it out somehow. Not sure if this is possible or not.
This works for what I am doing. Its a little tedious to have to include every time but it allows me to return error codes if necessary and retain the help documentation functionality.
[ResponseType(typeof(IEnumerable<Value>))]
public IHttpActionResult GetThis()
{
Values values = new Values();
return Ok(values);
}
Resource Description on Web API Help page is showing "None."

Is this an MVC anti-pattern?

I’m very new to any kind of .NET web development (thus far I’ve worked primarily with Winforms and services.) I’ve started to work on an existing MVC3 project with two other developers. I’m conceptually familiar with MVC, and am trying to catch up on how it’s used in this project.
We have an AccountDto class to represent Accounts. There is a Response class that is inherited by another class for each Entity, i.e. AccountResponse:
public class Response
{
[DataMember]
public bool IsSuccess{get;set;}
[DataMember]
public string DisplayMessage { get; set; }
[DataMember]
public string DetailedMessage { get; set; }
[DataMember]
public ErrorType ErrorType { get; set; }
public Response(){
this.IsSuccess=true;
this.ErrorType = ErrorType.None;
}
}
public partial class AccountResponse : Response
{
[DataMember]
public IList<AccountDto> AccountList { get; set; }
}
There’s an AccountService which will return an AccountResponse to the Controller, with a list of the AccountDto object:
public AccountResponse GetAccountByAccountId(Int64 accountId)
{
_logger.Info("Executing GetAccountByAccountId()");
AccountResponse response = new AccountResponse();
try
{
Account item = AccountPersistence.GetAccountByAccountId(accountId);
AccountDto dto = Mapper.Map<AccountDto>(item);
response.AccountList = new List<AccountDto>() { dto };
response.IsSuccess = true;
}
catch (Exception ex)
{
response.IsSuccess = false;
response.ErrorType = ErrorType.GeneralFault;
response.DetailedMessage = ex.ExceptionMessageBuilder();
response.DisplayMessage = "System Failure: Failed to get Account by AccountId";
_logger.Error(ex);
}
return response;
}
I was told the Response thing is implemented to be able to handle success/failure messages. So in a controller, there’s code like the following (doesn’t happen to do anything special if a failure):
public ActionResult ToBeCalled(int id)
{
AccountDto dto = null;
var response = _accountService.GetAccountByAccountId(Convert.ToInt64(id));
if (response.IsSuccess)
{
dto = response.AccountList[0];
return View(dto);
}
return View(dto);
}
This made sense to me though I wasn’t sure where the success/error messages were going to be utilized. However, they now want to switch from using the DTO in views to using the Response, so success/failure will have to be handled in the views:
public ActionResult ToBeCalled(int id)
{
var response = _accountService.GetAccountByAccountId(Convert.ToInt64(id));
return View(response);
}
This seems off to me – instead of coding against a DTO as the model, I have to do something like the following for each page:
#{
if (Model.IsSuccess)
{
var account = Model.AccountList.FirstOrDefault();
if (account != null)
{
#Html.HiddenFor(x => account.AccountNumber)
}
}
The controllers’ ActionResult / HttpPost methods then have to also parse the DTO from these Response objects. This seems like an anti-pattern to me; are approaches like this normal?
Apologies if this is too lengthy, please migrate if it belongs on Code Review or another site.
I agree with you that this would be an anti-pattern. The View is supposed to be quite ignorant, especially of logic like this.
I can see why this would be tempting, if the difference between success and failure is a minor part of the UI, but imagine if that were to change. A view has little ability (without unnecessary nesting of partials) to switch to an entirely different view. It has no ability to issue a redirect or other error codes. In the event that you decide to change your UI, you may have to go back and rewrite your Controller yet again.
If the reasoning behind moving the logic to the view was to remove the response.IsSuccess logic from the Controller (and to be honest, that seems fine to me; it's pretty much the same as the classic Model.IsValid), you could consider another approach: refactor your Response class to inherit from ActionResult. Then you could move that logic into the ExecuteResult() method and it would be separate from your Controller.
Just use the coalesce operator and you can get rid of a whole lot of cruft (like that strange Response base class (which should be marked abstract if it continues to exist)) and avoid null-checking.
public ActionResult ToBeCalled(int id)
{
var response = _accountService.GetAccountByAccountId(id) ??
new AccountResponse();
return View(response);
}
Better yet, migrate that logic into your service class so that it guarantees return of an object (it doesn't necessarily make sense for a repository to do this when there's no backing entity, but it does for a service).
Either way, you don't need to include unsightly null-checking or if/else logic on your view. Move as much logic to places that you can test it as you can and you'll be happier.

Categories