Asp.net web api发布动作参数

时间:2013-02-22 23:57:08

标签: c# c#-4.0 asp.net-mvc-4 asp.net-web-api action-filter

我目前正在编写一个由mvc web api服务器和mvc 4客户端组成的小应用程序,我遇到了一个问题,这已经困扰了我好几天了。

我有一个ContactsController,其中包含:

[HttpPost]
    public ActionResult AddContact(ContactModel model, HttpPostedFileBase image)
    {
        return ActionWrapper(() =>
        {
            if (model.InitializeFromCookie())
            {
                if (image != null)
                {
                    model.ImageMimeType = image.ContentType;
                    model.Picture = new byte[image.ContentLength];
                    image.InputStream.Read(model.Picture, 0, image.ContentLength);
                }

                PostObject("api/contacts/postcontact", model);
                RefreshCookie();
                return RedirectToAction("Contacts", "Contacts");
            }

            else
            {
                return JsonRedirectResult(Url.Action("Login", "Users"));
            }
        });
    }

模型源自AuthorizationContent。 post对象方法:

[NonAction]
        protected object PostObject(string apiUrl, object obj, object additionalData = null)
        {
            var query = additionalData != null ? additionalData.GetQueryString() : string.Empty;
            apiUrl += query;
            var action = _client.PostAsJsonAsync(apiUrl, obj);
            action.Wait();

            if (!action.Result.IsSuccessStatusCode)
            {
                var code = action.Result.StatusCode;
                var error = action.Result.ReasonPhrase;
                throw new ServerSideException(code, error);
            }

            else
            {
                return action.Result.Content.ReadAsAsync<object>().Result;
            }
        }

该方法即将调用webapi控制器的方法:

[AuthorizedOnly, HttpPost]
    public void PostContact([FromBody]AuthorizationContent item, User authorizedUser)
    {
        var realItem = Mapper.Map<ContactModel, Contact>((ContactModel) item);
        _contactService.AddContact(authorizedUser, realItem);
    }

过滤器:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
class AuthorizedOnly : ActionFilterAttribute
{
    private ISessionService _sessionService;
    private Session _userSession;

    public ISessionService SessionService
    {
        get { return _sessionService ?? (_sessionService = NinjectWebCommon.Kernel.Get<ISessionService>()); }
    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var auth = actionContext.ActionArguments.Values.FirstOrDefault() as AuthorizationContent;

        if (auth == null)
        {
            throw new UnauthorizedException();
        }

        else
        {
            var user = SessionService.GetMemberBySessionCredentials(auth.Token, auth.UserName);
            _userSession = user.Session;

            if (SessionService.IsSessionValid(_userSession))
            {
                actionContext.ActionArguments["authorizedUser"] = user;
                base.OnActionExecuting(actionContext);
            }

            else
            {
                throw new UnauthorizedException();
            }
        }
    }

代码适用于获取操作,但是当我尝试执行上面显示的帖子时,我总是得到服务器端异常说明

  

{StatusCode:400,ReasonPhrase:

     

'无法将多个参数('item'和'authorizedUser')绑定到   请求的内容。',版本:1.1,内容:   System.Net.Http.StringContent,Headers:{Content-Type:text / plain;   charset = utf-8}}

问题 - 如何声明授权用户将来自过滤器和模型绑定器不应该在请求内容中查找它? 抱歉我的英文不好,并事先感谢你!

1 个答案:

答案 0 :(得分:0)

你可以拥有一个空的参数绑定,除了说它不会从正文中读取之外什么都不做。请参阅此博客post,了解为什么只有一个参数可以读取Web API中的正文。您可以在全局配置中注册参数绑定,也可以为其定义属性。参数绑定的示例代码如下,

public class EmptyParameterBinding : HttpParameterBinding
{
    public EmptyParameterBinding(HttpParameterDescriptor descriptor)
        : base(descriptor)
    {
    }

    public override bool WillReadBody
    {
        get
        {
            return false;
        }
    }

    public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        return Task.FromResult(0);
    }
}