ASP.NET index page with search posting into partial view - asp.net

I have an Index page with a search box (straight from this tutorial: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application) to which I've added a Create form in the footer, which I display as a partial view.
Although the Create form works well and adds new records, the search form seems to post back the Create Form instead, causing a validation error, and redisplaying the whole layout.cshtml page within the location of my partial view.
Edit - the search form posts itself and returns the correct result and then seems to post my partial view as well. My debugger shows the controllers ActionResult Create HTTP post function being called
How do I get the Search form to stop also posting into my partial view?
My index.cshml:
#using (Html.BeginForm("Index"))
{
<p>
#Html.TextBox("SearchString", ViewBag.CurrentFilter as string, new { #class = "search-query", placeholder = "Search by name" })
<input type="submit" value="Search" class="btn" />
</p>
}
#Html.Action("Create");
My Create.cshtml:
#using (Html.BeginForm("Create"))
{
#Html.TextBoxFor(model => model.Title, new { #style = "width:250px" })
#Html.TextBoxFor(model => model.AnnouncementText, new { #style = "width:250px" })
<input type="submit" value="Create" class="btn btn-small" />
#Html.ValidationMessageFor(model => model.Title)
#Html.ValidationMessageFor(model => model.AnnouncementDate)
}
My controller:
public ViewResult Index(string searchString, int? page)
{
var Announcements = from a in db.Announcements
select a;
if (!String.IsNullOrEmpty(searchString))
{
ViewBag.Search = true;
Announcements = Announcements.Where(s => (s.Title.ToUpper().Contains(searchString.ToUpper()) || s.AnnouncementText.ToUpper().Contains(searchString.ToUpper())));
}
Announcements = Announcements.OrderBy(s => s.Title);
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(Announcements.ToPagedList(pageNumber, pageSize));
}
public ActionResult Create()
{
Announcement announcement = new Announcement();
return PartialView(announcement);
}
//
// POST: /Announcement/Create
[HttpPost]
public ActionResult Create(Announcement announcement)
{
if (ModelState.IsValid)
{
db.Announcements.Add(announcement);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(announcement);
}

One possible solution is to use ajax to post a partial back to the view without a full page reload. If you use Ajax.BeginForm{} then your controller can return your partial as html as a model property and then you just load the content on the Ajax.BeginForm's successFunction. I use the method below in a base controller class as I often return partial content in views.
Model...
public class BaseEditModel
{
public string PostAction{get;set;}
public string PostController{get;set;}
public string PartialViewContent{get;set;}
}
Controller...
public ActionResult(int someID)
{
BaseEditModel model=new BaseEditModel();
model.PostController="SaveController";
model.PostAction="SaveEntity";
model.PartialViewContent=this.RenderPartialViewToString("Partials/Entity/EntityEdit", model);
}
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
View...
#using(Ajax.BeginForm(
Model.PostAction,
Model.PostController,
null,
new AjaxOptions { OnSuccess = "editPostSuccess", OnFailure = "editPostFailure" },
new { id = "editBase_frmEdit", name = "editBase_frmEdit" }))
{
}
<script type="text/javascript">
function editPostSuccess(ajaxContext) {
if (ajaxContext.PartialViewContent != null)
$('#partialDiv').html(ajaxContext.PartialViewContent);
}

I still don't entirely understand what caused the problem, but I fixed it by renaming the Create Post method to CreatePost. When the GET and POST methods both had the same name, for some reason the POST was being called.
My create.cshtml
#using (Html.BeginForm("CreatePost"))
Thanks all for your help

Related

Get checked checkbox MVC5

I have searched some articles but none of them fits with my problem. i have this code in my cshtml
#model IEnumerable<MonitoreoIntegrado.Models.Sensores>
#using (Html.BeginForm("Graphics", "Datos_extensometro", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<div style="margin:0; padding:0; border:none; position:absolute; bottom:5px; right:25px;"><input type="submit" id="enviar" class="btn btn-primary" value="Consultar"></div>
<div style="float:left; width:428px; height:105px; padding:5px; overflow-y: scroll;">
<h4 style="margin-top:0px;">Consultar multiples sensores</h4>
#foreach (var item in Model)
{
#Html.CheckBox("sensoresCB", false, new { value = #item.idSensor.ToString() }) #item.nombre <a class="moverse" objetivo="#(item.idSensor)" href=""><span class="glyphicon glyphicon-map-marker" title="Ir al marcador"></span></a><br />
}
</div>
}
and this in my controller:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics()
{
return View();
}
I need help to receive that checkboxes in my controller and check which of them are checked
You should use unique id's for your inputs. The easiest way:
#for (var i = 0; i < Model.Count(); i++)
{
#Html.CheckBox("sensoresCB["+i.ToString()+"]", false, new { value = Model[i].idSensor.ToString() })
//your other stuff
}
And on controller side:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics(bool[] sensoresCB) //note this
{
return View();
}
So you got the array with your selections. Use index to understand what checkbox it is.
You could extend the model of item with a Checked property or similar.
public class GraphicsViewModel {
public GraphicsItemViewModel[] Items { get; set; }
}
public class GraphicsItemViewModel {
public bool Checked { get; set; }
public long IdSensor { get; set; }
}
Then you can render the checkbox with a binding to this Checked property.
#model GraphicsViewModel
#using (Html.BeginForm(/* ....*/) {
// use a for loop so the array is bound correctly
#for (int i = 0; i < Model.Items.Length; i++) {
#Html.CheckBoxFor(m => m.Items[i].Checked)
// post back IdSensor value so we can access it in the controller
#Html.HiddenFor(m => m.Items[i].IdSensor)
}
}
Your controller should accept a model for the POST data, you can reuse the ViewModel:
[HttpPost]
public ActionResult Graphics(GraphicsViewModel postData) {
bool areAllChecked = postData.Items.All(i => i.Checked);
bool isFirstChecked = postData.Items.First().Checked;
bool isCertainIdChecked = postData.Items.Single(i => i.IdSensor == 1337).Checked;
// ...
}
I would like to mention a helpful point here, that is
If a checkbox is checked, then the postback values will contain a
key-value pair of the form [InputName]=[InputValue]
If a checkbox is not checked, then the posted form contains no
reference to the checkbox at all.
So in a controller action method, you can use the name of the checkbox and get the values which is only checked
ex:
public ActionResult Graphics(bool[] sensoresCB)
{
return View();
}
Hope above information was helpful
Thanks
Karthik
Based on #teo van kot reply I achieved to recover the checkboxes values. This is my working code.
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics(int[] sensoresCB)//you can receive a string[] as well
{
//code and stuff
return View();
}
View:
#model IEnumerable<MonitoreoIntegrado.Models.Sensores>
#using (Html.BeginForm("Graphics", "Datos_extensometro", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
//some code stuff
#{
int i = 0;
foreach (var item in Model)
{
#Html.CheckBox("sensoresCB[" + i.ToString() + "]", false, new { value = item.idSensor.ToString() }) #item.nombre<br />
i++;
}
}
}

EditorForMany not working for objects deeper than 1 level

I have an example asp.net mvc5 program in which I'm trying to build a payment model with many levels of partials added to make a complete object. In this example, I am using generic data. I have a top level 'testing', to which you can add multiple 'A1' objects, and to that you can add multiple 'B2' objects.
The form uses ajax and jqueryto allow the person to add data on the fly, which is then submitted all at once when the submit button is pressed.
I found an html helper made by Matt Lunn that does an editorForMany. It works very well, adds all my info to the web page, but it will never post back a model that is deeper than 2 levels(top, with a1's attached).
I can get the entire model to build on my page. It looks appropriate, but when I post back, nothing under A1 shows up. I can add as many 'A1's as I want. If I change the code and put 'B2's directly under testing, that will work, but nothing will add under the 'A1's as I have it.
Here is my code. I apologize for the formatting and the length of this post.
MVC helper
public static MvcHtmlString EditorForMany<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TValue>>> propertyExpression, Expression<Func<TValue, string>> indexResolverExpression = null, bool includeIndexField = true) where TModel : class
{
var items = propertyExpression.Compile()(html.ViewData.Model);
var htmlBuilder = new StringBuilder();
var htmlFieldName = ExpressionHelper.GetExpressionText(propertyExpression);
var htmlFieldNameWithPrefix = html.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName);
Func<TValue, string> indexResolver = null;
if (indexResolverExpression == null)
{
indexResolver = x => null;
}
else
{
indexResolver = indexResolverExpression.Compile();
}
foreach (var item in items)
{
var dummy = new { Item = item };
var guid = indexResolver(item);
var memberExp = Expression.MakeMemberAccess(Expression.Constant(dummy), dummy.GetType().GetProperty("Item"));
var singleItemExp = Expression.Lambda<Func<TModel, TValue>>(memberExp, propertyExpression.Parameters);
if (String.IsNullOrEmpty(guid))
{
guid = Guid.NewGuid().ToString();
}
else
{
guid = html.AttributeEncode(guid);
}
if (includeIndexField)
{
htmlBuilder.Append(_EditorForManyIndexField<TValue>(htmlFieldNameWithPrefix, guid, indexResolverExpression));
}
htmlBuilder.Append(html.EditorFor(singleItemExp, null, String.Format("{0}[{1}]", htmlFieldName, guid)));
}
MvcHtmlString m1 = new MvcHtmlString(htmlBuilder.ToString());
return m1;
}
testing Controller
public class testingController : Controller
{
// GET: testing
public ActionResult startTest()
{
var model = new testing();
return View(model);
}
[HttpPost]
public ActionResult startTest([Bind] testing model)
{
if (ModelState.IsValid)
{
var r = 1;
}
return View(model);
}
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult addA1()//current running test
{
var model = new testing();
model.aas.Add(new A1());
return View(model);
}
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult addB2()//current running test
{
var model = new A1();
model.bbs.Add(new B2());
return View(model);
}
}
model class
public class testing
{
public string name { get; set; }
public List<A1> aas { get; set; }
public testing()
{
aas = new List<A1>();
}
}
public class A1
{
public string aName { get; set; }
public List<B2> bbs { get; set; }
public A1()
{
bbs = new List<B2>();
}
}
public class B2
{
public string bName { get; set; }
public B2() { }
}
startTest.cshtml
#model proofOfConceptPaymentBuilder.Models.testing
#{
ViewBag.Title = "startTest";
}
#section Scripts
{
<script>
jQuery(document).ready(function ($) {
$('#add-bbs').on('click', function () {
jQuery.get('/testing/addB2').done(function (html) {
$('#bbsList').append(html);
});
});
$('#add-aas').on('click', function () {
jQuery.get('/testing/addA1').done(function (html) {
$('#aasList').append(html);
});
});
});
function alertSomething() {
alert('something');
jQuery.get('/testing/addB2').done(function (html) {
$('#bbsList').append(html);
});
};
</script>
}
#using (Html.BeginForm())
{
<h2>Create</h2>
#Html.EditorFor(x => x)
<input type="submit" />
}
EditorTemplates
(testing editor template)
#model proofOfConceptPaymentBuilder.Models.testing
<div class="form-group">
#Html.LabelFor(x => x.name)
#Html.EditorFor(x => x.name)
</div>
<div class="form-group">
<div id="aasList">
#Html.EditorFor(x => x.aas)
</div>
<input type="button" id="add-aas" value="add aas" />
<input type="button" id="delete-testing" value="delete test" />
</div>
(a1 editor template)
#model proofOfConceptPaymentBuilder.Models.A1
<div class="form-group">
#Html.LabelFor(x => x.aName)
#Html.EditorFor(x => x.aName)
</div>
<div class="form-group">
<div id="bbsList">
#Html.EditorForMany(x => x.bbs)
</div>
<input type="button" id="add-bbs" value="add bss" onclick="alertSomething()"/>
<input type="button" id="delete-aas" value="delete ass" />
</div>
(b2 editor template)
#model proofOfConceptPaymentBuilder.Models.B2
<div class="form-group">
#Html.LabelFor(x => x.bName)
#Html.EditorFor(x => x.bName)
</div>
<div>
<input type="button" id="delete-bss" value="delete bbs" />
</div>
addA1.cshtml
#model proofOfConceptPaymentBuilder.Models.testing
#{
Layout = null;
}
#Html.EditorForMany(x => x.aas)
addB2.cshtml
#model proofOfConceptPaymentBuilder.Models.A1
#{
Layout = null;
}
#Html.EditorForMany(x => x.bbs)
Ok, so I'm sorry for the formatting. I'm kinda new to the formatting here. I had to manually indent my code for it to show up in code blocks.
I also stumbled upon this problem and, given the number of questions I have found here in StackOverflow dealing with similar problems, I have created a .NET Core library to solve exactly this. It is called DynamicVML (Dynamic View-Model Lists) and you can get it with NuGet.
It is basically a list templating engine for ASP.NET Core, that you can use to display lists of view models of any depth.
You can use it like this:
#Html.ListEditorFor(x => x.Addresses,
Url.Action("AddAddress"), // the action in your controller that creates views
"Add new address", // some text for the "add new item button" in your form
listContainerTemplate: "viewThatWrapsTheList",
listTemplate: "viewForTheList",
itemContainerTemplate: "viewThatWrapsYourViewModel",
ItemTemplate: "viewForYourViewModel")
Now, you do not actually have to specifiy all of this. If you want you can do just
#Html.ListEditorFor(x => x.Addresses, Url.Action("AddAddress"), "Add new address")
And it will guess all the rest.
It will support nesting with any depth, as it was the core of the question.

asp.net mvc how to work with model (update in post controller)

I'm new to mvc and I'm struggling with this model stuff.
My understanding is that I can only use one model per action.
public class TestModel
{
public string foo1 { get; set; }
public string foo2 { get; set; }
public string foo3 { get; set; }
}
I want to partially load my model in the normal action:
public ActionResult Index()
{
TestModel model = new TestModel();
model.foo1 = "foo1";
return View(model);
}
Then the user should add data to the model from the view.
#model SAS_MVC.Models.Test.TestModel
#using (Html.BeginForm())
{
#Html.EditorFor(model => model.foo1, new { htmlAttributes = new { #class = "form-control" } })
#Html.EditorFor(model => model.foo2, new { htmlAttributes = new { #class = "form-control" } })
#Html.EditorFor(model => model.foo3, new { htmlAttributes = new { #class = "form-control" } })
<input type="submit" value="submit" />
}
According to the user's data I have to add further data in the post controller:
[HttpPost]
public ActionResult Index(MyModel model, FormCollection form)
{
// get some data from DB
model.foo3 = 123;
return View(model);
}
How can I save this model permanently? I have problems with e.g. foo3 is empty in the view. I want to pass the model between the post-controller and view several times without losing data.
I did try with TempData and ViewBag but for me this is very uncomfortable to work with... no intellisense.
So how can I do it right? Thanks for help!
Update with EF6:
public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
public class TestController : Controller
{
DB03SASModel dbModel = new DB03SASModel();
// GET: Test
public ActionResult Index()
{
MyEntity model = new MyEntity();
model.Name = "AAAA";
dbModel.MyEntities.Add(model);
dbModel.SaveChanges();
return View(model);
}
[HttpPost]
public ActionResult Index(MyEntity model)
{
model.Name = "BBBB";
dbModel.SaveChanges();
//UpdateModel(model);
return View(model);
}
}
View
#model SAS_MVC.MyEntity
#using (Html.BeginForm())
{
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.DisplayFor(model => model.Id, new { htmlAttributes = new { #class = "form-control" } })
#Html.HiddenFor(model => model.Id, new { htmlAttributes = new { #class = "form-control" } })
<input type="submit" value="submit" />
}
Now I save the model using EF Code First and I checked it in the DB --> every thing is well saved.
But: Again the view take the wrong value and I still struggle.
I found out the the #Html.HiddenFor provide me the current ID of the entity in the post controler. Than I changed the value to "BBBB" and than I pass the exact same entity back to the view but the view never did an update!
I don't get it sorry. When I try with UpdateModel(model); "AAAA" is again my value! Where did this value come from? In the DB there is no such value at this time!! What did I wrong??
Saving the model should happen in the post action, and to save the model permanently so you should save it to the database, that requires you to map your model to a database table, and to do that you should create a database and create a table that will hold your model data then use Entity framework or any other ORM to map your model with the database table.
Update 1:
You are saving the model to the database in two places, first in the get action and then in the post action, so every time you save "BBB" in the post action it will get overridden in the get action to "AAAA", so here is how your code should be :
public class TestController : Controller
{
TestEntities dbModel = new TestEntities();
public ActionResult Index(int? id)
{
MyEntity model = new MyEntity();
if (id.HasValue)
model = dbModel.MyEntity.First(m => m.Id == (id ?? 0));
return View(model);
}
[HttpPost]
public ActionResult Index(MyEntity model)
{
dbModel.MyEntity.Add(model);
dbModel.SaveChanges();
return RedirectToAction("Index", new { id = model.Id });
}
}
as you see saving the data to the database only happen in the post action, the get action is to get the data back from the database.

How to send data from view to controller action in asp.net mvc?

I developed a custom HtmlHelper extension method but that data is not
posting Action.
HtmlHelper extension class:
public static class TestHtmlHelper
{
public static MvcHtmlString CreateControl(this HtmlHelper helper, string tagName, IDictionary<string, string> attributes)
{
var newTag = new TagBuilder(tagName);
newTag.MergeAttributes(attributes, true);
return MvcHtmlString.Create(newTag.ToString(TagRenderMode.Normal));
}
public static string Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
{
// Create tag builder
var builder = new TagBuilder("img");
// Create valid id
builder.GenerateId(id);
// Add attributes
builder.MergeAttribute("src", url);
builder.MergeAttribute("alt", alternateText);
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
// Render tag
return builder.ToString(TagRenderMode.Normal);
}
}
//View code
#using (Html.BeginForm("Go","Home",FormMethod.Post))
{
IDictionary<string, string> d = new Dictionary<string, string>();
d.Add("type", "text");
d.Add("id", "text1");
d.Add("required", "required");
#Html.Raw(Html.CreateControl("input", d))
#Html.Raw(Html.Image("image1", "/Images/bullet.png", "bullet", new { border = "4px" }))
d = null;
d = new Dictionary<string, string>();
d.Add("type", "submit");
d.Add("value", "Go");
#Html.Raw(Html.CreateControl("input", d))
<span></span>
d = null;
d = new Dictionary<string, string>();
d.Add("value", "text");
d.Add("id", "span1");
d.Add("text", "required");
#Html.Raw(Html.CreateControl("span", d))
}
// Controller code
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
[HttpPost]
public ActionResult Go(string test)
{
return Content(test);
}
I didn't get data in string test. I want to submit that data to DB.
To get input values as parameters for an MVC action, you need to include NAME for the input types.
I do not see NAME for any input types in your code.
Also I do not see TEST in your code
For example, if your form is -
#using (Html.BeginForm("Submit","Ajax",FormMethod.Post))
{
<input type="text" name="Rami"/>
<input type="submit" value="Go"/>
}
Output ScreenShot -
Put your inputs inside a form tag. All the input data will be sent to the controller on form submit. Please see the example:
View:
#using (Html.BeginForm("Search", "Events"))
{
#Html.TextBox("name")
<input type="submit" value="Search" />
}
Controller:
public class EventsController: Controller
{
public ActionResult Search(string name)
{
//some operations goes here
return View(); //return some view to the user
}
}
If you need to work with more complex types just lern how to use models in ASP.NET MVC. Here is short example:
Razor:
#model UserModel
#using (Html.BeginForm("Search", "Events"))
{
#Html.TextBoxFor(m => m.FirstName)
#Html.TextBoxFor(m => m.LastName)
<input type="submit" value="Search" />
}
Controller:
public class EventsController: Controller
{
public ActionResult Search(UserModel model)
{
//some operations goes here
return View(); //return some view to the user
}
}
Model (C#):
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

ASP.NET MVC redirect actions error with 'create' partial view on 'index' page

I'm having a problem with partial views. I have an index view of Announcements and I'm trying to add a partial view to create a new Announcement within the same page.
I can display the partial view, and submit the form to create a new record. The record gets submitted into the database, but when re-rendering the page, I get the error: Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper', {"Child actions are not allowed to perform redirect actions."} on my Html.Action statement in my index page.
I've been struggling to make this work, and have firstly changed the Html.Partial to a Html.Action statement as the controller methods weren't firing, then secondly, after I read that this error is because while rendering the page, .NET doesn't know what my redirect action is doing so automatically stops it, tried changing the Html.Action to Html.RedirectAction inside a code block, but still get the same error detailed above.
My model is quite simple:
public class Announcement
{
public Announcement()
{
AnnouncementDate = System.DateTime.Now;
}
[Key]
public int AnnouncementID { get; set; }
public string Title { get; set; }
public string Type { get; set; }
}
My Controller methods:
public ViewResult Index(string searchString, int? page)
{
var Announcements = from a in db.Announcements
select a;
if (!String.IsNullOrEmpty(searchString))
{
Announcements = Announcements.Where(s => (s.Title.ToUpper().Contains(searchString.ToUpper()) || s.AnnouncementText.ToUpper().Contains(searchString.ToUpper())));
}
Announcements = Announcements.OrderBy(s => s.Title);
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(Announcements.ToPagedList(pageNumber, pageSize));
}
//
// GET: /Announcement/Create
public ActionResult Create()
{
Announcement announcement = new Announcement();
return PartialView(announcement);
}
//
// POST: /Announcement/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Announcement announcement)
{
if (ModelState.IsValid)
{
db.Announcements.Add(announcement);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(announcement);
}
Index.cshtml
#model PagedList.IPagedList<Project.Models.Announcement>
#using PagedList.Mvc;
#using PagedList;
#using (Html.BeginForm())
{
#Html.TextBox("SearchString", ViewBag.CurrentFilter as string, new { #class = "search-query", placeholder = "Search by name" })
<input type="submit" value="Search" class="btn" />
}
#item.Title
#item.Type
#Html.Action("Create"); // This is the line causing errors after I submit the Create form. Have tried changing to Html.RedirectAction
Create.cshtml:
#model Project.Models.Announcement
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.TextBoxFor(model => model.Title, new { #style = "width:250px" })
#Html.TextBoxFor(model => model.Type, new { #style = "width:250px" })
<input type="submit" value="Create" class="btn btn-small" />
}
After doing some testing locally...
You can keep
#Html.Action("Create")
However, you have to change one small thing. Define what action the POST points to in your form :)
#model Project.Models.Announcement
#using (Html.BeginForm("Create"))
{
#Html.AntiForgeryToken()
#Html.TextBoxFor(model => model.Title, new { #style = "width:250px" })
#Html.TextBoxFor(model => model.Type, new { #style = "width:250px" })
<input type="submit" value="Create" class="btn btn-small" />
}

Resources