I'm currently writing a little application consisting of a mvc web api server and mvc 4 client, I've faced a problem, that is eating my mind for several days already.
I have a ContactsController, that contains:
[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"));
}
});
}
Model is derived from AuthorizationContent.
The post object method:
[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;
}
}
The method is about to call webapi controllers' method:
[AuthorizedOnly, HttpPost]
public void PostContact([FromBody]AuthorizationContent item, User authorizedUser)
{
var realItem = Mapper.Map<ContactModel, Contact>((ContactModel) item);
_contactService.AddContact(authorizedUser, realItem);
}
The filter:
[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();
}
}
}
The code works just fine for get actions, but when i am trying to do the post as shown above i'm always getting a server side exception stating
{StatusCode: 400, ReasonPhrase:
'Can't bind multiple parameters ('item' and 'authorizedUser') to the
request's content.', Version: 1.1, Content:
System.Net.Http.StringContent, Headers: { Content-Type: text/plain;
charset=utf-8 } }
The question - how can i state that authorizedUser will come from filter and model binder should NOT look for it in requests content?
Sorry for my bad english and thank you beforehand!