Attempting ValidationAttribute in MVC4 that is asynchronous using Async, Task and Await

ⅰ亾dé卋堺 提交于 2020-05-15 03:35:25

问题


I am attempting to write a Validation attribute in MVC4. The purpose is to check for the existence of an application reference (just a string that represents a key I wish to prevent a duplicate for). My data is accessed via WebAPI and because I am using 4.5 I wish to make this asynchronous if possible.

I am perhaps not making the best or appropriate usage of async and await but I would like to know how to call my async method from the overridden IsValid method of the inherited Validation class.

public class UniqueApplicationReferenceAttribute : ValidationAttribute
{
    public UniqueApplicationReferenceAttribute() : base(() => "The {0} already exists") { }

    public int? ApplicationCount { get; set; }

    public override bool IsValid(object value)
    {
        var myTask = GetApplicationRefCountAsync();

        myTask.Wait();

        this.ApplicationCount = this.ApplicationCount ?? 0;

        if (ApplicationCount > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    public async Task GetApplicationRefCountAsync()
    {
        HttpClient client = new HttpClient();

        client.BaseAddress = new Uri("http://localhost:11111/");
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

        var apps = client.GetStringAsync("api/dataapplications");

        await Task.WhenAll(apps);

        var appList = apps.Result;

        this.ApplicationCount =  appList.Count();// apps.Count();
    }
}

Many thanks, Dan.


回答1:


I recommend that you call your WebAPI methods synchronously. ValidationAttribute does not support asynchronous implementations natively, so any synchronous-over-asynchronous code you'll write is just going to be a hack and not actually provide any benefit as compared to the synchronous version.




回答2:


I'm not able to test this in full, but you should be able to do something like this:

public bool IsValid(object value)
{
    var appCount = GetApplicationRefCountAsync().Result;
    return appCount > 0;
}

public async Task<int> GetApplicationRefCountAsync()
{
    var client = new HttpClient();

    client.BaseAddress = new Uri("http://localhost:11111/");
    client.DefaultRequestHeaders.Accept.Add(
        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

    return await client.GetStringAsync("api/dataapplications")
        .ContinueWith(r => Convert.ToInt32(r))
        .ConfigureAwait(false);
}

Be careful about using async/await methods in an ASP.NET thread. It's easy to create deadlocks.



来源:https://stackoverflow.com/questions/18707228/attempting-validationattribute-in-mvc4-that-is-asynchronous-using-async-task-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!