Do I need to add Async to my Controller Actions in Visual Studio 2017 ASP.NET Core MVC - asp.net-core-mvc

I just converted my Visual Studio 2015 ASP.NET MVC Core project to Visual Studio 2017...and I get the following Informational messages in my Error List
Message IDE1006 Naming rule violation: Missing suffix: 'Async'
This message occurs in my Controllers that focus on the following:
public async Task<IActionResult> Index()
This also applies to Create, Delete, Details and Edit. The messages show as Informational and applies to over 1,000 occurences in my project. It appears that I need to change Index to IndexAsync
ie.
Change from:
public async Task<IActionResult> Index()
public async Task<IActionResult> Create()
public async Task<IActionResult> Delete(int? id)
public async Task<IActionResult> Details(int? id)
Change to:
public async Task<IActionResult> IndexAsync()
public async Task<IActionResult> CreateAsync()
public async Task<IActionResult> DeleteAsync(int? id)
public async Task<IActionResult> DetailsAysnc(int? id)
This appears to be optional at this time as my project will Build and it's not an issue in VS 2015. I don't mind doing the work,I need confirmation that changing this in Visual Studio 2017 ASP.NET Core is the correct approach.

Microsoft is nudging you in the direction of suffixing your your asynchronous methods with the word async. Why? The release notes for Visual Studio 2017 mention this tidbit.
Task-like return types for async methods: This introduces the ability
to return any task-like type from an async method. Previously these
return types were constrained to Task<T> and Task.
Sounds like it's going to become less obvious which methods are asynchronous just from examining their return types. Suffixing them with async may be a good idea. Before VS was making this "suggestion" there was a previous stack overflow question debating the convention. Stephen Toub from Microsoft addressed it, and I quote.
If a public method is Task-returning and is asynchronous in nature (as
opposed to a method that is known to always execute synchronously to
completion but still returns a Task for some reason), it should have
an “Async” suffix. That’s the guideline. The primary goal here with
the naming is to make it very obvious to a consumer of the
functionality that the method being invoked will likely not complete
all of its work synchronously; it of course also helps with the case
where functionality is exposed with both synchronous and asynchronous
methods such that you need a name difference to distinguish them. How
the method achieves its asynchronous implementation is immaterial to
the naming: whether async/await is used to garner the compiler’s help,
or whether types and methods from System.Threading.Tasks are used
directly (e.g. TaskCompletionSource) doesn’t really matter, as that
doesn’t affect the method’s signature as far as a consumer of the
method is concerned.
Of course, there are always exceptions to a guideline. The most
notable one in the case of naming would be cases where an entire
type’s raison d’etre is to provide async-focused functionality, in
which case having Async on every method would be overkill, e.g. the
methods on Task itself that produce other Tasks.
As for void-returning asynchronous methods, it’s not desirable to have
those in public surface area, since the caller has no good way of
knowing when the asynchronous work has completed. If you must expose a
void-returning asynchronous method publicly, though, you likely do
want to have a name that conveys that asynchronous work is being
initiated, and you could use the “Async” suffix here if it made sense.
Given how rare this case should be, I’d argue it’s really a
case-by-case kind of decision.
I hope that helps, Steve
Bottomline, it's informational. But as Microsoft has expanded the return types beyond Task, it it beggining to look more and more like best practice. Use your own judgement.

I noticed that for MVC Controller classes, that in addition to adding Async to the method name, I needed to add [ActionName("MethodName")] as a method attribute where "MethodName" did not have Async at the end. If I didn't add the ActionName attribute, the code would compile, but the URL would not route to the method unless I added Async in the URL as well. I don't want Async in my URLs so I ended up adding ActionName attributes everywhere. It seems like the MVC routing engine should try to find the Async methods, but it doesn't.

Related

Why doesn't my Android ViewModel's Room RxJava3 Flowable publish any result when my Activity is paused?

I'm aware it's a complex question that cannot have a definite answer without posting a few hundreds of lines of code, which is why I'm looking for help through general ideas and pointers.
I have a Room #Query returning a RxJava3 Flowable<List<...>> which I subscribe to on RxJava thread Schedulers.io(), and observe from an activity-scoped ViewModel on RxJava thread AndroidSchedulers.mainThread(). The data is then stored in my ViewModel as LiveData, which plays better than RxJava when it comes to handle Android components' lifecycle.
The idea is to have a clean and immediate data update pattern, not to have to handle disposal and re-subscription separately on each activity or fragment lifecycle event such as onPaused and onResumed, and being updated in the background even when my activity is hidden in order to avoid that awful refresh lag when returning to my activity. I was pretty amazed at that design pattern. I still am, but I'm beginning to have doubts.
When starting another activity with the same design pattern, I do change a value and immediately get an updated List<...> from the other ViewModel. Different Activity, different ViewModel, same design, same database table. When returning to the first Activity, I find that the new data does never get updated: Room did not emit any update even though the data set has changed. I have to dispose and subscribe again in order to see the new data.
So my question is: any pointer on where the source of my problem might be?! Is there something rotten in the core of this design pattern? Something I misunderstood about all those things are supposed to work together? Is it just a mistake of mine due to some threading issue? Or should I fill a bug report for Room?
I tried to observe another non-Room RxJava3 observable from the ViewModel of my first Activity, and it does get updates when its data set is updated.
By the way, I also use Hilt in order to inject eveything as #Singleton.
Thank you for your time :-)
After a week of headaches, I have finally stumbled upon a solution, which happens to be clean and elegant.
The issue was RxJava, which, I just learnt, is not supposed to seamlessly handle multiple subscriptions to the same Observable. The solution is supposedly to make use of the publish(), connect(), refcount() operators, or better use the shortcut share(). I tried every way I could think of, without success (it actually made it worse). I also tried to subscribe() to the Room Flowable from my repository and proxy it through a BehaviorSubject.
There was this weird org.reactivestreams.Publisher in Room's documentation, whose added value I wouldn't know, and whose origin wasn't even my familiar io.reactivex.rxjava3. It turns out it that was the solution. Edit: It turns out Publisher is an interface that Flowable happens to implement.
build.gradle
implementation 'android.arch.lifecycle:reactivestreams:+'
Dao.java
#Query("...")
Flowable<List<...>> getFlowable();
ViewModel.java
public liveData;
#Inject
public ViewModel(#NonNull RoomDatabase roomDatabase) {
liveData = LiveDataReactiveStreams.fromPublisher(roomDatabase.dao().getFlowable());
}
It seems too easy to be true, but as far as I can see it seems to work perfectly better this way.
Edit:
It turns out the root of this issue was a slight little bit more vicious than I thought. I assumed #InstallIn(SingletonComponent.class) in my dependency injection #Module was enough, but apparently a #Singleton annotation on each #Provides method is also required.
#Module
#InstallIn(SingletonComponent.class)
public abstract class DependencyInjection
{
#Provides
#NonNull
#Singleton // do not omit this
public static DataDao provideDataDao(#NonNull RoomDatabase roomDatabase) {
return roomDatabase.dataDao();
}
#Provides
#NonNull
#Singleton // do not omit this
public static RoomDatabase provideRoomDatabase(#ApplicationContext Context applicationContext) {
return
BuildConfig.DEBUG ?
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").fallbackToDestructiveMigration().build() :
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").build() ;
}
}

Xamarin Async Constructor

For my application I need to fetch some data asynchronously and do some initialization for each page. Unfortunately, a constructor does not allow me to make asynchronous calls. I followed this article and put all of my code into the OnAppearing method. However, since then I ran into multiple issues since each platform handles the event a little bit differently. For example, I have pages where you can take pictures, on iOS the OnAppearing is called again every time after the camera is closed while Android doesn't. It doesn't seem like a reliable method for my needs, which is also described here:
Calls to the OnDisappearing and OnAppearing overrides cannot be treated as guaranteed indications of page navigation. For example, on iOS, the OnDisappearing override is called on the active page when the application terminates.
I am searching for a method/way where I can perform my own initialization. The constructor would be perfect for that but I cannot perform anything asynchronously in there. Please do not provide me with any work arounds, I am searching for a solution that is the "recommended" way or maybe someone with a lot of experience can tell me what they are doing. (I also don't want to .Wait() or .Result as it will lock my app)
You can use Stephen Cleary's excellent NotifyTaskCompletion class.
You can read more how it works and what to do/don't in these cases in Microsoft's excellent Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding. The highlights of this topics are:
Let’s walk through the core method
NotifyTaskCompletion.WatchTaskAsync. This method takes a task
representing the asynchronous operation, and (asynchronously) waits
for it to complete. Note that the await does not use
ConfigureAwait(false); I want to return to the UI context before
raising the PropertyChanged notifications. This method violates a
common coding guideline here: It has an empty general catch clause. In
this case, though, that’s exactly what I want. I don’t want to
propagate exceptions directly back to the main UI loop; I want to
capture any exceptions and set properties so that the error handling
is done via data binding. When the task completes, the type raises
PropertyChanged notifications for all the appropriate properties.
A sample usage of it:
public class MainViewModel
{
public MainViewModel()
{
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
}
public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
}
Here, the demo is about binding the returned asynchronous value to some bindable property, but of course you can you is without any return value (for simple data loading).
This may be too simple to say, but you CAN run asynchronous tasks in the constructor. Just wrap it in an anonymous Task.
public MyConstructor() {
Task.Run(async () => {
<Your code>
}
}
Be careful when doing this though as you can get into resource conflict issues if you accidentally open the page twice.
Another thing I like to do is use an _isInit flag, which indicates a first time use, and then never again.

ActionMethodSelectorAttribute equivalent in ASP.NET Web API?

Is there a Web API equivalent to the MVC ActionMethodSelectorAttribute?
My specific purpose is this: I have, for example, a ResourceController and when I POST to the controller, I'd like to be able to receive a single resource (Resource) or a list (IEnumerable<Resource>).
I was hoping creating two methods with different parameters would cause the deserialization process to do some evaluation but this doesn't seem to be the case (and frankly, I don't think it's efficiently realistic with the combination of content negotiation and the fact that many data formats, like JSON, make it difficult to infer the data type). So I originally had:
public HttpResponseMessage Post(Resource resource) {...}
public HttpResponseMessage Post(IEnumerable<Resource> resources) {...}
...but this gets the "multiple actions" error. So I investigated how to annotate my methods and came across ActionMethodSelectorAttribute but also discovered this is only for MVC routing and not Web API.
So... without requiring a different path for POSTing multiple resources vs. one (which isn't the end of the world), what would I do to differentiate?
My thoughts along the ActionMethodSelectorAttribute were to require a query parameter specifying multiple, which I suppose is no different than a different path. So, I think I just eliminated my current need to do this, but I would still like to know if there is an equivalent ActionMethodSelectorAttribute for Web API :)
I haven't seen a replacement for that method (there is an IActionMethodSelector interface but it is internal to the DLL). One option (although it seems like it might be overdoing it) is to overload the IHttpActionSelector implementation that is used.
But changing gears slightly, why not always expect an IEnumerable<Resource>? My first guess is that the collection method (that takes IEnumerable<Resource>) would simply loop and call the single value (just Resource) function?

Command Pattern in .NET MVC 3 (removing junk from the controller)

I am trying to implement this Command Pattern on my .NET MVC 3 application, specifically for saving edits to a Thing. I am undecided on how to proceed. Before I get to the actual question, here is the simplified code:
public class ThingController
{
private readonly ICommandHandler<EditThingCommand> handler;
public ThingController(ICommandHandler<EditThingCommand> handler)
{
this.handler = handler;
}
public ActionMethod EditThing(int id)
{
...build EditThingViewModel and return with View...
}
[HttpPost]
public ActionMethod EditThing(int id, EditThingViewModel vm)
{
var command = new EditThingCommand
{
...not sure yet...
};
this.handler.Handle(command);
...redirect somewhere...
}
}
My EditThingViewModel is wholly disconnected from my domain, which consists of POCO classes. It seems like my EditThingCommand should look like this:
public class EditThingCommand
{
Thing ModifiedThing;
}
However, building ModifiedThing would then still be happening in my controller. That's the majority of the work in this case. By the time ModifiedThing is built (and the "old" timestamp applied to it for optimistic concurrency checking), all that's left is for command to call Update on my data context.
Clearly there is value in being able to easily decorate it with other commands, but I'd also like to be able to move the construction of ModifiedThing outside of my controller. (Perhaps this question is really just about that.) EditThingCommand is in my domain and doesn't have a reference to EditThingViewModel, so it can't go there. Does it make sense to have another command in my presentation layer for mapping my viewmodel to my poco entity?
I created an EditThingPostCommand outside of my domain, which takes the EditThingViewModel as a parameter. The EditThingPostCommandHandler is responsible for creating the EditThingCommand and calling its handler.
It works, but I'm not going to assume that's the best answer to my question. Arguably most of what the EditThingPostCommandHandler is doing could be done in a custom AutoMapper configuration, which would still serve the purpose of cleaning up the controller action method.
After several months of using this pattern on other projects, it is apparent to me that the commands on this particular project were simply too general and therefore too complex, requiring too much setup. It would have been better to create, for example, an EditThingTitleCommand and a MoveThingPiecesCommand and so on, and call them from their own ActionMethods.
In other words, when using the command pattern, don't just use the commands as replacements for typical CRUD operations. With more specificity comes more benefit.

Is there a preferred way to resolve CA1062 for MVC controller actions?

Running code analysis on the following action results in a CA1062 warning, advising I validate the parameter before using it:
[HttpPost]
public ActionResult Index(SomeViewModel vm)
{
if (!ModelState.IsValid)
return View(vm);
// ... other code
return View(vm);
}
I realize I could resolve the warning by adding:
if(vm==null)
throw new ArgumentNullException("vm");
I was under the impression that if default model binding succeeded the incoming parameter could never be null and would not need to be validated beyond "ModelState.IsValid".
Is that the case?
Is there a widely accepted technique for addressing this warning for MVC actions?
It is a public method, so you shouldn't be making assumptions about who will be calling it. While one caller (the MVC framework) might only invoke the method with non-null values, other potential callers might not be quite so "polite".
That said, if your code does not have other potential callers (which wouldn't be unusual for an MVC application, as opposed to a library), allowing a NullReferenceException to be thrown instead of an ArgumentNullException might be perfectly acceptable. That would depend largely on your expectations for future use and maintainability of the code base. (Amongst other things, a future maintenance developer would probably find it easier to identify a problem if it's signalled via an ArgumentNullException.)
I think that the model parameter can be null during development when MVC is not able to do the mapping, but I suppose that it shouldn't during normal operation.
In my opinion it is not bad to check your parameter as the warning points out.

Resources