Guid of created aggregate root in CQRS - asp.net-mvc

Looking at this code from here:
[Serializable]
public class CreateClientCommand : Command
{
public string ClientName { get; private set; }
public string Street { get; private set; }
public string StreetNumber { get; private set; }
public string PostalCode { get; private set; }
public string City { get; private set; }
public string PhoneNumber { get; private set; }
public CreateClientCommand(Guid id, string clientName, string street, string streetNumber, string postalCode, string city, string phoneNumber) : base(id)
{
ClientName = clientName;
Street = street;
StreetNumber = streetNumber;
PostalCode = postalCode;
City = city;
PhoneNumber = phoneNumber;
}
}
The Guid here is just relevant for the command. It is not the Guid of the (potentially) created aggregate root. What is the best practice to obtain this Guid and how are any potential validation errors communicated back to the the code that puts a command on the bus? For example like this:
_bus.Publish(new CreateClientCommand(
Guid.NewGuid(),
_clientDetailsReport.ClientName,
_clientDetailsReport.Street,
_clientDetailsReport.StreetNumber,
_clientDetailsReport.PostalCode,
_clientDetailsReport.City,
_clientDetailsView.PhoneNumber));
_bus.Commit();
I understand that CQRS usually implements eventual consistency. This means that it might take a while before the client is actually created. Some MVC/CQRS code uses this approach:
[HttpPost]
public ActionResult Add(DiaryItemDto item)
{
ServiceLocator.CommandBus.Send(new CreateItemCommand(Guid.NewGuid(),item.Title,item.Description,-1,item.From,item.To));
return RedirectToAction("Index");
}
Obviously, the index page might show some grid containing the DiaryItems and the user might be able to see the latest created DiaryItem (potentiality after a while). Any feedback would be very much appreciated. Thanks.

Are you asking about the distinction between an ID for the command itself, versus the ID of the entity it might create? The former would typically be an infrastructure concern, found on something like a message envelope, buried in a RPC protocol, or the like. The latter would be part of your domain. (Though in many cases, it's nice to treat the ID of an entity as an infrastructure concern as well, since you might choose it for convenience in your persistence model.)

The easiest way to do this is to use the guid that you pass on the command as the actual aggregate Id and then you have it to hand and don't have to wait for it to be communicated back down on an event

Not sure why your command has an id it confuses things ( Yes some distributed systems use this but it should be a last resort). Most developers would see this as the id of the aggregate .
Generally just create the aggregate Id and send it with the command . After all the command is creating the Entity ..
Commands should in most cases be sync so you can throw errors back . With async commands you really should have a call back for success or failure ( and async should only be used where you really have the need it adds a lot of cost to the system ) .
You don't move to the next step ( if you need a next step ) until either
A) Its a system that deals with eventual consistency, a lot of business logic does do this. eg waiting for the exchange or a 3rd party to process something , then the work is waiting for that information . ( Ie the command creates an Order but the processing of the order eg OrderDetail may not be there yet and the order has a state of Order Processing)
B) You have success , timeout or failure response to command before continuing .

Related

why to use select statement even though inserting values in sql server database,using entity framework MVC application

I am very new to the MVC,Entity framework application and am still learning. I have a query.
I am inserting the values in SQL server database using Entity Framework and MVC application with the stored procedure. I am using the DB first approach. I want to ask why I need to add an select statement even though I have written the procedure to insert the values. If I dont write the select statement then it throws the error.
An exception of type 'System.Data.Entity.Core.EntityCommandExecutionException' occurred in EntityFramework.SqlServer.dll but was not handled in user code
Additional information: The data reader is incompatible with the specified 'EmployeeDBModel.Employee'. A member of the type, 'Id', does not have a corresponding column in the data reader with the same name.
ALTER PROCEDURE [dbo].[sp_InsertEmployees]
-- Add the parameters for the stored procedure here
#FirstName varchar(50),
#LastName varchar(50),
#Address varchar(50),
#Salary int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
Insert into Employee values(#FirstName,#LastName,#Address,#Salary)
--select scope_identity() as Id,Firstname,LastName,Address,Salary from Employee
END
If I uncomment select command it just work.
Note:- Id is identity column and auto seed is true
Model :-
public partial class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public Nullable<int> Salary { get; set; }
}
Controller:
[HttpPost]
public ActionResult Create(Employee emp)
{
using (EmployeeDBEntities db = new EmployeeDBEntities())
{
if (ModelState.IsValid)
{
db.InsertEmpDetail(emp.FirstName, emp.LastName, emp.Address, emp.Salary);
db.SaveChanges();
ViewBag.Message = "New Employee Created Successfully!!";
}
}
return View(emp);
}
I have created the function InsertEmpDetail and mapped it properly.
I think if I dont remember it wrongly , when you map you entity, the orm entity framework will need to be able to read for the entity through certaion way. (sorry cant get to my net computer, but in java it often the same).
I'm guessing that your procedure have return result thus the will be read onto the entity.
another possibililty is the commit of the stored procedure, since it cant be read after insert properly, the column seems to be missing.
(just saying this have happen to me before)
good luck,
edd

asp net mvc oracle database fail to retrieve data

I have an Oracle DB set up, and the Database has a bunch of Views.
The view GFL_BUYERS_ID_V has 2 columns of EMPLOYEE_ID and FULL_NAME. The database is already filled before I created the mvc project.
I Add the database successfully and added the a schema modelBuilder.HasDefaultSchema("examplename."); to my context because when I use SQL to retrieve data, I need to do:
SELECT * FROM "examplename".GFL_BUYERS_ID_V
for it to work, I assume that is what it's for. Apologies in advance I am new to .net, mvc and connecting databases.
The following crashes at the .Select and tells me that value cannot be null (I have no clue what is returning a null value, if I inspect values in context->GFL_BUYERS_ID_V when it breaks, in Local there are 0 values, and in Result View it contains all the appropriate one's, I assume this is relevant info but I don't know how to use it):
var model = new EmployeeModel();
using (var context = new OracleContext())
{
model.Buyers = context.GFL_BUYERS_ID_V.Select(s => new EmployeeModel.Buyer
{
BuyerId = s.EMPLOYEE_ID,
FullName = s.FULL_NAME
}).ToList();
}
return View(model);
this is my object:
public class EmployeeModel
{
public int EmployeeModelId { get; set; }
public List<Buyer> Buyers { get; set; }
public class Buyer
{
public int BuyerId { get; set; }
public string FullName { get; set; }
}
}
I know there is a connection to the database and I can query it via VB. I have fiddled enough with the connection string to know it is correct.
Edit: Scratch that I have no clue if my program is able to connect to the Database or not.
Screen shot of the error
If you would like me to provide more information, I will be happy to, really want to make this one work.
Edit 2: This seems like some sick joke clearly it shows a count: how
Is there an inner exception which is causing the ArgumentNullException?
You are definitely thinking along the right path, so I would break it down into manageable pieces:
1) confirm DB connectivity
2) confirm context is valid, which would most likely only be invalid if no DB connectivity
3) confirm GFL_BUYERS_ID_V is showing data
4) then do the projection to a different model
So the problem was in the Database server not the code. For some reason it used an old default schema variable that wasn't used for a long time.

Asp.net core MVC post parameter always null

I am new to MVC core.
I have created a project with MVC core which has a controller. This controller has Get and Post action methods. If i pass data to Get method using query string it works fine, but when i pass complex JSON to post method, then it always shows me null.
Here what i am doing:
Post Request
URL: http://localhost:1001/api/users
Content-Type: application/json
Body:
{
"Name":"UserName",
"Gender":"Gender of the user",
"PhoneNumber":"PhoneNumber of the user"
}
Here is the Post action method
[HttpPost]
[Route("api/users")]
public async Task<IActionResult> Post([FromBody]User newUser)
{
...
}
When post request is called, then newUser always shows me null. And if i remove [FromBody] attribute then i receive newUser object but all of its fields are null.
Please help me and guide me in this issue.
EDITED
Here is my User class
public class User{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string PhoneNumber { get; set; }
}
I had done same as described here for json data, but still receives null.
This could be because of how the null values are being handled. Set NullValueHandling to Ignore in AddJsonOptions and see if that works.
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddJsonOptions(jsonOptions=>
{
jsonOptions.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
});
}
Note the original method Post([FromBody] User newUser)
For future readers from google, this same issue could arise if the method was Post(User newUser)
Note the lack of [FromBody]. This is a departure from previous versions of MVC where these parameters were generally inferred.
If you're an existing MVC5 developer who finds this page regarding AspNetCore.MVC, make sure to double check that you have [FromBody] decorated where relevant.
I created new ASP.NET Core project, added your functionality, and it works. Please, checkout this project on github.
Also, see screenshot of log with simple communication with this controller from browser console: Console output
Are you on Microsoft.AspNetCore.Mvc 1.0.0?
If you are, try sending this object as your body in a request (camel cased properties):
{
"name":"UserName",
"gender":"Gender of the user",
"phoneNumber":"PhoneNumber of the user"
}

Sitecore PageEditor randomly shows error with Glass.Mapper

I sometimes receive an error when I open a page in page editor mode on my Sitecore site using Glass.Mapper.
You cannot save a class that does not contain a property that
represents the item ID. Ensure that at least one property has been
marked to contain the Sitecore ID. Type:
Castle.Proxies.IBasicPageProxy
at Glass.Mapper.Sc.Configuration.SitecoreTypeConfiguration.ResolveItem(Object
target, Database database)
at Glass.Mapper.Sc.GlassHtml.MakeEditable[T](Expression'1 field, Expression'1 standardOutput, T model, Object parameters,
Context context, Database database, TextWriter writer)
This appears in the place of the rendering, so it doesn't show up as a standard ASP error.
Restarting IIS solves this, but soon it appears again..
I use interfaces for model definitions, with every single interface inheriting from IBaseType:
[SitecoreType]
public interface IBaseType
{
[SitecoreId]
Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Name)]
string Name { get; set; }
[SitecoreItem]
Item InnerItem { get; set; }
[SitecoreInfo(SitecoreInfoType.Url)]
string Url { get; set; }
[SitecoreInfo(SitecoreInfoType.TemplateId)]
Guid TemplateId { get; set; }
[SitecoreInfo(SitecoreInfoType.FullPath)]
string FullPath { get; set; }
}
I use Sitecore 7.5 rev. 141003 (.NET 4.5, MVC5), and the latest versions of Glass.Mapper related NuGet packages currently:
Castle.Windsor 3.3.0
Castle.Core 3.3.3
Glass.Mapper 3.0.14.26
Glass.Mapper.Sc 3.2.3.46
Glass.Mapper.Sc.CastleWindsor 3.3.0.24
Glass.Mapper.Sc.Mvc-5 3.3.0.43
The issue appears on all machines we tried, but all of them uses Windows 8, IIS 8.5.9600. I tried reverting to the WebActivator method, but it didn't help. Model definitions are in a separate class library project, which references all glass mapper assemblies.
I'm pretty clueless, never run into this error before on other projects. Does anyone have any idea what can cause this, or how I could debug it?
Thank you for your help!
I have put below code in my model and it works
[SitecoreId]
public virtual Guid Id { get; set; }
Glass mapper requires Item to be represented by a ID. If the glass model does not have a property for GUID, you will see this error.
You can fix this by adding the property public virtual GUID Id {get; set;} to your glass model

Initialising configurable objects with dependency injection container

I am trying to find the best way to initialise device drivers (maintained by production staff). Configuration generally contains serial ports and other information which production staff may need to change if the underlying hardware for the device driver changes.
e.g.
using System.IO.Ports;
public class Scanner : IDriver
{
public SerialPort SerialPort { get; private set; }
public String Id { get; private set; }
public String DisplayName { get; private set; }
public Scanner(SerialPort serialPort, String id, String displayName)
{
SerialPort = serialPort;
Id = id;
DisplayName = displayName;
}
}
public class TestMethod
{
public Scanner MainScanner { get; private set; }
public Scanner SecondaryScanner { get; private set; }
public TestMethod (Scanner main, Scanner secondary)
{
MainScanner = main;
SecondaryScanner = secondary;
}
}
How can I use a DI container and still make the configuration changeable at runtime? I would like to avoid using the XML configuration that comes with the DI containers as I expect the production staff to modify these (configuration) files often. A separate configuration file would be prefered.
A possible implementation of xml configuration
<DeviceDrivers>
<Driver name="main" id="IX234" displayName="main scanner">
<SerialPort name="serialPort" portName="COM8" baudRate="11560" parity="None" dataBits="8" stopBits="None">
</Driver>
<Driver name="secondary" id="IX2E3" displayName="secondary scanner">
<SerialPort name="serialPort" portName="COM9" baudRate="11560" parity="None" dataBits="8" stopBits="None">
</Driver>
</DeviceDrivers>
SerialPort itself need to be intialised from the configuration file.
Thanks
PS: I was considering Ninject, but not sure if I can pull this off.
First of all I have not worked on Ninject but have some idea about Unity. Secondly, I hope I understood your problem correctly that you would want the mentioned XML configuration for DeviceDrivers to go as a separate config file to which production staff will not have access.
So for the said scenario I think you would have to have two different mapping for IDriver to Scanner (both should preferably be named, say, 'Main' and 'Secondary') and in both you can specify initialization values for instances of SerialPort as also mentioned in your XML config. All these configuration will be part of a separate file that will be loaded to Unity container. To see how to load container with configuration from multiple config files please refer to http://msdn.microsoft.com/en-in/library/ff660935(v=pandp.20).aspx.

Resources