Save methods and results - c#

I currently have a method to save a user.
public PersonDto Save(PersonDto personDto)
However, if, while saving, I find there is a duplicate username, or some other issue with the data - my only way to respond to this is to throw an exception.
throw new Exception("Username exists");
I have read that exceptions shouldn't be used for 'Business Requirement Transgressions'.
Is there a better way to return results to my calling methods? I need to return to PersonDto, but also, some information about any issues. Is there a common practice or model for doing this? Maybe return a 'SaveResult' object, which contains a Object SavedObject (in this case, my PersonDto), as well as some other properties like string SaveResult and bool Success?

Maybe implement a generic wrapper for use with all such requests.
enum Disposition
{
OK,
Warning,
Error
}
class Response<T>
{
public T Result { get; set; }
public Disposition Disposition { get; set; }
public string Message { get; set; }
}
i.e.:
public Response<PersonDto> Save(PersonDto personDto)
This way you can specify some metadata for each of your return values.

I recommend using a SaveResult approach to your problem e.g.
public class SaveResult
{
public PersonDto { get; set; }
public bool Success { get; set; }
public string ErrorMessage { get; set; }
}
var result = Save(person);
if (!result.Success)
{
Console.WriteLine(result.ErrorMessage);
}
Or something like that. This will allow you to pass back the PersonDto, but also signal to the API caller that an error occurred when trying to save.
There's nothing really wrong with throwing an exception, but as you also want to return the person DTO, then you might as well use a specific method return type for that purpose.

Related

Exception handling in GRPC - return common object

I googled a lot C# articles how to proceed with that with interceptors. I can divide them on 2 types:
Rethrow RPCException
return default
My problem, i want to return back some common API response object.
public class GrpcResponseBase
{
public int StatusCode { get; set; }
public string ErrorMessage { get; set; }
}
public class GrpcResponse<TData> : GrpcResponseBase
{
public TData Data { get; set; }
...
}
So all the objects i return to client need to be based on that. And the object returned from exception handler too.
But that's the problem. The response objects are autogenerated by protobuf compiler from proto files. Proto doesn't support inheritance, and i don't want to copy-paste those 2-3 fields each time for each "message". And i think it doesn't support generics too.
What can i do ? Maybe don't use interceptors, but use something else ? Please suggest

Designing Viewmodels and avoid if else statements in controllers and write good business logic asp.net web api using design patterns

I have a web api action method which takes below Model as parameter (Post).
public class RequestModel
{
public string PartType { get; set; }
public int Quantity { get; set; }
public decimal UnitCost{ get; set; }
public bool? Owner { get; set; }
public bool? DoSplit { get; set; }
}
The options Owner/Do Split will be choosen by the user on UI and its based on Part Type. Also based on the Owner flag there is some other business logic which needs to be executed in combination with the DoSplit and Quantity. Hence I have many permuations and combinations. Going bruteforce the logic would go this way:
int existingQty = GetInitialQuantity(model.SerialId); //returns esisting qty
if(existingQty < model.Quantity && model.Owner)
{
// logic here
}
else if (existingQty < model.Quantity && model.Owner == false)
{
}
else if (existingQty = model.Quantity) // no need to check for DoSplit
{
}
etc..... more if else in combincation with qty comaprison, Dosplit and owner flag checks with null checks.
based on the different property values in the model (in combination) I need to do different actions. How to avoid if else and use a proper design patterns of C# here.
Since the model is passed from javascript through a web api call to my action method how can I use OOPs here for the requestmodel and avoid branching in the controller method ?
I think one of the main reasons that you have so much if/else is that you do not have the business logic in the object itsel but try to use the business logic from outside. As I do not get what your business logic is, my implementation might not work on your case, but i want to show you how to get rid of the if else in a simple case. The main goal is to not use the properties but only use the functions and let the object handle its state on its own. (lookup Tell dont ask and State Pattern)
lets look at this class
public class User
{
string name { get; set; }
bool isDisabled { get; set; }
}
using it might be like this
if (!user.isDisabled)
{
user.name = nameFromApi
}
but in this case you have to repeat this on every corner where you want to use the User. So consider this
public interface IUser
{
string name { get; }
IUser updateName(string newName);
IUser disableUser();
}
public class DisabledUser : IUser
{
public DisabledUser(IUser activeUser)
{
this.name = activeUser.name;
}
public string name { get; }
public IUser updateName(string newName)
{
return this;
}
public IUser disableUser()
{
return new DisabledUser(this);
}
}
public class ActiveUser : IUser
{
public ActiveUser(IUser user)
{
this.name = user.name;
}
public string name { get; private set; }
public IUser updateName(string newName)
{
this.name = newName;
return this;
}
public IUser disableUser()
{
return new DisabledUser(this);
}
}
In this way the if is gone and you actually gained something else: You can easily extend the implementation with other states like banned and you do not have to change the old implementation. Yes, it is more code, but way easier to maintain.
In you case i think you should be able to get rid of all the if/elses regarding the boolean flags, if you initialize the objects correctly. This is a powerfull pattern and you do not need to cast anything to be able to use the user.
I do not know your usecase for the quantity stuff, so I can not tell you how this might get resolved, but there is certainly a way to do that.

JSON Deserialization in .NET

I've had a look at a few threads but what I'm aiming for I can't seem to find.
I have the following JSON strings returned:
On success:
{"success":{"username":"key"}}
On Error:
{"error":{"type":101,"address":"/","description":"link button not pressed"}}
I need to be able to de-serialize these into a class and determine whether I've got an error or a success message to carry on doing it. Any ideas on how to achieve this?
thanks,
Adam
No need to declare a lot of tiny classes. dynamic keyword can help here.
dynamic jObj = JObject.Parse(json);
if (jObj.error!= null)
{
string error = jObj.error.description.ToString();
}
else
{
string key = jObj.success.username.ToString();
}
One option is to use http://nuget.org/packages/newtonsoft.json - you can either create your own custom class to deserialize into or use dynamic as the target type.
var result = JsonConvert.DeserializeObject<Result>(jsonString);
class Result
{
public SuccessResult success { get; set; }
public ErrorResult error { get; set; }
}
class SuccessResult
{
public string username { get; set; }
}
class ErrorResult
{
public int type { get; set; }
public string address { get; set; }
public string description { get; set; }
}
If you need just to check for success, it is possible to just check result.StartsWith("{\"success\":") to avoid unnecessary parsing. But this should only be done if you have guarantee that the JSON string will always be exactly like this (no extra whitespaces etc.) - so it is usually only appropriate if you own the JSON generation yourself.
This answer covers most options, including rolling your own parser and using JSON.Net:
Parse JSON in C#
You could also just write a regex if the format is going to be that simple...

Can ServiceStack services contain multiple methods?

Environment is Visual Studio 2012, ServiceStack, ASP.NET Web Application Project (followed https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webservice)
Looking through some of the classes in ServiceStack.Examples, I noticed that most of the services contain only one method. Either some override on Execute() or, if a REST service, some override of OnPost/Get/Put/Delete().
How should I approach making a full API set, if I have tens of functions I need implemented RegisterUser(), RemoveUser(), AddFriend(), RemoveFriend() ... One service per method?
public RegisterUserService : IService<User> { public object Execute(User> dto) { ... } }
public RemoveUserService : IService<User> { public object Execute(User> dto) { ... } }
public AddFriendService : IService<Friend> { public object Execute(Friend dto) { ... } }
public RemoveFriendService: IService<RequestDTO4> { public object Execute(Friend dto) { ... } }
I'm pretty lost on how to begin implementing a full API set. I've read the first and second wiki page on 'Creating your first webservice', which I've copied to make 1 service method. But now I want to make 10 or 40 service methods and I'm not sure how to do that.
I noticed that implementing from IRestService<T> allows you up to 4 methods instead of the one Execute() method, simply because each method corresponds to a different HTTP verb. So is there something like that I could write? Basically something like:
public MyService : IService/IRestService/ServiceBase?<User>
{
public object AddUser(User user) { }
public object RemoveUser(User user) { }
public object ModifyUser(User user) { }
}
Just looking for something that doesn't necessarily have to contain all methods in one service class, but as many as reasonably possible ... do I really have to create 1 service for each service method?
Note on pursuing a strictly RESTful architecture: I only read up a little on REST, but it seems like I'd have to strictly follow rules like: treat everything as a resource even if you have to re-design your models, no verbs in the URL names (/Friends, not /GetFriends because REST gives you OnGet(), OnPost(), OnPut(), and OnDelete() ... basically I'm interested in the easiest, quickest, and most painless way of implementing a a few dozen service methods. It's a personal project, so the requirements won't vary too much.
Thanks in advance for guiding me through this first step.
EDIT: Just saw this related question: How to send commands using ServiceStack?
Mythz said there's no "ServiceStack way" to design. The guy's question is pretty much like mine. I'm wondering how to stack a lot of service methods in a service.
EDIT 2: Just saw Need help on servicestack implementation, and Separate or combined ServiceStack services?.
I just tested the code below successfully with working routes:
[Route("/registerUser/setEmail/{Email}")]
[Route("/registerUser/setPassword/{Password}")]
[Route("/registerUser/setPhoneNumber/{PhoneNumber}")]
[Route("/lalal2395823")]
[Route("/test3234/test23423511")]
public class RegisterUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Nickname { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
But what I'd like is for each [Route("path")] to go to a different method, instead of having them all parsed in Execute() and having to parse which string isn't null or empty.
My Solution
I decided to take Rickard's advice and make a proper REST API, because it seems simpler and cleaner in the end.
This is now my class using the new ServiceStack API (new as of 9/24/12):
using UserModel = Project.Model.Entities.User;
[Route("/User", "POST")]
[Route("/User/{FirstName}", "POST")]
[Route("/User/{FirstName}/{LastName}", "POST")]
[Route("/User/{FirstName}/{LastName}/{Nickname}", "POST")]
[Route("/User/{FirstName}/{LastName}/{Nickname}/{PhoneNumber}", "POST")]
[Route("/User/{FirstName}/{LastName}/{Nickname}/{PhoneNumber}/{Email}", "POST")]
public class CreateUser : IReturn<UserModel>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Nickname { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
public class CreateUserService : Service
{
public object Post(CreateUser request)
{
try
{
using (var session = FluentNHibernateHelper.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var user = new UserModel()
{
FirstName = request.FirstName,
LastName = request.LastName,
Nickname = request.Nickname,
PhoneNumber = request.PhoneNumber,
Email = request.Email,
Password = request.Password,
};
session.SaveOrUpdate(user);
transaction.Commit();
return user;
}
}
}
catch
{
throw;
}
}
}
This is now a lot simpler with ServiceStack's new API Design released in (v3.9.15+).
#Rickard makes a lot of good points on how to re-structure your service so it's more REST-ful which is now easier to achieve with ServiceStack's new API which is now less restrictive and more flexible where the same service can handle multiple different Request DTOs and you're no longer restricted in the Response Type you can return.
Following the HTTP way you have to turn your way of thinking upside down. You need to think in terms of resources, i.e. users, friends, etc. Using HTTP you already have a finite set of methods, namely Get, Put, Post, and Delete.
Hence, the service API design could look like this:
RegisterUser() => POST /users
RemoveUser() => DELETE /users/{userid}
AddFriend() => POST /users/{userid}/friends
RemoveFriend() => DELETE /users/{userid}/friends/{friendid}
ModifyUser() => PUT /users/{userid}
etc.
To implement for example RemoveFriend in ServiceStack you could do like this:
public class UserFriendService : RestServiceBase<UserFriendRequest>
{
public override object OnPost(UserFriendRequest request)
{
// pseudo code
var user = GetUser(request.UserId);
var friend = GetUser(request.FriendId); // FriendId is a field in the HTTP body
user.Friends.Add(friend);
return HttpResult.Status201Created(user, ...);
}
//...
}
[Route("/users/{userId}/friends")]
public class UserFriendRequest
{
public string UserId { get; set; }
public string FriendId { get; set; }
}

IDataErrorInfo with complex types

I have an Address object defined simply as follows:
public class Address
{
public string StreetNumber { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
Fairly simple. On the advice an answer to another question I asked, I am referring to this blog post when databinding my UI to an object of type Person (which contains an Address MailingAddress field).
The problem is that the IDataError interface method isn't validating any of the properties of the Address type.
public string this[string columnName]
{
get
{
string result = null;
// the following works fine
if(columnName == "FirstName")
{
if (string.IsNullOrEmpty(this.FirstName))
result = "First name cannot be blank.";
}
// the following does not run
// mostly because I don't know what the columnName should be
else if (columnName == "NotSureWhatToPutHere")
{
if (!Util.IsValidPostalCode(this.MailingAddress.PostalCode))
result = "Postal code is not in a know format.";
}
return result;
}
}
So, obviously I don't know what the columnName will be... I've stepped through it and it has never been anything other than any of the public properties (of intrinsic types). I've even tried running and breaking on a statement like:
if (columnName.Contains("Mailing") || columnName.Contains("Postal"))
System.Windows.Forms.MessageBox.Show(columnName);
All to no avail.
Is there something I'm missing?
You need to define IErrorInfo on all the classes that you want to supply error messages for.
Take a look at my answer here.
This explains how to use a modelbinder to add 'class-level' checking of your model without having to use IDataError - which as you have seen here can be quite clumsy. It still lets you use [Required] attributes or any other custom validation attributes you have, but lets you add or remove individual model errors. For more on how to use data annotations I highly recommend this post from Scott Gu.

Categories

Resources